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;
|
||||
}
|
||||
|
||||
// Use the default method of path replacement.
|
||||
/// <summary> Use the default method of path replacement. </summary>
|
||||
private (FullPath?, ResolveData) DefaultResolver(Utf8GamePath path)
|
||||
{
|
||||
var resolved = _collectionManager.Default.ResolvePath(path);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Penumbra.Interop.Services;
|
|||
|
||||
namespace Penumbra.Interop.Resolver;
|
||||
|
||||
public class CutsceneCharacters : IDisposable
|
||||
public class CutsceneService : IDisposable
|
||||
{
|
||||
public const int CutsceneStartIdx = 200;
|
||||
public const int CutsceneSlots = 40;
|
||||
|
|
@ -23,7 +23,7 @@ public class CutsceneCharacters : IDisposable
|
|||
.Where(i => _objects[i] != null)
|
||||
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects[i]!));
|
||||
|
||||
public CutsceneCharacters(ObjectTable objects, GameEventManager events)
|
||||
public CutsceneService(ObjectTable objects, GameEventManager events)
|
||||
{
|
||||
_objects = objects;
|
||||
_events = events;
|
||||
|
|
@ -69,19 +69,19 @@ public class CutsceneCharacters : IDisposable
|
|||
|
||||
private unsafe void OnCharacterDestructor(Character* character)
|
||||
{
|
||||
if (character->GameObject.ObjectIndex is >= CutsceneStartIdx and < CutsceneEndIdx)
|
||||
{
|
||||
var idx = character->GameObject.ObjectIndex - CutsceneStartIdx;
|
||||
_copiedCharacters[idx] = -1;
|
||||
}
|
||||
if (character->GameObject.ObjectIndex is < CutsceneStartIdx or >= CutsceneEndIdx)
|
||||
return;
|
||||
|
||||
var idx = character->GameObject.ObjectIndex - CutsceneStartIdx;
|
||||
_copiedCharacters[idx] = -1;
|
||||
}
|
||||
|
||||
private unsafe void OnCharacterCopy(Character* target, Character* source)
|
||||
{
|
||||
if (target != null && target->GameObject.ObjectIndex is >= CutsceneStartIdx and < CutsceneEndIdx)
|
||||
{
|
||||
var idx = target->GameObject.ObjectIndex - CutsceneStartIdx;
|
||||
_copiedCharacters[idx] = (short)(source != null ? source->GameObject.ObjectIndex : -1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,31 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dalamud.Game.ClientState;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Services;
|
||||
|
||||
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 GameEventManager _events;
|
||||
private readonly Dictionary<IntPtr, (ActorIdentifier, ModCollection)> _cache = new(317);
|
||||
private bool _dirty = false;
|
||||
private bool _enabled = false;
|
||||
private readonly ClientState _clientState;
|
||||
private readonly Dictionary<IntPtr, (ActorIdentifier, ModCollection)> _cache = new(317);
|
||||
private bool _dirty;
|
||||
private bool _enabled;
|
||||
|
||||
public IdentifiedCollectionCache(CommunicatorService communicator, GameEventManager events)
|
||||
public IdentifiedCollectionCache(ClientState clientState, CommunicatorService communicator, GameEventManager events)
|
||||
{
|
||||
_clientState = clientState;
|
||||
_communicator = communicator;
|
||||
_events = events;
|
||||
Enable();
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
|
|
@ -29,10 +33,10 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
if (_enabled)
|
||||
return;
|
||||
|
||||
_communicator.CollectionChange.Event += CollectionChangeClear;
|
||||
DalamudServices.SClientState.TerritoryChanged += TerritoryClear;
|
||||
_events.CharacterDestructor += OnCharacterDestruct;
|
||||
_enabled = true;
|
||||
_communicator.CollectionChange.Event += CollectionChangeClear;
|
||||
_clientState.TerritoryChanged += TerritoryClear;
|
||||
_events.CharacterDestructor += OnCharacterDestruct;
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
|
|
@ -40,10 +44,10 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
if (!_enabled)
|
||||
return;
|
||||
|
||||
_communicator.CollectionChange.Event -= CollectionChangeClear;
|
||||
DalamudServices.SClientState.TerritoryChanged -= TerritoryClear;
|
||||
_events.CharacterDestructor -= OnCharacterDestruct;
|
||||
_enabled = false;
|
||||
_communicator.CollectionChange.Event -= CollectionChangeClear;
|
||||
_clientState.TerritoryChanged -= TerritoryClear;
|
||||
_events.CharacterDestructor -= OnCharacterDestruct;
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
public ResolveData Set(ModCollection collection, ActorIdentifier identifier, GameObject* data)
|
||||
|
|
@ -54,7 +58,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
_cache.Clear();
|
||||
}
|
||||
|
||||
_cache[(IntPtr)data] = (identifier, collection);
|
||||
_cache[(nint)data] = (identifier, collection);
|
||||
return collection.ToResolveData(data);
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +69,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
_dirty = false;
|
||||
_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);
|
||||
return true;
|
||||
|
|
@ -81,7 +85,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
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)
|
||||
{
|
||||
|
|
@ -108,5 +112,5 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(IntPtr
|
|||
=> _dirty = _cache.Count > 0;
|
||||
|
||||
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.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using Penumbra.Collections;
|
||||
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.
|
||||
private readonly ConcurrentDictionary< ByteString, ResolveData > _pathCollections = new();
|
||||
|
||||
private readonly ThreadLocal<ResolveData> _resolveData = new ThreadLocal<ResolveData>(() => ResolveData.Invalid, true);
|
||||
|
||||
public PathState( PathResolver parent )
|
||||
{
|
||||
SignatureHelper.Initialise( this );
|
||||
|
|
@ -60,6 +63,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
_resolveData.Dispose();
|
||||
_human.Dispose();
|
||||
_weapon.Dispose();
|
||||
_demiHuman.Dispose();
|
||||
|
|
@ -76,7 +80,10 @@ public unsafe partial class PathResolver
|
|||
=> _pathCollections.TryGetValue( path, out 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.
|
||||
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
|
||||
|
|
@ -89,6 +96,7 @@ public unsafe partial class PathResolver
|
|||
|
||||
var gamePath = new ByteString( ( byte* )path );
|
||||
SetCollection( gameObject, gamePath, collection );
|
||||
_resolveData.Value = collection.ToResolveData(gameObject);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Loader;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
|
|
@ -18,6 +16,20 @@ using Penumbra.Util;
|
|||
|
||||
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.
|
||||
// It will hook any path resolving functions for humans,
|
||||
// as well as DrawObject creation.
|
||||
|
|
@ -29,7 +41,7 @@ public partial class PathResolver : IDisposable
|
|||
|
||||
private readonly CommunicatorService _communicator;
|
||||
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 readonly BitArray ValidHumanModels;
|
||||
internal static IdentifiedCollectionCache IdentifiedCache = null!; // TODO
|
||||
|
|
@ -41,11 +53,11 @@ public partial class PathResolver : IDisposable
|
|||
static PathResolver()
|
||||
=> 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);
|
||||
_communicator = communicator;
|
||||
IdentifiedCache = new IdentifiedCollectionCache(communicator, events);
|
||||
IdentifiedCache = cache;
|
||||
SignatureHelper.Initialise(this);
|
||||
_drawObjects = new DrawObjectState(_communicator);
|
||||
_loader = loader;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ using Penumbra.Interop.Services;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
using Penumbra.UI.ModsTab;
|
||||
using Penumbra.UI.Tabs;
|
||||
|
|
@ -60,12 +59,12 @@ public class PenumbraNew
|
|||
.AddSingleton<StainService>()
|
||||
.AddSingleton<ItemService>()
|
||||
.AddSingleton<ActorService>();
|
||||
|
||||
|
||||
// Add Game Services
|
||||
services.AddSingleton<GameEventManager>()
|
||||
.AddSingleton<FrameworkManager>()
|
||||
.AddSingleton<MetaFileManager>()
|
||||
.AddSingleton<CutsceneCharacters>()
|
||||
.AddSingleton<CutsceneService>()
|
||||
.AddSingleton<CharacterUtility>()
|
||||
.AddSingleton<ResourceManagerService>()
|
||||
.AddSingleton<ResourceService>()
|
||||
|
|
@ -74,7 +73,11 @@ public class PenumbraNew
|
|||
.AddSingleton<CreateFileWHook>()
|
||||
.AddSingleton<ResidentResourceManager>()
|
||||
.AddSingleton<FontReloader>()
|
||||
.AddSingleton<RedrawService>();
|
||||
.AddSingleton<RedrawService>();
|
||||
|
||||
// Add PathResolver
|
||||
services.AddSingleton<CutsceneService>()
|
||||
.AddSingleton<IdentifiedCollectionCache>();
|
||||
|
||||
// Add Configuration
|
||||
services.AddTransient<ConfigMigrationService>()
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public sealed class ItemService : AsyncServiceWrapper<ItemData>
|
|||
public sealed class ActorService : AsyncServiceWrapper<ActorManager>
|
||||
{
|
||||
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,
|
||||
() => new ActorManager(pi, objects, clientState, framework, gameData, gui, idx => (short)cutscene.GetParentIndex(idx)))
|
||||
{ }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue