Skip to content

Commit

Permalink
Respect name override + allow export cancel
Browse files Browse the repository at this point in the history
  • Loading branch information
PassiveModding committed Aug 31, 2024
1 parent 3d68908 commit f6e03e1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 12 deletions.
46 changes: 38 additions & 8 deletions Meddle/Meddle.Plugin/Models/Composer/InstanceComposer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Numerics;
using System.Collections.Concurrent;
using System.Numerics;
using System.Runtime.InteropServices;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Meddle.Plugin.Models.Layout;
using Meddle.Plugin.Utils;
using Meddle.Utils;
Expand All @@ -18,35 +20,56 @@ namespace Meddle.Plugin.Models.Composer;

public class InstanceComposer
{
public InstanceComposer(ILogger log, SqPack manager, ParsedInstance[] instances, string? cacheDir = null,
public InstanceComposer(ILogger log, SqPack manager, Configuration config, ParsedInstance[] instances, string? cacheDir = null,
Action<ProgressEvent>? progress = null, CancellationToken cancellationToken = default)
{
CacheDir = cacheDir ?? Path.GetTempPath();
Directory.CreateDirectory(CacheDir);
this.instances = instances;
this.log = log;
this.dataManager = manager;
this.config = config;
this.progress = progress;
this.cancellationToken = cancellationToken;
this.count = instances.Length;
}

private readonly ILogger log;
private readonly SqPack dataManager;
private readonly Configuration config;
private readonly Action<ProgressEvent>? progress;
private readonly CancellationToken cancellationToken;
private readonly int count;
private int countProgress;
public string CacheDir { get; }
private readonly ParsedInstance[] instances;
private readonly Dictionary<string, (string PathOnDisk, MemoryImage MemoryImage)> imageCache = new();
private readonly Dictionary<string, (ShpkFile File, ShaderPackage Package)> shpkCache = new();
private readonly Dictionary<string, MaterialBuilder> mtrlCache = new();
private readonly ConcurrentDictionary<string, (string PathOnDisk, MemoryImage MemoryImage)> imageCache = new();
private readonly ConcurrentDictionary<string, (ShpkFile File, ShaderPackage Package)> shpkCache = new();
private readonly ConcurrentDictionary<string, MaterialBuilder> mtrlCache = new();

public void Compose(SceneBuilder scene)
{
progress?.Invoke(new ProgressEvent("Export", 0, count));
foreach (var instance in instances)
Parallel.ForEach(instances, instance =>
{
try
{
var node = ComposeInstance(scene, instance);
if (node != null)
{
scene.AddNode(node);
}
}
catch (Exception ex)
{
log.LogError(ex, "Failed to compose instance {instanceId} {instanceType}", instance.Id, instance.Type);
}

//countProgress++;
Interlocked.Increment(ref countProgress);
progress?.Invoke(new ProgressEvent("Export", countProgress, count));
});
/*foreach (var instance in instances)
{
try
{
Expand All @@ -63,7 +86,7 @@ public void Compose(SceneBuilder scene)
countProgress++;
progress?.Invoke(new ProgressEvent("Export", countProgress, count));
}
}*/
}

public NodeBuilder? ComposeInstance(SceneBuilder scene, ParsedInstance parsedInstance)
Expand Down Expand Up @@ -93,7 +116,14 @@ public void Compose(SceneBuilder scene)

if (parsedInstance is ParsedCharacterInstance { CharacterInfo: not null } characterInstance)
{
root.Name = $"{characterInstance.Type}_{characterInstance.Kind}_{characterInstance.Name}";
if (characterInstance.Kind == ObjectKind.Pc && !string.IsNullOrWhiteSpace(config.PlayerNameOverride))
{
root.Name = $"{characterInstance.Type}_{characterInstance.Kind}_{config.PlayerNameOverride}";
}
else
{
root.Name = $"{characterInstance.Type}_{characterInstance.Kind}_{characterInstance.Name}";
}
ComposeCharacterInstance(characterInstance, scene, root);
wasAdded = true;
}
Expand Down
2 changes: 2 additions & 0 deletions Meddle/Meddle.Plugin/UI/Layout/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ public partial class LayoutWindow
[Flags]
public enum ExportType
{
// ReSharper disable InconsistentNaming
GLTF = 1,
GLB = 2,
OBJ = 4
// ReSharper restore InconsistentNaming
}

private const ParsedInstanceType DefaultDrawTypes = ParsedInstanceType.Character | ParsedInstanceType.Housing | ParsedInstanceType.Terrain | ParsedInstanceType.BgPart | ParsedInstanceType.SharedGroup;
Expand Down
15 changes: 14 additions & 1 deletion Meddle/Meddle.Plugin/UI/Layout/Instance.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Numerics;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Utility.Raii;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using ImGuiNET;
using Meddle.Plugin.Models.Layout;
using Meddle.Plugin.Utils;
Expand Down Expand Up @@ -41,10 +42,22 @@ private void DrawInstance(ParsedInstance instance, Stack<ParsedInstance> stack,
ParsedHousingInstance housingObject => $"{housingObject.Type} - {housingObject.Name}",
ParsedBgPartsInstance bgObject => $"{bgObject.Type} - {bgObject.Path}",
ParsedUnsupportedInstance unsupported => $"{unsupported.Type} - {unsupported.InstanceType}",
ParsedCharacterInstance character => $"{character.Type} - {character.Kind} - {character.Name}",
ParsedCharacterInstance character => $"{character.Type} - {character.Kind}",
_ => $"{instance.Type}"
};

if (instance is ParsedCharacterInstance ci)
{
if (!string.IsNullOrWhiteSpace(config.PlayerNameOverride) && ci.Kind == ObjectKind.Pc)
{
infoHeader += $" - {config.PlayerNameOverride}";
}
else
{
infoHeader += $" - {ci.Name}";
}
}

if (instance is ParsedSharedInstance {Children.Count: > 0} shared)
{
var childTypeGroups = shared.Children.GroupBy(x => x.Type);
Expand Down
13 changes: 10 additions & 3 deletions Meddle/Meddle.Plugin/UI/Layout/LayoutWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public partial class LayoutWindow : Window

private ProgressEvent? progress;
private Task exportTask = Task.CompletedTask;
private CancellationTokenSource cancelToken = new();
private ParsedInstance[] currentLayout = [];
private readonly Dictionary<nint, ParsedInstance> selectedInstances = new();
private Vector3 currentPos;
Expand Down Expand Up @@ -81,6 +82,11 @@ public override void Draw()
ImGui.ProgressBar(subProgress.Progress / (float)subProgress.Total, new Vector2(-1, 0), subProgress.Name);
subProgress = subProgress.SubProgress;
}

if (ImGui.Button("Cancel"))
{
cancelToken.Cancel();
}
}

if (exportTask.IsFaulted)
Expand Down Expand Up @@ -263,6 +269,7 @@ private void InstanceExport(ParsedInstance[] instances)

var defaultName = $"InstanceExport-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}";
var currentExportType = exportType;
cancelToken = new CancellationTokenSource();
fileDialog.SaveFolderDialog("Save Instances", defaultName,
(result, path) =>
{
Expand All @@ -273,8 +280,8 @@ private void InstanceExport(ParsedInstance[] instances)
var cacheDir = Path.Combine(path, "cache");
Directory.CreateDirectory(cacheDir);
var instanceSet =
new InstanceComposer(log, dataManager, instances, cacheDir,
x => progress = x);
new InstanceComposer(log, dataManager, config, instances, cacheDir,
x => progress = x, cancelToken.Token);
var scene = new SceneBuilder();
instanceSet.Compose(scene);
var gltf = scene.ToGltf2();
Expand All @@ -294,7 +301,7 @@ private void InstanceExport(ParsedInstance[] instances)
}

Process.Start("explorer.exe", path);
});
}, cancelToken.Token);
}, Plugin.TempDirectory);
}
}

0 comments on commit f6e03e1

Please sign in to comment.