mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Use explicit priorities for all internal communication events.
This commit is contained in:
parent
f46daf0f54
commit
fb84b43d69
36 changed files with 681 additions and 384 deletions
|
|
@ -22,6 +22,7 @@ using Penumbra.String;
|
|||
using Penumbra.String.Classes;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.UI;
|
||||
|
||||
|
|
@ -34,13 +35,13 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
|
||||
public event Action<string>? PreSettingsPanelDraw
|
||||
{
|
||||
add => _communicator.PreSettingsPanelDraw.Subscribe(value!);
|
||||
add => _communicator.PreSettingsPanelDraw.Subscribe(value!, Communication.PreSettingsPanelDraw.Priority.Default);
|
||||
remove => _communicator.PreSettingsPanelDraw.Unsubscribe(value!);
|
||||
}
|
||||
|
||||
public event Action<string>? PostSettingsPanelDraw
|
||||
{
|
||||
add => _communicator.PostSettingsPanelDraw.Subscribe(value!);
|
||||
add => _communicator.PostSettingsPanelDraw.Subscribe(value!, Communication.PostSettingsPanelDraw.Priority.Default);
|
||||
remove => _communicator.PostSettingsPanelDraw.Unsubscribe(value!);
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return;
|
||||
|
||||
CheckInitialized();
|
||||
_communicator.CreatingCharacterBase.Subscribe(new Action<nint, string, nint, nint, nint>(value));
|
||||
_communicator.CreatingCharacterBase.Subscribe(new Action<nint, string, nint, nint, nint>(value), Communication.CreatingCharacterBase.Priority.Api);
|
||||
}
|
||||
remove
|
||||
{
|
||||
|
|
@ -88,7 +89,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return;
|
||||
|
||||
CheckInitialized();
|
||||
_communicator.CreatedCharacterBase.Subscribe(new Action<nint, string, nint>(value));
|
||||
_communicator.CreatedCharacterBase.Subscribe(new Action<nint, string, nint>(value), Communication.CreatedCharacterBase.Priority.Api);
|
||||
}
|
||||
remove
|
||||
{
|
||||
|
|
@ -147,8 +148,8 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
_lumina = _dalamud.GameData.GameData;
|
||||
|
||||
_resourceLoader.ResourceLoaded += OnResourceLoaded;
|
||||
_communicator.ModPathChanged.Subscribe(ModPathChangeSubscriber);
|
||||
_communicator.ModSettingChanged.Subscribe(OnModSettingChange, -1000);
|
||||
_communicator.ModPathChanged.Subscribe(ModPathChangeSubscriber, ModPathChanged.Priority.Api);
|
||||
_communicator.ModSettingChanged.Subscribe(OnModSettingChange, Communication.ModSettingChanged.Priority.Api);
|
||||
}
|
||||
|
||||
public unsafe void Dispose()
|
||||
|
|
@ -180,7 +181,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
|
||||
public event ChangedItemClick? ChangedItemClicked
|
||||
{
|
||||
add => _communicator.ChangedItemClick.Subscribe(new Action<MouseButton, object?>(value!));
|
||||
add => _communicator.ChangedItemClick.Subscribe(new Action<MouseButton, object?>(value!), Communication.ChangedItemClick.Priority.Default);
|
||||
remove => _communicator.ChangedItemClick.Unsubscribe(new Action<MouseButton, object?>(value!));
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +204,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
add
|
||||
{
|
||||
CheckInitialized();
|
||||
_communicator.ModDirectoryChanged.Subscribe(value!);
|
||||
_communicator.ModDirectoryChanged.Subscribe(value!, Communication.ModDirectoryChanged.Priority.Api);
|
||||
}
|
||||
remove
|
||||
{
|
||||
|
|
@ -220,7 +221,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
add
|
||||
{
|
||||
CheckInitialized();
|
||||
_communicator.EnabledChanged.Subscribe(value!, int.MinValue);
|
||||
_communicator.EnabledChanged.Subscribe(value!, EnabledChanged.Priority.Api);
|
||||
}
|
||||
remove
|
||||
{
|
||||
|
|
@ -237,7 +238,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
|
||||
public event ChangedItemHover? ChangedItemTooltip
|
||||
{
|
||||
add => _communicator.ChangedItemHover.Subscribe(new Action<object?>(value!));
|
||||
add => _communicator.ChangedItemHover.Subscribe(new Action<object?>(value!), Communication.ChangedItemHover.Priority.Default);
|
||||
remove => _communicator.ChangedItemHover.Unsubscribe(new Action<object?>(value!));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ using Penumbra.Mods;
|
|||
using System.Collections.Generic;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Collections.Manager;
|
||||
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
public enum RedirectResult
|
||||
|
|
@ -27,7 +28,7 @@ public class TempModManager : IDisposable
|
|||
public TempModManager(CommunicatorService communicator)
|
||||
{
|
||||
_communicator = communicator;
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.TempModManager);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using OtterGui.Classes;
|
|||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
|
|
@ -44,15 +45,15 @@ public class CollectionCacheManager : IDisposable
|
|||
|
||||
if (!_active.Individuals.IsLoaded)
|
||||
_active.Individuals.Loaded += CreateNecessaryCaches;
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, -100);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeAddition, -100);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeRemoval, 100);
|
||||
_communicator.TemporaryGlobalModChange.Subscribe(OnGlobalModChange);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, -100);
|
||||
_communicator.ModSettingChanged.Subscribe(OnModSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, -100);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.CollectionCacheManager);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeAddition, ModPathChanged.Priority.CollectionCacheManagerAddition);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeRemoval, ModPathChanged.Priority.CollectionCacheManagerRemoval);
|
||||
_communicator.TemporaryGlobalModChange.Subscribe(OnGlobalModChange, TemporaryGlobalModChange.Priority.CollectionCacheManager);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.CollectionCacheManager);
|
||||
_communicator.ModSettingChanged.Subscribe(OnModSettingChange, ModSettingChanged.Priority.CollectionCacheManager);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange, CollectionInheritanceChanged.Priority.CollectionCacheManager);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted, ModDiscoveryStarted.Priority.CollectionCacheManager);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, ModDiscoveryFinished.Priority.CollectionCacheManager);
|
||||
|
||||
if (!MetaFileManager.CharacterUtility.Ready)
|
||||
MetaFileManager.CharacterUtility.LoadingFinished += IncrementCounters;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Dalamud.Interface.Internal.Notifications;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -44,7 +45,7 @@ public class ActiveCollections : ISavable, IDisposable
|
|||
Default = storage.DefaultNamed;
|
||||
Interface = storage.DefaultNamed;
|
||||
Individuals = new IndividualCollections(actors, config, false);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, -100);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ActiveCollections);
|
||||
LoadCollections();
|
||||
UpdateCurrentCollectionInUse();
|
||||
Individuals.Loaded += UpdateCurrentCollectionInUse;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||
using Dalamud.Interface.Internal.Notifications;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -56,10 +57,10 @@ public class CollectionStorage : IReadOnlyList<ModCollection>, IDisposable
|
|||
_communicator = communicator;
|
||||
_saveService = saveService;
|
||||
_modStorage = modStorage;
|
||||
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, 10);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, 100);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(OnModDiscoveryStarted, ModDiscoveryStarted.Priority.CollectionStorage);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, ModDiscoveryFinished.Priority.CollectionStorage);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.CollectionStorage);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.CollectionStorage);
|
||||
ReadCollections(out DefaultNamed);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using Dalamud.Interface.Internal.Notifications;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
|
@ -47,7 +48,7 @@ public class InheritanceManager : IDisposable
|
|||
_modStorage = modStorage;
|
||||
|
||||
ApplyInheritances();
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.InheritanceManager);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -27,7 +28,7 @@ public class TempCollectionManager : IDisposable
|
|||
_storage = storage;
|
||||
Collections = new IndividualCollections(actors, config, true);
|
||||
|
||||
_communicator.TemporaryGlobalModChange.Subscribe(OnGlobalModChange);
|
||||
_communicator.TemporaryGlobalModChange.Subscribe(OnGlobalModChange, TemporaryGlobalModChange.Priority.TempCollectionManager);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
28
Penumbra/Communication/ChangedItemClick.cs
Normal file
28
Penumbra/Communication/ChangedItemClick.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a Changed Item in Penumbra is clicked.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the clicked mouse button. </item>
|
||||
/// <item>Parameter is the clicked object data if any.. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ChangedItemClick : EventWrapper<Action<MouseButton, object?>, ChangedItemClick.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.ChangedItemClicked"/>
|
||||
Default = 0,
|
||||
}
|
||||
|
||||
public ChangedItemClick()
|
||||
: base(nameof(ChangedItemClick))
|
||||
{ }
|
||||
|
||||
public void Invoke(MouseButton button, object? data)
|
||||
=> Invoke(this, button, data);
|
||||
}
|
||||
29
Penumbra/Communication/ChangedItemHover.cs
Normal file
29
Penumbra/Communication/ChangedItemHover.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a Changed Item in Penumbra is hovered.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the hovered object data if any. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ChangedItemHover : EventWrapper<Action<object?>, ChangedItemHover.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.ChangedItemTooltip"/>
|
||||
Default = 0,
|
||||
}
|
||||
|
||||
public ChangedItemHover()
|
||||
: base(nameof(ChangedItemHover))
|
||||
{ }
|
||||
|
||||
public void Invoke(object? data)
|
||||
=> Invoke(this, data);
|
||||
|
||||
public bool HasTooltip
|
||||
=> HasSubscribers;
|
||||
}
|
||||
54
Penumbra/Communication/CollectionChange.cs
Normal file
54
Penumbra/Communication/CollectionChange.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever collection setup is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of the changed collection. (Inactive or Temporary for additions or deletions)</item>
|
||||
/// <item>Parameter is the old collection, or null on additions.</item>
|
||||
/// <item>Parameter is the new collection, or null on deletions.</item>
|
||||
/// <item>Parameter is the display name for Individual collections or an empty string otherwise.</item>
|
||||
/// </list> </summary>
|
||||
public sealed class CollectionChange : EventWrapper<Action<CollectionType, ModCollection?, ModCollection?, string>, CollectionChange.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnCollectionChange"/>
|
||||
CollectionCacheManager = -2,
|
||||
|
||||
/// <seealso cref="Collections.Manager.ActiveCollections.OnCollectionChange"/>
|
||||
ActiveCollections = -1,
|
||||
|
||||
/// <seealso cref="Api.TempModManager.OnCollectionChange"/>
|
||||
TempModManager = 0,
|
||||
|
||||
/// <seealso cref="Collections.Manager.InheritanceManager.OnCollectionChange" />
|
||||
InheritanceManager = 0,
|
||||
|
||||
/// <seealso cref="Interop.PathResolving.IdentifiedCollectionCache.CollectionChangeClear" />
|
||||
IdentifiedCollectionCache = 0,
|
||||
|
||||
/// <seealso cref="UI.AdvancedWindow.ItemSwapTab.OnCollectionChange" />
|
||||
ItemSwapTab = 0,
|
||||
|
||||
/// <seealso cref="UI.CollectionTab.CollectionSelector.OnCollectionChange" />
|
||||
CollectionSelector = 0,
|
||||
|
||||
/// <seealso cref="UI.CollectionTab.IndividualAssignmentUi.UpdateIdentifiers"/>
|
||||
IndividualAssignmentUi = 0,
|
||||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnCollectionChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
}
|
||||
|
||||
public CollectionChange()
|
||||
: base(nameof(CollectionChange))
|
||||
{ }
|
||||
|
||||
public void Invoke(CollectionType collectionType, ModCollection? oldCollection, ModCollection? newCollection, string displayName)
|
||||
=> Invoke(this, collectionType, oldCollection, newCollection, displayName);
|
||||
}
|
||||
34
Penumbra/Communication/CollectionInheritanceChanged.cs
Normal file
34
Penumbra/Communication/CollectionInheritanceChanged.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a collections inheritances change.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the collection whose ancestors were changed. </item>
|
||||
/// <item>Parameter is whether the change was itself inherited, i.e. if it happened in a direct parent (false) or a more removed ancestor (true). </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class CollectionInheritanceChanged : EventWrapper<Action<ModCollection, bool>, CollectionInheritanceChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnCollectionInheritanceChange"/>
|
||||
CollectionCacheManager = 0,
|
||||
|
||||
/// <seealso cref="UI.AdvancedWindow.ItemSwapTab.OnInheritanceChange"/>
|
||||
ItemSwapTab = 0,
|
||||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnInheritanceChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
}
|
||||
|
||||
public CollectionInheritanceChanged()
|
||||
: base(nameof(CollectionInheritanceChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModCollection collection, bool inherited)
|
||||
=> Invoke(this, collection, inherited);
|
||||
}
|
||||
25
Penumbra/Communication/CreatedCharacterBase.cs
Normal file
25
Penumbra/Communication/CreatedCharacterBase.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary> <list type="number">
|
||||
/// <item>Parameter is the game object for which a draw object is created. </item>
|
||||
/// <item>Parameter is the name of the applied collection. </item>
|
||||
/// <item>Parameter is the created draw object. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class CreatedCharacterBase : EventWrapper<Action<nint, string, nint>, CreatedCharacterBase.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.CreatedCharacterBase"/>
|
||||
Api = 0,
|
||||
}
|
||||
|
||||
public CreatedCharacterBase()
|
||||
: base(nameof(CreatedCharacterBase))
|
||||
{ }
|
||||
|
||||
public void Invoke(nint gameObject, string appliedCollectionName, nint drawObject)
|
||||
=> Invoke(this, gameObject, appliedCollectionName, drawObject);
|
||||
}
|
||||
29
Penumbra/Communication/CreatingCharacterBase.cs
Normal file
29
Penumbra/Communication/CreatingCharacterBase.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a character base draw object is being created by the game.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the game object for which a draw object is created. </item>
|
||||
/// <item>Parameter is the name of the applied collection. </item>
|
||||
/// <item>Parameter is a pointer to the model id (an uint). </item>
|
||||
/// <item>Parameter is a pointer to the customize array. </item>
|
||||
/// <item>Parameter is a pointer to the equip data array. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class CreatingCharacterBase : EventWrapper<Action<nint, string, nint, nint, nint>, CreatingCharacterBase.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.CreatingCharacterBase"/>
|
||||
Api = 0,
|
||||
}
|
||||
|
||||
public CreatingCharacterBase()
|
||||
: base(nameof(CreatingCharacterBase))
|
||||
{ }
|
||||
|
||||
public void Invoke(nint gameObject, string appliedCollectionName, nint modelIdAddress, nint customizeArrayAddress, nint equipDataAddress)
|
||||
=> Invoke(this, gameObject, appliedCollectionName, modelIdAddress, customizeArrayAddress, equipDataAddress);
|
||||
}
|
||||
26
Penumbra/Communication/EnabledChanged.cs
Normal file
26
Penumbra/Communication/EnabledChanged.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the general Enabled state of Penumbra is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is whether Penumbra is now Enabled (true) or Disabled (false). </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class EnabledChanged : EventWrapper<Action<bool>, EnabledChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.EnabledChange"/>
|
||||
Api = int.MinValue,
|
||||
}
|
||||
|
||||
public EnabledChanged()
|
||||
: base(nameof(EnabledChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(bool enabled)
|
||||
=> Invoke(this, enabled);
|
||||
}
|
||||
35
Penumbra/Communication/ModDataChanged.cs
Normal file
35
Penumbra/Communication/ModDataChanged.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever mod meta data or local data is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of data change for the mod, which can be multiple flags. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the old name of the mod in case of a name change, and null otherwise. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class ModDataChanged : EventWrapper<Action<ModDataChangeType, Mod, string?>, ModDataChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnModDataChange"/>
|
||||
ModFileSystemSelector = -10,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModCacheManager.OnModDataChange"/>
|
||||
ModCacheManager = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModFileSystem.OnDataChange"/>
|
||||
ModFileSystem = 0,
|
||||
}
|
||||
|
||||
public ModDataChanged()
|
||||
: base(nameof(ModDataChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModDataChangeType changeType, Mod mod, string? oldName)
|
||||
=> Invoke(this, changeType, mod, oldName);
|
||||
}
|
||||
30
Penumbra/Communication/ModDirectoryChanged.cs
Normal file
30
Penumbra/Communication/ModDirectoryChanged.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever the mod root directory changes.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the full path of the new directory. </item>
|
||||
/// <item>Parameter is whether the new directory is valid. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModDirectoryChanged : EventWrapper<Action<string, bool>, ModDirectoryChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.ModDirectoryChanged"/>
|
||||
Api = 0,
|
||||
|
||||
/// <seealso cref="UI.FileDialogService.OnModDirectoryChange"/>
|
||||
FileDialogService = 0,
|
||||
}
|
||||
|
||||
public ModDirectoryChanged()
|
||||
: base(nameof(ModDirectoryChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(string newModDirectory, bool newDirectoryValid)
|
||||
=> Invoke(this, newModDirectory, newDirectoryValid);
|
||||
}
|
||||
33
Penumbra/Communication/ModDiscoveryFinished.cs
Normal file
33
Penumbra/Communication/ModDiscoveryFinished.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary> Triggered whenever a new mod discovery has finished. </summary>
|
||||
public sealed class ModDiscoveryFinished : EventWrapper<Action, ModDiscoveryFinished.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.RestoreLastSelection"/>
|
||||
ModFileSystemSelector = -200,
|
||||
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModDiscoveryFinished"/>
|
||||
CollectionCacheManager = -100,
|
||||
|
||||
/// <seealso cref="Collections.Manager.CollectionStorage.OnModDiscoveryFinished"/>
|
||||
CollectionStorage = 0,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModCacheManager.OnModDiscoveryFinished"/>
|
||||
ModCacheManager = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModFileSystem.Reload"/>
|
||||
ModFileSystem = 0,
|
||||
}
|
||||
|
||||
public ModDiscoveryFinished()
|
||||
: base(nameof(ModDiscoveryFinished))
|
||||
{ }
|
||||
|
||||
public void Invoke()
|
||||
=> Invoke(this);
|
||||
}
|
||||
26
Penumbra/Communication/ModDiscoveryStarted.cs
Normal file
26
Penumbra/Communication/ModDiscoveryStarted.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary> Triggered whenever mods are prepared to be rediscovered. </summary>
|
||||
public sealed class ModDiscoveryStarted : EventWrapper<Action, ModDiscoveryStarted.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModDiscoveryStarted"/>
|
||||
CollectionCacheManager = 0,
|
||||
|
||||
/// <seealso cref="Collections.Manager.CollectionStorage.OnModDiscoveryStarted"/>
|
||||
CollectionStorage = 0,
|
||||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.StoreCurrentSelection"/>
|
||||
ModFileSystemSelector = 200,
|
||||
}
|
||||
public ModDiscoveryStarted()
|
||||
: base(nameof(ModDiscoveryStarted))
|
||||
{ }
|
||||
|
||||
public void Invoke()
|
||||
=> Invoke(this);
|
||||
}
|
||||
40
Penumbra/Communication/ModOptionChanged.cs
Normal file
40
Penumbra/Communication/ModOptionChanged.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever an option of a mod is changed inside the mod.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type option change. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the index of the changed group inside the mod. </item>
|
||||
/// <item>Parameter is the index of the changed option inside the group or -1 if it does not concern a specific option. </item>
|
||||
/// <item>Parameter is the index of the group an option was moved to. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class ModOptionChanged : EventWrapper<Action<ModOptionChangeType, Mod, int, int, int>, ModOptionChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModOptionChange"/>
|
||||
CollectionCacheManager = -100,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModCacheManager.OnModOptionChange"/>
|
||||
ModCacheManager = 0,
|
||||
|
||||
/// <seealso cref="UI.AdvancedWindow.ItemSwapTab.OnModOptionChange"/>
|
||||
ItemSwapTab = 0,
|
||||
|
||||
/// <seealso cref="Collections.Manager.CollectionStorage.OnModOptionChange"/>
|
||||
CollectionStorage = 100,
|
||||
}
|
||||
|
||||
public ModOptionChanged()
|
||||
: base(nameof(ModOptionChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModOptionChangeType changeType, Mod mod, int groupIndex, int optionIndex, int moveToIndex)
|
||||
=> Invoke(this, changeType, mod, groupIndex, optionIndex, moveToIndex);
|
||||
}
|
||||
54
Penumbra/Communication/ModPathChanged.cs
Normal file
54
Penumbra/Communication/ModPathChanged.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a mod is added, deleted, moved or reloaded.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of change. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the old directory on deletion, move or reload and null on addition. </item>
|
||||
/// <item>Parameter is the new directory on addition, move or reload and null on deletion. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModPathChanged : EventWrapper<Action<ModPathChangeType, Mod, DirectoryInfo?, DirectoryInfo?>, ModPathChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModChangeAddition"/>
|
||||
CollectionCacheManagerAddition = -100,
|
||||
|
||||
/// <seealso cref="Api.PenumbraApi.ModPathChangeSubscriber"/>
|
||||
Api = 0,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModCacheManager.OnModPathChange"/>
|
||||
ModCacheManager = 0,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModExportManager.OnModPathChange"/>
|
||||
ModExportManager = 0,
|
||||
|
||||
/// <seealso cref="Mods.ModFileSystem.OnModPathChange"/>
|
||||
ModFileSystem = 0,
|
||||
|
||||
/// <seealso cref="Mods.Manager.ModManager.OnModPathChange"/>
|
||||
ModManager = 0,
|
||||
|
||||
/// <seealso cref="Collections.Manager.CollectionStorage.OnModPathChange"/>
|
||||
CollectionStorage = 10,
|
||||
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModChangeRemoval"/>
|
||||
CollectionCacheManagerRemoval = 100,
|
||||
|
||||
|
||||
}
|
||||
public ModPathChanged()
|
||||
: base(nameof(ModPathChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModPathChangeType changeType, Mod mod, DirectoryInfo? oldModDirectory, DirectoryInfo? newModDirectory)
|
||||
=> Invoke(this, changeType, mod, oldModDirectory, newModDirectory);
|
||||
}
|
||||
43
Penumbra/Communication/ModSettingChanged.cs
Normal file
43
Penumbra/Communication/ModSettingChanged.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using System;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a mod setting is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the collection in which the setting was changed. </item>
|
||||
/// <item>Parameter is the type of change. </item>
|
||||
/// <item>Parameter is the mod the setting was changed for, unless it was a multi-change. </item>
|
||||
/// <item>Parameter is the old value of the setting before the change as int. </item>
|
||||
/// <item>Parameter is the index of the changed group if the change type is Setting. </item>
|
||||
/// <item>Parameter is whether the change was inherited from another collection. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModSettingChanged : EventWrapper<Action<ModCollection, ModSettingChange, Mod?, int, int, bool>, ModSettingChanged.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.OnModSettingChange"/>
|
||||
Api = int.MinValue,
|
||||
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModSettingChange"/>
|
||||
CollectionCacheManager = 0,
|
||||
|
||||
/// <seealso cref="UI.AdvancedWindow.ItemSwapTab.OnSettingChange"/>
|
||||
ItemSwapTab = 0,
|
||||
|
||||
/// <seealso cref="UI.ModsTab.ModFileSystemSelector.OnSettingChange"/>
|
||||
ModFileSystemSelector = 0,
|
||||
}
|
||||
|
||||
public ModSettingChanged()
|
||||
: base(nameof(ModSettingChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool inherited)
|
||||
=> Invoke(this, collection, type, mod, oldValue, groupIdx, inherited);
|
||||
}
|
||||
26
Penumbra/Communication/PostSettingsPanelDraw.cs
Normal file
26
Penumbra/Communication/PostSettingsPanelDraw.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered after the settings panel is drawn.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the identifier (directory name) of the currently selected mod. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class PostSettingsPanelDraw : EventWrapper<Action<string>, PostSettingsPanelDraw.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.PostSettingsPanelDraw"/>
|
||||
Default = 0,
|
||||
}
|
||||
|
||||
public PostSettingsPanelDraw()
|
||||
: base(nameof(PostSettingsPanelDraw))
|
||||
{ }
|
||||
|
||||
public void Invoke(string modDirectory)
|
||||
=> Invoke(this, modDirectory);
|
||||
}
|
||||
26
Penumbra/Communication/PreSettingsPanelDraw.cs
Normal file
26
Penumbra/Communication/PreSettingsPanelDraw.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered before the settings panel is drawn.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the identifier (directory name) of the currently selected mod. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class PreSettingsPanelDraw : EventWrapper<Action<string>, PreSettingsPanelDraw.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Api.PenumbraApi.PreSettingsPanelDraw"/>
|
||||
Default = 0,
|
||||
}
|
||||
|
||||
public PreSettingsPanelDraw()
|
||||
: base(nameof(PreSettingsPanelDraw))
|
||||
{ }
|
||||
|
||||
public void Invoke(string modDirectory)
|
||||
=> Invoke(this, modDirectory);
|
||||
}
|
||||
31
Penumbra/Communication/TemporaryGlobalModChange.cs
Normal file
31
Penumbra/Communication/TemporaryGlobalModChange.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a temporary mod for all collections is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter added, deleted or edited temporary mod.</item>
|
||||
/// <item>Parameter is whether the mod was newly created.</item>
|
||||
/// <item>Parameter is whether the mod was deleted.</item>
|
||||
/// </list> </summary>
|
||||
public sealed class TemporaryGlobalModChange : EventWrapper<Action<TemporaryMod, bool, bool>, TemporaryGlobalModChange.Priority>
|
||||
{
|
||||
public enum Priority
|
||||
{
|
||||
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnGlobalModChange"/>
|
||||
CollectionCacheManager = 0,
|
||||
|
||||
/// <seealso cref="Collections.Manager.TempCollectionManager.OnGlobalModChange"/>
|
||||
TempCollectionManager = 0,
|
||||
}
|
||||
|
||||
public TemporaryGlobalModChange()
|
||||
: base(nameof(TemporaryGlobalModChange))
|
||||
{ }
|
||||
|
||||
public void Invoke(TemporaryMod temporaryMod, bool newlyCreated, bool deleted)
|
||||
=> Invoke(this, temporaryMod, newlyCreated, deleted);
|
||||
}
|
||||
|
|
@ -5,7 +5,8 @@ using Dalamud.Game.ClientState;
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -26,7 +27,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(nint A
|
|||
_communicator = communicator;
|
||||
_events = events;
|
||||
|
||||
_communicator.CollectionChange.Subscribe(CollectionChangeClear);
|
||||
_communicator.CollectionChange.Subscribe(CollectionChangeClear, CollectionChange.Priority.IdentifiedCollectionCache);
|
||||
_clientState.TerritoryChanged += TerritoryClear;
|
||||
_events.CharacterDestructor += OnCharacterDestruct;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
@ -23,10 +24,10 @@ public class ModCacheManager : IDisposable
|
|||
_identifier = identifier;
|
||||
_modManager = modStorage;
|
||||
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.ModCacheManager);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModCacheManager);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange, ModDataChanged.Priority.ModCacheManager);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(OnModDiscoveryFinished, ModDiscoveryFinished.Priority.ModCacheManager);
|
||||
if (!identifier.Valid)
|
||||
identifier.FinishedCreation += OnIdentifierCreation;
|
||||
OnModDiscoveryFinished();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
|
@ -21,7 +22,7 @@ public class ModExportManager : IDisposable
|
|||
_communicator = communicator;
|
||||
_modManager = modManager;
|
||||
UpdateExportDirectory(_config.ExportDirectory, false);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModExportManager);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="UpdateExportDirectory(string, bool)"/>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
|
@ -25,9 +26,9 @@ public sealed class ModFileSystem : FileSystem<Mod>, IDisposable, ISavable
|
|||
_saveService = saveService;
|
||||
Reload();
|
||||
Changed += OnChange;
|
||||
_communicator.ModDiscoveryFinished.Subscribe(Reload);
|
||||
_communicator.ModDataChanged.Subscribe(OnDataChange);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(Reload, ModDiscoveryFinished.Priority.ModFileSystem);
|
||||
_communicator.ModDataChanged.Subscribe(OnDataChange, ModDataChanged.Priority.ModFileSystem);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModFileSystem);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
|
@ -50,7 +51,7 @@ public sealed class ModManager : ModStorage, IDisposable
|
|||
OptionEditor = optionEditor;
|
||||
Creator = creator;
|
||||
SetBaseDirectory(config.ModDirectory, true);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange);
|
||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModManager);
|
||||
DiscoverMods();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,350 +1,59 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Util;
|
||||
using Penumbra.Communication;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever collection setup is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of the changed collection. (Inactive or Temporary for additions or deletions)</item>
|
||||
/// <item>Parameter is the old collection, or null on additions.</item>
|
||||
/// <item>Parameter is the new collection, or null on deletions.</item>
|
||||
/// <item>Parameter is the display name for Individual collections or an empty string otherwise.</item>
|
||||
/// </list> </summary>
|
||||
public sealed class CollectionChange : EventWrapper<Action<CollectionType, ModCollection?, ModCollection?, string>>
|
||||
{
|
||||
public CollectionChange()
|
||||
: base(nameof(CollectionChange))
|
||||
{ }
|
||||
|
||||
public void Invoke(CollectionType collectionType, ModCollection? oldCollection, ModCollection? newCollection, string displayName)
|
||||
=> Invoke(this, collectionType, oldCollection, newCollection, displayName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a temporary mod for all collections is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter added, deleted or edited temporary mod.</item>
|
||||
/// <item>Parameter is whether the mod was newly created.</item>
|
||||
/// <item>Parameter is whether the mod was deleted.</item>
|
||||
/// </list> </summary>
|
||||
public sealed class TemporaryGlobalModChange : EventWrapper<Action<TemporaryMod, bool, bool>>
|
||||
{
|
||||
public TemporaryGlobalModChange()
|
||||
: base(nameof(TemporaryGlobalModChange))
|
||||
{ }
|
||||
|
||||
public void Invoke(TemporaryMod temporaryMod, bool newlyCreated, bool deleted)
|
||||
=> Invoke(this, temporaryMod, newlyCreated, deleted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a character base draw object is being created by the game.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the game object for which a draw object is created. </item>
|
||||
/// <item>Parameter is the name of the applied collection. </item>
|
||||
/// <item>Parameter is a pointer to the model id (an uint). </item>
|
||||
/// <item>Parameter is a pointer to the customize array. </item>
|
||||
/// <item>Parameter is a pointer to the equip data array. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class CreatingCharacterBase : EventWrapper<Action<nint, string, nint, nint, nint>>
|
||||
{
|
||||
public CreatingCharacterBase()
|
||||
: base(nameof(CreatingCharacterBase))
|
||||
{ }
|
||||
|
||||
public void Invoke(nint gameObject, string appliedCollectionName, nint modelIdAddress, nint customizeArrayAddress, nint equipDataAddress)
|
||||
=> Invoke(this, gameObject, appliedCollectionName, modelIdAddress, customizeArrayAddress, equipDataAddress);
|
||||
}
|
||||
|
||||
/// <summary> <list type="number">
|
||||
/// <item>Parameter is the game object for which a draw object is created. </item>
|
||||
/// <item>Parameter is the name of the applied collection. </item>
|
||||
/// <item>Parameter is the created draw object. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class CreatedCharacterBase : EventWrapper<Action<nint, string, nint>>
|
||||
{
|
||||
public CreatedCharacterBase()
|
||||
: base(nameof(CreatedCharacterBase))
|
||||
{ }
|
||||
|
||||
public void Invoke(nint gameObject, string appliedCollectionName, nint drawObject)
|
||||
=> Invoke(this, gameObject, appliedCollectionName, drawObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever mod meta data or local data is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of data change for the mod, which can be multiple flags. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the old name of the mod in case of a name change, and null otherwise. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class ModDataChanged : EventWrapper<Action<ModDataChangeType, Mod, string?>>
|
||||
{
|
||||
public ModDataChanged()
|
||||
: base(nameof(ModDataChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModDataChangeType changeType, Mod mod, string? oldName)
|
||||
=> Invoke(this, changeType, mod, oldName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever an option of a mod is changed inside the mod.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type option change. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the index of the changed group inside the mod. </item>
|
||||
/// <item>Parameter is the index of the changed option inside the group or -1 if it does not concern a specific option. </item>
|
||||
/// <item>Parameter is the index of the group an option was moved to. </item>
|
||||
/// </list> </summary>
|
||||
public sealed class ModOptionChanged : EventWrapper<Action<ModOptionChangeType, Mod, int, int, int>>
|
||||
{
|
||||
public ModOptionChanged()
|
||||
: base(nameof(ModOptionChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModOptionChangeType changeType, Mod mod, int groupIndex, int optionIndex, int moveToIndex)
|
||||
=> Invoke(this, changeType, mod, groupIndex, optionIndex, moveToIndex);
|
||||
}
|
||||
|
||||
/// <summary> Triggered whenever mods are prepared to be rediscovered. </summary>
|
||||
public sealed class ModDiscoveryStarted : EventWrapper<Action>
|
||||
{
|
||||
public ModDiscoveryStarted()
|
||||
: base(nameof(ModDiscoveryStarted))
|
||||
{ }
|
||||
|
||||
public void Invoke()
|
||||
=> EventWrapper<Action>.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary> Triggered whenever a new mod discovery has finished. </summary>
|
||||
public sealed class ModDiscoveryFinished : EventWrapper<Action>
|
||||
{
|
||||
public ModDiscoveryFinished()
|
||||
: base(nameof(ModDiscoveryFinished))
|
||||
{ }
|
||||
|
||||
public void Invoke()
|
||||
=> Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever the mod root directory changes.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the full path of the new directory. </item>
|
||||
/// <item>Parameter is whether the new directory is valid. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModDirectoryChanged : EventWrapper<Action<string, bool>>
|
||||
{
|
||||
public ModDirectoryChanged()
|
||||
: base(nameof(ModDirectoryChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(string newModDirectory, bool newDirectoryValid)
|
||||
=> Invoke(this, newModDirectory, newDirectoryValid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a mod is added, deleted, moved or reloaded.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the type of change. </item>
|
||||
/// <item>Parameter is the changed mod. </item>
|
||||
/// <item>Parameter is the old directory on deletion, move or reload and null on addition. </item>
|
||||
/// <item>Parameter is the new directory on addition, move or reload and null on deletion. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModPathChanged : EventWrapper<Action<ModPathChangeType, Mod, DirectoryInfo?, DirectoryInfo?>>
|
||||
{
|
||||
public ModPathChanged()
|
||||
: base(nameof(ModPathChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModPathChangeType changeType, Mod mod, DirectoryInfo? oldModDirectory, DirectoryInfo? newModDirectory)
|
||||
=> Invoke(this, changeType, mod, oldModDirectory, newModDirectory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a mod setting is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the collection in which the setting was changed. </item>
|
||||
/// <item>Parameter is the type of change. </item>
|
||||
/// <item>Parameter is the mod the setting was changed for, unless it was a multi-change. </item>
|
||||
/// <item>Parameter is the old value of the setting before the change as int. </item>
|
||||
/// <item>Parameter is the index of the changed group if the change type is Setting. </item>
|
||||
/// <item>Parameter is whether the change was inherited from another collection. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ModSettingChanged : EventWrapper<Action<ModCollection, ModSettingChange, Mod?, int, int, bool>>
|
||||
{
|
||||
public ModSettingChanged()
|
||||
: base(nameof(ModSettingChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool inherited)
|
||||
=> Invoke(this, collection, type, mod, oldValue, groupIdx, inherited);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered whenever a collections inheritances change.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the collection whose ancestors were changed. </item>
|
||||
/// <item>Parameter is whether the change was itself inherited, i.e. if it happened in a direct parent (false) or a more removed ancestor (true). </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class CollectionInheritanceChanged : EventWrapper<Action<ModCollection, bool>>
|
||||
{
|
||||
public CollectionInheritanceChanged()
|
||||
: base(nameof(CollectionInheritanceChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(ModCollection collection, bool inherited)
|
||||
=> Invoke(this, collection, inherited);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the general Enabled state of Penumbra is changed.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is whether Penumbra is now Enabled (true) or Disabled (false). </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class EnabledChanged : EventWrapper<Action<bool>>
|
||||
{
|
||||
public EnabledChanged()
|
||||
: base(nameof(EnabledChanged))
|
||||
{ }
|
||||
|
||||
public void Invoke(bool enabled)
|
||||
=> Invoke(this, enabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered before the settings panel is drawn.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the identifier (directory name) of the currently selected mod. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class PreSettingsPanelDraw : EventWrapper<Action<string>>
|
||||
{
|
||||
public PreSettingsPanelDraw()
|
||||
: base(nameof(PreSettingsPanelDraw))
|
||||
{ }
|
||||
|
||||
public void Invoke(string modDirectory)
|
||||
=> Invoke(this, modDirectory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered after the settings panel is drawn.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the identifier (directory name) of the currently selected mod. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class PostSettingsPanelDraw : EventWrapper<Action<string>>
|
||||
{
|
||||
public PostSettingsPanelDraw()
|
||||
: base(nameof(PostSettingsPanelDraw))
|
||||
{ }
|
||||
|
||||
public void Invoke(string modDirectory)
|
||||
=> Invoke(this, modDirectory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a Changed Item in Penumbra is hovered.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the hovered object data if any. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ChangedItemHover : EventWrapper<Action<object?>>
|
||||
{
|
||||
public ChangedItemHover()
|
||||
: base(nameof(ChangedItemHover))
|
||||
{ }
|
||||
|
||||
public void Invoke(object? data)
|
||||
=> Invoke(this, data);
|
||||
|
||||
public bool HasTooltip
|
||||
=> HasSubscribers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a Changed Item in Penumbra is clicked.
|
||||
/// <list type="number">
|
||||
/// <item>Parameter is the clicked mouse button. </item>
|
||||
/// <item>Parameter is the clicked object data if any.. </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class ChangedItemClick : EventWrapper<Action<MouseButton, object?>>
|
||||
{
|
||||
public ChangedItemClick()
|
||||
: base(nameof(ChangedItemClick))
|
||||
{ }
|
||||
|
||||
public void Invoke(MouseButton button, object? data)
|
||||
=> Invoke(this, button, data);
|
||||
}
|
||||
|
||||
public class CommunicatorService : IDisposable
|
||||
{
|
||||
/// <inheritdoc cref="Services.CollectionChange"/>
|
||||
/// <inheritdoc cref="Communication.CollectionChange"/>
|
||||
public readonly CollectionChange CollectionChange = new();
|
||||
|
||||
/// <inheritdoc cref="Services.TemporaryGlobalModChange"/>
|
||||
/// <inheritdoc cref="Communication.TemporaryGlobalModChange"/>
|
||||
public readonly TemporaryGlobalModChange TemporaryGlobalModChange = new();
|
||||
|
||||
/// <inheritdoc cref="Services.CreatingCharacterBase"/>
|
||||
/// <inheritdoc cref="Communication.CreatingCharacterBase"/>
|
||||
public readonly CreatingCharacterBase CreatingCharacterBase = new();
|
||||
|
||||
/// <inheritdoc cref="Services.CreatedCharacterBase"/>
|
||||
/// <inheritdoc cref="Communication.CreatedCharacterBase"/>
|
||||
public readonly CreatedCharacterBase CreatedCharacterBase = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModDataChanged"/>
|
||||
/// <inheritdoc cref="Communication.ModDataChanged"/>
|
||||
public readonly ModDataChanged ModDataChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModOptionChanged"/>
|
||||
/// <inheritdoc cref="Communication.ModOptionChanged"/>
|
||||
public readonly ModOptionChanged ModOptionChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModDiscoveryStarted"/>
|
||||
/// <inheritdoc cref="Communication.ModDiscoveryStarted"/>
|
||||
public readonly ModDiscoveryStarted ModDiscoveryStarted = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModDiscoveryFinished"/>
|
||||
/// <inheritdoc cref="Communication.ModDiscoveryFinished"/>
|
||||
public readonly ModDiscoveryFinished ModDiscoveryFinished = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModDirectoryChanged"/>
|
||||
/// <inheritdoc cref="Communication.ModDirectoryChanged"/>
|
||||
public readonly ModDirectoryChanged ModDirectoryChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModPathChanged"/>
|
||||
/// <inheritdoc cref="Communication.ModPathChanged"/>
|
||||
public readonly ModPathChanged ModPathChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ModSettingChanged"/>
|
||||
/// <inheritdoc cref="Communication.ModSettingChanged"/>
|
||||
public readonly ModSettingChanged ModSettingChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.CollectionInheritanceChanged"/>
|
||||
/// <inheritdoc cref="Communication.CollectionInheritanceChanged"/>
|
||||
public readonly CollectionInheritanceChanged CollectionInheritanceChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.EnabledChanged"/>
|
||||
/// <inheritdoc cref="Communication.EnabledChanged"/>
|
||||
public readonly EnabledChanged EnabledChanged = new();
|
||||
|
||||
/// <inheritdoc cref="Services.PreSettingsPanelDraw"/>
|
||||
/// <inheritdoc cref="Communication.PreSettingsPanelDraw"/>
|
||||
public readonly PreSettingsPanelDraw PreSettingsPanelDraw = new();
|
||||
|
||||
/// <inheritdoc cref="Services.PostSettingsPanelDraw"/>
|
||||
/// <inheritdoc cref="Communication.PostSettingsPanelDraw"/>
|
||||
public readonly PostSettingsPanelDraw PostSettingsPanelDraw = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ChangedItemHover"/>
|
||||
/// <inheritdoc cref="Communication.ChangedItemHover"/>
|
||||
public readonly ChangedItemHover ChangedItemHover = new();
|
||||
|
||||
/// <inheritdoc cref="Services.ChangedItemClick"/>
|
||||
/// <inheritdoc cref="Communication.ChangedItemClick"/>
|
||||
public readonly ChangedItemClick ChangedItemClick = new();
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using OtterGui.Widgets;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Meta;
|
||||
|
|
@ -57,10 +58,10 @@ public class ItemSwapTab : IDisposable, ITab
|
|||
// @formatter:on
|
||||
};
|
||||
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ItemSwapTab);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange, ModSettingChanged.Priority.ItemSwapTab);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange, CollectionInheritanceChanged.Priority.ItemSwapTab);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.ItemSwapTab);
|
||||
}
|
||||
|
||||
/// <summary> Update the currently selected mod or its settings. </summary>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using OtterGui;
|
|||
using OtterGui.Raii;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
|
|
@ -34,7 +35,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
|
|||
_active = active;
|
||||
_tutorial = tutorial;
|
||||
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.CollectionSelector);
|
||||
// Set items.
|
||||
OnCollectionChange(CollectionType.Inactive, null, null, string.Empty);
|
||||
// Set selection.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using ImGuiNET;
|
|||
using OtterGui.Raii;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.Services;
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ public class IndividualAssignmentUi : IDisposable
|
|||
_communicator = communicator;
|
||||
_actorService = actors;
|
||||
_collectionManager = collectionManager;
|
||||
_communicator.CollectionChange.Subscribe(UpdateIdentifiers);
|
||||
_communicator.CollectionChange.Subscribe(UpdateIdentifiers, CollectionChange.Priority.IndividualAssignmentUi);
|
||||
if (_actorService.Valid)
|
||||
SetupCombos();
|
||||
else
|
||||
|
|
@ -57,7 +58,7 @@ public class IndividualAssignmentUi : IDisposable
|
|||
public void DrawWorldCombo(float width)
|
||||
{
|
||||
if (_ready && _worldCombo.Draw(width))
|
||||
UpdateIdentifiers();
|
||||
UpdateIdentifiersInternal();
|
||||
}
|
||||
|
||||
public void DrawObjectKindCombo(float width)
|
||||
|
|
@ -76,7 +77,7 @@ public class IndividualAssignmentUi : IDisposable
|
|||
continue;
|
||||
|
||||
_newKind = kind;
|
||||
UpdateIdentifiers();
|
||||
UpdateIdentifiersInternal();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ public class IndividualAssignmentUi : IDisposable
|
|||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
if (ImGui.InputTextWithHint("##NewCharacter", "Character Name...", ref _newCharacterName, 32))
|
||||
UpdateIdentifiers();
|
||||
UpdateIdentifiersInternal();
|
||||
}
|
||||
|
||||
public void DrawNewNpcCollection(float width)
|
||||
|
|
@ -97,7 +98,7 @@ public class IndividualAssignmentUi : IDisposable
|
|||
|
||||
var combo = GetNpcCombo(_newKind);
|
||||
if (combo.Draw(width))
|
||||
UpdateIdentifiers();
|
||||
UpdateIdentifiersInternal();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -154,10 +155,10 @@ public class IndividualAssignmentUi : IDisposable
|
|||
private void UpdateIdentifiers(CollectionType type, ModCollection? _1, ModCollection? _2, string _3)
|
||||
{
|
||||
if (type == CollectionType.Individual)
|
||||
UpdateIdentifiers();
|
||||
UpdateIdentifiersInternal();
|
||||
}
|
||||
|
||||
private void UpdateIdentifiers()
|
||||
private void UpdateIdentifiersInternal()
|
||||
{
|
||||
var combo = GetNpcCombo(_newKind);
|
||||
PlayerTooltip = _collectionManager.Active.Individuals.CanAdd(IdentifierType.Player, _newCharacterName,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Dalamud.Interface.ImGuiFileDialog;
|
|||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
|
@ -22,9 +23,9 @@ public class FileDialogService : IDisposable
|
|||
|
||||
public FileDialogService(CommunicatorService communicator, Configuration config)
|
||||
{
|
||||
_communicator = communicator;
|
||||
_manager = SetupFileManager(config.ModDirectory);
|
||||
_communicator.ModDirectoryChanged.Subscribe(OnModDirectoryChange);
|
||||
_communicator = communicator;
|
||||
_manager = SetupFileManager(config.ModDirectory);
|
||||
_communicator.ModDirectoryChanged.Subscribe(OnModDirectoryChange, ModDirectoryChanged.Priority.FileDialogService);
|
||||
}
|
||||
|
||||
public void OpenFilePicker(string title, string filters, Action<bool, List<string>> callback, int selectionCountMax, string? startPath,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ using OtterGui.Raii;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -72,12 +73,12 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
|
|||
SetFilterTooltip();
|
||||
|
||||
SelectionChanged += OnSelectionChange;
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(StoreCurrentSelection);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(RestoreLastSelection);
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange, CollectionChange.Priority.ModFileSystemSelector);
|
||||
_communicator.ModSettingChanged.Subscribe(OnSettingChange, ModSettingChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnInheritanceChange, CollectionInheritanceChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDataChanged.Subscribe(OnModDataChange, ModDataChanged.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDiscoveryStarted.Subscribe(StoreCurrentSelection, ModDiscoveryStarted.Priority.ModFileSystemSelector);
|
||||
_communicator.ModDiscoveryFinished.Subscribe(RestoreLastSelection, ModDiscoveryFinished.Priority.ModFileSystemSelector);
|
||||
OnCollectionChange(CollectionType.Current, null, _collectionManager.Active.Current, "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ using System.Linq;
|
|||
|
||||
namespace Penumbra.Util;
|
||||
|
||||
public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
||||
public abstract class EventWrapper<T, TPriority> : IDisposable
|
||||
where T : Delegate
|
||||
where TPriority : struct, Enum
|
||||
{
|
||||
private readonly string _name;
|
||||
private readonly List<(object Subscriber, int Priority)> _event = new();
|
||||
private readonly string _name;
|
||||
private readonly List<(object Subscriber, TPriority Priority)> _event = new();
|
||||
|
||||
public bool HasSubscribers
|
||||
=> _event.Count > 0;
|
||||
|
|
@ -23,12 +25,12 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
public void Subscribe(T subscriber, int priority = 0)
|
||||
public void Subscribe(T subscriber, TPriority priority)
|
||||
{
|
||||
lock (_event)
|
||||
{
|
||||
var existingIdx = _event.FindIndex(p => (T) p.Subscriber == subscriber);
|
||||
var idx = _event.FindIndex(p => p.Priority > priority);
|
||||
var existingIdx = _event.FindIndex(p => (T)p.Subscriber == subscriber);
|
||||
var idx = _event.FindIndex(p => p.Priority.CompareTo(priority) > 0);
|
||||
if (idx == existingIdx)
|
||||
{
|
||||
if (idx < 0)
|
||||
|
|
@ -53,14 +55,14 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
{
|
||||
lock (_event)
|
||||
{
|
||||
var idx = _event.FindIndex(p => (T) p.Subscriber == subscriber);
|
||||
var idx = _event.FindIndex(p => (T)p.Subscriber == subscriber);
|
||||
if (idx >= 0)
|
||||
_event.RemoveAt(idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static void Invoke(EventWrapper<T> wrapper)
|
||||
protected static void Invoke(EventWrapper<T, TPriority> wrapper)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -78,7 +80,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1>(EventWrapper<T> wrapper, T1 a)
|
||||
protected static void Invoke<T1>(EventWrapper<T, TPriority> wrapper, T1 a)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -96,7 +98,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1, T2>(EventWrapper<T> wrapper, T1 a, T2 b)
|
||||
protected static void Invoke<T1, T2>(EventWrapper<T, TPriority> wrapper, T1 a, T2 b)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -114,7 +116,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1, T2, T3>(EventWrapper<T> wrapper, T1 a, T2 b, T3 c)
|
||||
protected static void Invoke<T1, T2, T3>(EventWrapper<T, TPriority> wrapper, T1 a, T2 b, T3 c)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -132,7 +134,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1, T2, T3, T4>(EventWrapper<T> wrapper, T1 a, T2 b, T3 c, T4 d)
|
||||
protected static void Invoke<T1, T2, T3, T4>(EventWrapper<T, TPriority> wrapper, T1 a, T2 b, T3 c, T4 d)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -150,7 +152,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1, T2, T3, T4, T5>(EventWrapper<T> wrapper, T1 a, T2 b, T3 c, T4 d, T5 e)
|
||||
protected static void Invoke<T1, T2, T3, T4, T5>(EventWrapper<T, TPriority> wrapper, T1 a, T2 b, T3 c, T4 d, T5 e)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
@ -168,7 +170,7 @@ public abstract class EventWrapper<T> : IDisposable where T : Delegate
|
|||
}
|
||||
}
|
||||
|
||||
protected static void Invoke<T1, T2, T3, T4, T5, T6>(EventWrapper<T> wrapper, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f)
|
||||
protected static void Invoke<T1, T2, T3, T4, T5, T6>(EventWrapper<T, TPriority> wrapper, T1 a, T2 b, T3 c, T4 d, T5 e, T6 f)
|
||||
{
|
||||
lock (wrapper._event)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue