Material editor: tear down previewers bound to a CharacterBase that goes away

This commit is contained in:
Exter-N 2023-08-30 01:51:43 +02:00
parent bb8d9441f4
commit 5346abaadf
3 changed files with 33 additions and 2 deletions

View file

@ -154,7 +154,7 @@ public partial class ModEditWindow
protected readonly int ModelSlot; protected readonly int ModelSlot;
protected readonly int MaterialSlot; protected readonly int MaterialSlot;
protected readonly CharacterBase* DrawObject; public readonly CharacterBase* DrawObject;
protected readonly Material* Material; protected readonly Material* Material;
protected bool Valid; protected bool Valid;

View file

@ -512,6 +512,29 @@ public partial class ModEditWindow
ColorSetPreviewers.Clear(); ColorSetPreviewers.Clear();
} }
public unsafe void UnbindFromDrawObjectMaterialInstances(nint characterBase)
{
for (var i = MaterialPreviewers.Count; i-- > 0; )
{
var previewer = MaterialPreviewers[i];
if ((nint)previewer.DrawObject != characterBase)
continue;
previewer.Dispose();
MaterialPreviewers.RemoveAt(i);
}
for (var i = ColorSetPreviewers.Count; i-- > 0;)
{
var previewer = ColorSetPreviewers[i];
if ((nint)previewer.DrawObject != characterBase)
continue;
previewer.Dispose();
ColorSetPreviewers.RemoveAt(i);
}
}
public void SetShaderPackageFlags(uint shPkFlags) public void SetShaderPackageFlags(uint shPkFlags)
{ {
foreach (var previewer in MaterialPreviewers) foreach (var previewer in MaterialPreviewers)
@ -665,7 +688,10 @@ public partial class ModEditWindow
AssociatedBaseDevkit = TryLoadShpkDevkit( "_base", out LoadedBaseDevkitPathName ); AssociatedBaseDevkit = TryLoadShpkDevkit( "_base", out LoadedBaseDevkitPathName );
LoadShpk( FindAssociatedShpk( out _, out _ ) ); LoadShpk( FindAssociatedShpk( out _, out _ ) );
if (writable) if (writable)
{
_edit._gameEvents.CharacterBaseDestructor += UnbindFromDrawObjectMaterialInstances;
BindToMaterialInstances(); BindToMaterialInstances();
}
} }
~MtrlTab() ~MtrlTab()
@ -682,6 +708,8 @@ public partial class ModEditWindow
private void DoDispose() private void DoDispose()
{ {
UnbindFromMaterialInstances(); UnbindFromMaterialInstances();
if (Writable)
_edit._gameEvents.CharacterBaseDestructor -= UnbindFromDrawObjectMaterialInstances;
} }
public bool Valid public bool Valid

View file

@ -19,6 +19,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Files; using Penumbra.GameData.Files;
using Penumbra.Import.Textures; using Penumbra.Import.Textures;
using Penumbra.Interop.ResourceTree; using Penumbra.Interop.ResourceTree;
using Penumbra.Interop.Services;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Mods.Manager; using Penumbra.Mods.Manager;
@ -45,6 +46,7 @@ public partial class ModEditWindow : Window, IDisposable
private readonly ModMergeTab _modMergeTab; private readonly ModMergeTab _modMergeTab;
private readonly CommunicatorService _communicator; private readonly CommunicatorService _communicator;
private readonly IDragDropManager _dragDropManager; private readonly IDragDropManager _dragDropManager;
private readonly GameEventManager _gameEvents;
private Mod? _mod; private Mod? _mod;
private Vector2 _iconSize = Vector2.Zero; private Vector2 _iconSize = Vector2.Zero;
@ -546,7 +548,7 @@ public partial class ModEditWindow : Window, IDisposable
public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, IDataManager gameData, public ModEditWindow(PerformanceTracker performance, FileDialogService fileDialog, ItemSwapTab itemSwapTab, IDataManager gameData,
Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager, Configuration config, ModEditor editor, ResourceTreeFactory resourceTreeFactory, MetaFileManager metaFileManager,
StainService stainService, ActiveCollections activeCollections, DalamudServices dalamud, ModMergeTab modMergeTab, StainService stainService, ActiveCollections activeCollections, DalamudServices dalamud, ModMergeTab modMergeTab,
CommunicatorService communicator, TextureManager textures, IDragDropManager dragDropManager) CommunicatorService communicator, TextureManager textures, IDragDropManager dragDropManager, GameEventManager gameEvents)
: base(WindowBaseLabel) : base(WindowBaseLabel)
{ {
_performance = performance; _performance = performance;
@ -562,6 +564,7 @@ public partial class ModEditWindow : Window, IDisposable
_dragDropManager = dragDropManager; _dragDropManager = dragDropManager;
_textures = textures; _textures = textures;
_fileDialog = fileDialog; _fileDialog = fileDialog;
_gameEvents = gameEvents;
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl", _materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl",
() => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty, () => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable)); (bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));