mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
tmp
This commit is contained in:
parent
c5ac9f6f08
commit
b6d6993c9f
7 changed files with 70 additions and 43 deletions
|
|
@ -76,7 +76,7 @@ public class CharacterResolver : IDisposable
|
||||||
_loader.FileLoaded -= ImcLoadResource;
|
_loader.FileLoaded -= ImcLoadResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the default method of path replacement.
|
/// <summary> Use the default method of path replacement. </summary>
|
||||||
private (FullPath?, ResolveData) DefaultResolver(Utf8GamePath path)
|
private (FullPath?, ResolveData) DefaultResolver(Utf8GamePath path)
|
||||||
{
|
{
|
||||||
var resolved = _collectionManager.Default.ResolvePath(path);
|
var resolved = _collectionManager.Default.ResolvePath(path);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using Penumbra.Interop.Services;
|
||||||
|
|
||||||
namespace Penumbra.Interop.Resolver;
|
namespace Penumbra.Interop.Resolver;
|
||||||
|
|
||||||
public class CutsceneCharacters : IDisposable
|
public class CutsceneService : IDisposable
|
||||||
{
|
{
|
||||||
public const int CutsceneStartIdx = 200;
|
public const int CutsceneStartIdx = 200;
|
||||||
public const int CutsceneSlots = 40;
|
public const int CutsceneSlots = 40;
|
||||||
|
|
@ -23,7 +23,7 @@ public class CutsceneCharacters : IDisposable
|
||||||
.Where(i => _objects[i] != null)
|
.Where(i => _objects[i] != null)
|
||||||
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects[i]!));
|
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects[i]!));
|
||||||
|
|
||||||
public CutsceneCharacters(ObjectTable objects, GameEventManager events)
|
public CutsceneService(ObjectTable objects, GameEventManager events)
|
||||||
{
|
{
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_events = events;
|
_events = events;
|
||||||
|
|
@ -69,19 +69,19 @@ public class CutsceneCharacters : IDisposable
|
||||||
|
|
||||||
private unsafe void OnCharacterDestructor(Character* character)
|
private unsafe void OnCharacterDestructor(Character* character)
|
||||||
{
|
{
|
||||||
if (character->GameObject.ObjectIndex is >= CutsceneStartIdx and < CutsceneEndIdx)
|
if (character->GameObject.ObjectIndex is < CutsceneStartIdx or >= CutsceneEndIdx)
|
||||||
{
|
return;
|
||||||
var idx = character->GameObject.ObjectIndex - CutsceneStartIdx;
|
|
||||||
_copiedCharacters[idx] = -1;
|
var idx = character->GameObject.ObjectIndex - CutsceneStartIdx;
|
||||||
}
|
_copiedCharacters[idx] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void OnCharacterCopy(Character* target, Character* source)
|
private unsafe void OnCharacterCopy(Character* target, Character* source)
|
||||||
{
|
{
|
||||||
if (target != null && target->GameObject.ObjectIndex is >= CutsceneStartIdx and < CutsceneEndIdx)
|
if (target == null || target->GameObject.ObjectIndex is < CutsceneStartIdx or >= CutsceneEndIdx)
|
||||||
{
|
return;
|
||||||
var idx = target->GameObject.ObjectIndex - CutsceneStartIdx;
|
|
||||||
_copiedCharacters[idx] = (short)(source != null ? source->GameObject.ObjectIndex : -1);
|
var idx = target->GameObject.ObjectIndex - CutsceneStartIdx;
|
||||||
}
|
_copiedCharacters[idx] = (short)(source != null ? source->GameObject.ObjectIndex : -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,27 +1,31 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Game.ClientState;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
using Penumbra.Interop.Services;
|
using Penumbra.Interop.Services;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
|
||||||
namespace Penumbra.Interop.Resolver;
|
namespace Penumbra.Interop.Resolver;
|
||||||
|
|
||||||
public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr Address, ActorIdentifier Identifier, ModCollection Collection)>
|
public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(nint Address, ActorIdentifier Identifier, ModCollection Collection)>
|
||||||
{
|
{
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
private readonly GameEventManager _events;
|
private readonly GameEventManager _events;
|
||||||
private readonly Dictionary<IntPtr, (ActorIdentifier, ModCollection)> _cache = new(317);
|
private readonly ClientState _clientState;
|
||||||
private bool _dirty = false;
|
private readonly Dictionary<IntPtr, (ActorIdentifier, ModCollection)> _cache = new(317);
|
||||||
private bool _enabled = false;
|
private bool _dirty;
|
||||||
|
private bool _enabled;
|
||||||
|
|
||||||
public IdentifiedCollectionCache(CommunicatorService communicator, GameEventManager events)
|
public IdentifiedCollectionCache(ClientState clientState, CommunicatorService communicator, GameEventManager events)
|
||||||
{
|
{
|
||||||
|
_clientState = clientState;
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
_events = events;
|
_events = events;
|
||||||
|
Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Enable()
|
public void Enable()
|
||||||
|
|
@ -29,10 +33,10 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
if (_enabled)
|
if (_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_communicator.CollectionChange.Event += CollectionChangeClear;
|
_communicator.CollectionChange.Event += CollectionChangeClear;
|
||||||
DalamudServices.SClientState.TerritoryChanged += TerritoryClear;
|
_clientState.TerritoryChanged += TerritoryClear;
|
||||||
_events.CharacterDestructor += OnCharacterDestruct;
|
_events.CharacterDestructor += OnCharacterDestruct;
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disable()
|
public void Disable()
|
||||||
|
|
@ -40,10 +44,10 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
if (!_enabled)
|
if (!_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_communicator.CollectionChange.Event -= CollectionChangeClear;
|
_communicator.CollectionChange.Event -= CollectionChangeClear;
|
||||||
DalamudServices.SClientState.TerritoryChanged -= TerritoryClear;
|
_clientState.TerritoryChanged -= TerritoryClear;
|
||||||
_events.CharacterDestructor -= OnCharacterDestruct;
|
_events.CharacterDestructor -= OnCharacterDestruct;
|
||||||
_enabled = false;
|
_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResolveData Set(ModCollection collection, ActorIdentifier identifier, GameObject* data)
|
public ResolveData Set(ModCollection collection, ActorIdentifier identifier, GameObject* data)
|
||||||
|
|
@ -54,7 +58,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
_cache.Clear();
|
_cache.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_cache[(IntPtr)data] = (identifier, collection);
|
_cache[(nint)data] = (identifier, collection);
|
||||||
return collection.ToResolveData(data);
|
return collection.ToResolveData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +69,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
_dirty = false;
|
_dirty = false;
|
||||||
_cache.Clear();
|
_cache.Clear();
|
||||||
}
|
}
|
||||||
else if (_cache.TryGetValue((IntPtr)gameObject, out var p))
|
else if (_cache.TryGetValue((nint)gameObject, out var p))
|
||||||
{
|
{
|
||||||
resolve = p.Item2.ToResolveData(gameObject);
|
resolve = p.Item2.ToResolveData(gameObject);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -81,7 +85,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<(IntPtr Address, ActorIdentifier Identifier, ModCollection Collection)> GetEnumerator()
|
public IEnumerator<(nint Address, ActorIdentifier Identifier, ModCollection Collection)> GetEnumerator()
|
||||||
{
|
{
|
||||||
foreach (var (address, (identifier, collection)) in _cache)
|
foreach (var (address, (identifier, collection)) in _cache)
|
||||||
{
|
{
|
||||||
|
|
@ -108,5 +112,5 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
||||||
=> _dirty = _cache.Count > 0;
|
=> _dirty = _cache.Count > 0;
|
||||||
|
|
||||||
private void OnCharacterDestruct(Character* character)
|
private void OnCharacterDestruct(Character* character)
|
||||||
=> _cache.Remove((IntPtr)character);
|
=> _cache.Remove((nint)character);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
|
|
@ -33,6 +34,8 @@ public unsafe partial class PathResolver
|
||||||
// This map links files to their corresponding collection, if it is non-default.
|
// This map links files to their corresponding collection, if it is non-default.
|
||||||
private readonly ConcurrentDictionary< ByteString, ResolveData > _pathCollections = new();
|
private readonly ConcurrentDictionary< ByteString, ResolveData > _pathCollections = new();
|
||||||
|
|
||||||
|
private readonly ThreadLocal<ResolveData> _resolveData = new ThreadLocal<ResolveData>(() => ResolveData.Invalid, true);
|
||||||
|
|
||||||
public PathState( PathResolver parent )
|
public PathState( PathResolver parent )
|
||||||
{
|
{
|
||||||
SignatureHelper.Initialise( this );
|
SignatureHelper.Initialise( this );
|
||||||
|
|
@ -60,6 +63,7 @@ public unsafe partial class PathResolver
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
_resolveData.Dispose();
|
||||||
_human.Dispose();
|
_human.Dispose();
|
||||||
_weapon.Dispose();
|
_weapon.Dispose();
|
||||||
_demiHuman.Dispose();
|
_demiHuman.Dispose();
|
||||||
|
|
@ -76,7 +80,10 @@ public unsafe partial class PathResolver
|
||||||
=> _pathCollections.TryGetValue( path, out collection );
|
=> _pathCollections.TryGetValue( path, out collection );
|
||||||
|
|
||||||
public bool Consume( ByteString path, out ResolveData collection )
|
public bool Consume( ByteString path, out ResolveData collection )
|
||||||
=> _pathCollections.TryRemove( path, out collection );
|
{
|
||||||
|
collection = _resolveData.IsValueCreated && _resolveData.Value.Valid ? _resolveData.Value : ResolveData.Invalid;
|
||||||
|
return _pathCollections.TryRemove(path, out collection);
|
||||||
|
}
|
||||||
|
|
||||||
// Just add or remove the resolved path.
|
// Just add or remove the resolved path.
|
||||||
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
||||||
|
|
@ -89,6 +96,7 @@ public unsafe partial class PathResolver
|
||||||
|
|
||||||
var gamePath = new ByteString( ( byte* )path );
|
var gamePath = new ByteString( ( byte* )path );
|
||||||
SetCollection( gameObject, gamePath, collection );
|
SetCollection( gameObject, gamePath, collection );
|
||||||
|
_resolveData.Value = collection.ToResolveData(gameObject);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
|
||||||
using OtterGui.Classes;
|
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Interop.Loader;
|
using Penumbra.Interop.Loader;
|
||||||
using Penumbra.Interop.Services;
|
using Penumbra.Interop.Services;
|
||||||
using Penumbra.Interop.Structs;
|
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
@ -18,6 +16,20 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Interop.Resolver;
|
namespace Penumbra.Interop.Resolver;
|
||||||
|
|
||||||
|
//public class PathResolver2 : IDisposable
|
||||||
|
//{
|
||||||
|
// public readonly CutsceneService Cutscenes;
|
||||||
|
// public readonly IdentifiedCollectionCache Identified;
|
||||||
|
//
|
||||||
|
// public PathResolver(StartTracker timer, CutsceneService cutscenes, IdentifiedCollectionCache identified)
|
||||||
|
// {
|
||||||
|
// using var t = timer.Measure(StartTimeType.PathResolver);
|
||||||
|
// Cutscenes = cutscenes;
|
||||||
|
// Identified = identified;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
// The Path Resolver handles character collections.
|
// The Path Resolver handles character collections.
|
||||||
// It will hook any path resolving functions for humans,
|
// It will hook any path resolving functions for humans,
|
||||||
// as well as DrawObject creation.
|
// as well as DrawObject creation.
|
||||||
|
|
@ -29,7 +41,7 @@ public partial class PathResolver : IDisposable
|
||||||
|
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
private readonly ResourceLoader _loader;
|
private readonly ResourceLoader _loader;
|
||||||
private static readonly CutsceneCharacters Cutscenes = new(DalamudServices.SObjects, Penumbra.GameEvents); // TODO
|
private static readonly CutsceneService Cutscenes = new(DalamudServices.SObjects, Penumbra.GameEvents); // TODO
|
||||||
private static DrawObjectState _drawObjects = null!; // TODO
|
private static DrawObjectState _drawObjects = null!; // TODO
|
||||||
private static readonly BitArray ValidHumanModels;
|
private static readonly BitArray ValidHumanModels;
|
||||||
internal static IdentifiedCollectionCache IdentifiedCache = null!; // TODO
|
internal static IdentifiedCollectionCache IdentifiedCache = null!; // TODO
|
||||||
|
|
@ -41,11 +53,11 @@ public partial class PathResolver : IDisposable
|
||||||
static PathResolver()
|
static PathResolver()
|
||||||
=> ValidHumanModels = GetValidHumanModels(DalamudServices.SGameData);
|
=> ValidHumanModels = GetValidHumanModels(DalamudServices.SGameData);
|
||||||
|
|
||||||
public unsafe PathResolver(StartTracker timer, CommunicatorService communicator, GameEventManager events, ResourceLoader loader)
|
public unsafe PathResolver(IdentifiedCollectionCache cache, StartTracker timer, ClientState clientState, CommunicatorService communicator, GameEventManager events, ResourceLoader loader)
|
||||||
{
|
{
|
||||||
using var tApi = timer.Measure(StartTimeType.PathResolver);
|
using var tApi = timer.Measure(StartTimeType.PathResolver);
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
IdentifiedCache = new IdentifiedCollectionCache(communicator, events);
|
IdentifiedCache = cache;
|
||||||
SignatureHelper.Initialise(this);
|
SignatureHelper.Initialise(this);
|
||||||
_drawObjects = new DrawObjectState(_communicator);
|
_drawObjects = new DrawObjectState(_communicator);
|
||||||
_loader = loader;
|
_loader = loader;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ using Penumbra.Interop.Services;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
using Penumbra.UI.Classes;
|
|
||||||
using Penumbra.UI.AdvancedWindow;
|
using Penumbra.UI.AdvancedWindow;
|
||||||
using Penumbra.UI.ModsTab;
|
using Penumbra.UI.ModsTab;
|
||||||
using Penumbra.UI.Tabs;
|
using Penumbra.UI.Tabs;
|
||||||
|
|
@ -60,12 +59,12 @@ public class PenumbraNew
|
||||||
.AddSingleton<StainService>()
|
.AddSingleton<StainService>()
|
||||||
.AddSingleton<ItemService>()
|
.AddSingleton<ItemService>()
|
||||||
.AddSingleton<ActorService>();
|
.AddSingleton<ActorService>();
|
||||||
|
|
||||||
// Add Game Services
|
// Add Game Services
|
||||||
services.AddSingleton<GameEventManager>()
|
services.AddSingleton<GameEventManager>()
|
||||||
.AddSingleton<FrameworkManager>()
|
.AddSingleton<FrameworkManager>()
|
||||||
.AddSingleton<MetaFileManager>()
|
.AddSingleton<MetaFileManager>()
|
||||||
.AddSingleton<CutsceneCharacters>()
|
.AddSingleton<CutsceneService>()
|
||||||
.AddSingleton<CharacterUtility>()
|
.AddSingleton<CharacterUtility>()
|
||||||
.AddSingleton<ResourceManagerService>()
|
.AddSingleton<ResourceManagerService>()
|
||||||
.AddSingleton<ResourceService>()
|
.AddSingleton<ResourceService>()
|
||||||
|
|
@ -74,7 +73,11 @@ public class PenumbraNew
|
||||||
.AddSingleton<CreateFileWHook>()
|
.AddSingleton<CreateFileWHook>()
|
||||||
.AddSingleton<ResidentResourceManager>()
|
.AddSingleton<ResidentResourceManager>()
|
||||||
.AddSingleton<FontReloader>()
|
.AddSingleton<FontReloader>()
|
||||||
.AddSingleton<RedrawService>();
|
.AddSingleton<RedrawService>();
|
||||||
|
|
||||||
|
// Add PathResolver
|
||||||
|
services.AddSingleton<CutsceneService>()
|
||||||
|
.AddSingleton<IdentifiedCollectionCache>();
|
||||||
|
|
||||||
// Add Configuration
|
// Add Configuration
|
||||||
services.AddTransient<ConfigMigrationService>()
|
services.AddTransient<ConfigMigrationService>()
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public sealed class ItemService : AsyncServiceWrapper<ItemData>
|
||||||
public sealed class ActorService : AsyncServiceWrapper<ActorManager>
|
public sealed class ActorService : AsyncServiceWrapper<ActorManager>
|
||||||
{
|
{
|
||||||
public ActorService(StartTracker tracker, DalamudPluginInterface pi, ObjectTable objects, ClientState clientState,
|
public ActorService(StartTracker tracker, DalamudPluginInterface pi, ObjectTable objects, ClientState clientState,
|
||||||
Framework framework, DataManager gameData, GameGui gui, CutsceneCharacters cutscene)
|
Framework framework, DataManager gameData, GameGui gui, CutsceneService cutscene)
|
||||||
: base(nameof(ActorService), tracker, StartTimeType.Actors,
|
: base(nameof(ActorService), tracker, StartTimeType.Actors,
|
||||||
() => new ActorManager(pi, objects, clientState, framework, gameData, gui, idx => (short)cutscene.GetParentIndex(idx)))
|
() => new ActorManager(pi, objects, clientState, framework, gameData, gui, idx => (short)cutscene.GetParentIndex(idx)))
|
||||||
{ }
|
{ }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue