275 lines
7.5 KiB
C#
275 lines
7.5 KiB
C#
// Copyright © Gamesmiths Guild.
|
|
|
|
#if TOOLS
|
|
using System;
|
|
using System.Diagnostics;
|
|
using Gamesmiths.Forge.Core;
|
|
using Gamesmiths.Forge.Godot.Core;
|
|
using Gamesmiths.Forge.Godot.Editor;
|
|
using Gamesmiths.Forge.Godot.Editor.Attributes;
|
|
using Gamesmiths.Forge.Godot.Editor.Cues;
|
|
using Gamesmiths.Forge.Godot.Editor.Statescript;
|
|
using Gamesmiths.Forge.Godot.Editor.Tags;
|
|
using Gamesmiths.Forge.Godot.Resources.Statescript;
|
|
using Godot;
|
|
|
|
namespace Gamesmiths.Forge.Godot;
|
|
|
|
[Tool]
|
|
public partial class ForgePluginLoader : EditorPlugin
|
|
{
|
|
private const string AutoloadPath = "uid://ba8fquhtwu5mu";
|
|
|
|
private TagsEditorDock? _tagsEditorDock;
|
|
private TagContainerInspectorPlugin? _tagContainerInspectorPlugin;
|
|
private TagInspectorPlugin? _tagInspectorPlugin;
|
|
private AttributeSetInspectorPlugin? _attributeSetInspectorPlugin;
|
|
private CueHandlerInspectorPlugin? _cueHandlerInspectorPlugin;
|
|
private AttributeEditorPlugin? _attributeEditorPlugin;
|
|
private SharedVariableSetInspectorPlugin? _sharedVariableSetInspectorPlugin;
|
|
private StatescriptGraphEditorDock? _statescriptGraphEditorDock;
|
|
|
|
private EditorFileSystem? _fileSystem;
|
|
private Callable _resourcesReimportedCallable;
|
|
|
|
public override void _EnterTree()
|
|
{
|
|
EnsureForgeDataExists();
|
|
|
|
_tagsEditorDock = new TagsEditorDock();
|
|
AddDock(_tagsEditorDock);
|
|
|
|
_tagContainerInspectorPlugin = new TagContainerInspectorPlugin();
|
|
AddInspectorPlugin(_tagContainerInspectorPlugin);
|
|
_tagInspectorPlugin = new TagInspectorPlugin();
|
|
AddInspectorPlugin(_tagInspectorPlugin);
|
|
_attributeSetInspectorPlugin = new AttributeSetInspectorPlugin();
|
|
AddInspectorPlugin(_attributeSetInspectorPlugin);
|
|
_cueHandlerInspectorPlugin = new CueHandlerInspectorPlugin();
|
|
AddInspectorPlugin(_cueHandlerInspectorPlugin);
|
|
_attributeEditorPlugin = new AttributeEditorPlugin();
|
|
AddInspectorPlugin(_attributeEditorPlugin);
|
|
_sharedVariableSetInspectorPlugin = new SharedVariableSetInspectorPlugin();
|
|
_sharedVariableSetInspectorPlugin.SetUndoRedo(GetUndoRedo());
|
|
AddInspectorPlugin(_sharedVariableSetInspectorPlugin);
|
|
|
|
_statescriptGraphEditorDock = new StatescriptGraphEditorDock();
|
|
_statescriptGraphEditorDock.SetUndoRedo(GetUndoRedo());
|
|
AddDock(_statescriptGraphEditorDock);
|
|
|
|
AddToolMenuItem("Repair assets tags", new Callable(this, MethodName.CallAssetRepairTool));
|
|
|
|
_fileSystem = EditorInterface.Singleton.GetResourceFilesystem();
|
|
_resourcesReimportedCallable = new Callable(this, nameof(OnResourcesReimported));
|
|
|
|
_fileSystem.Connect(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable);
|
|
|
|
Validation.Enabled = true;
|
|
}
|
|
|
|
public override void _ExitTree()
|
|
{
|
|
Debug.Assert(
|
|
_tagsEditorDock is not null,
|
|
$"{nameof(_tagsEditorDock)} should have been initialized on _Ready().");
|
|
Debug.Assert(
|
|
_statescriptGraphEditorDock is not null,
|
|
$"{nameof(_statescriptGraphEditorDock)} should have been initialized on _Ready().");
|
|
|
|
if (_fileSystem?.IsConnected(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable)
|
|
== true)
|
|
{
|
|
_fileSystem.Disconnect(EditorFileSystem.SignalName.ResourcesReimported, _resourcesReimportedCallable);
|
|
}
|
|
|
|
RemoveDock(_tagsEditorDock);
|
|
_tagsEditorDock.Free();
|
|
|
|
RemoveInspectorPlugin(_tagContainerInspectorPlugin);
|
|
RemoveInspectorPlugin(_tagInspectorPlugin);
|
|
RemoveInspectorPlugin(_attributeSetInspectorPlugin);
|
|
RemoveInspectorPlugin(_cueHandlerInspectorPlugin);
|
|
RemoveInspectorPlugin(_attributeEditorPlugin);
|
|
RemoveInspectorPlugin(_sharedVariableSetInspectorPlugin);
|
|
|
|
RemoveDock(_statescriptGraphEditorDock);
|
|
_statescriptGraphEditorDock.Free();
|
|
|
|
RemoveToolMenuItem("Repair assets tags");
|
|
}
|
|
|
|
public override bool _Handles(GodotObject @object)
|
|
{
|
|
return @object is StatescriptGraph;
|
|
}
|
|
|
|
public override void _Edit(GodotObject? @object)
|
|
{
|
|
if (@object is StatescriptGraph graph && _statescriptGraphEditorDock is not null)
|
|
{
|
|
_statescriptGraphEditorDock.OpenGraph(graph);
|
|
}
|
|
}
|
|
|
|
public override void _MakeVisible(bool visible)
|
|
{
|
|
if (_statescriptGraphEditorDock is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (visible)
|
|
{
|
|
_statescriptGraphEditorDock.Open();
|
|
}
|
|
|
|
_statescriptGraphEditorDock.Visible = visible;
|
|
}
|
|
|
|
public override void _EnablePlugin()
|
|
{
|
|
base._EnablePlugin();
|
|
|
|
EnsureForgeDataExists();
|
|
|
|
var config = ProjectSettings.LoadResourcePack(AutoloadPath);
|
|
|
|
if (config)
|
|
{
|
|
GD.PrintErr("Failed to load script at res://addons/forge/core/ForgeBootstrap.cs");
|
|
return;
|
|
}
|
|
|
|
if (!ProjectSettings.HasSetting("autoload/Forge Bootstrap"))
|
|
{
|
|
ProjectSettings.SetSetting("autoload/Forge Bootstrap", AutoloadPath);
|
|
ProjectSettings.Save();
|
|
}
|
|
}
|
|
|
|
public override void _DisablePlugin()
|
|
{
|
|
if (ProjectSettings.HasSetting("autoload/Forge Bootstrap"))
|
|
{
|
|
ProjectSettings.Clear("autoload/Forge Bootstrap");
|
|
ProjectSettings.Save();
|
|
}
|
|
}
|
|
|
|
public override void _SaveExternalData()
|
|
{
|
|
_statescriptGraphEditorDock?.SaveAllOpenGraphs();
|
|
}
|
|
|
|
public override string _GetPluginName()
|
|
{
|
|
return "Forge";
|
|
}
|
|
|
|
public override void _GetWindowLayout(ConfigFile configuration)
|
|
{
|
|
if (_statescriptGraphEditorDock is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var paths = _statescriptGraphEditorDock.GetOpenResourcePaths();
|
|
|
|
if (paths.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
configuration.SetValue("Forge", "open_tabs", string.Join(";", paths));
|
|
configuration.SetValue("Forge", "active_tab", _statescriptGraphEditorDock.GetActiveTabIndex());
|
|
|
|
var varStates = _statescriptGraphEditorDock.GetVariablesPanelStates();
|
|
configuration.SetValue("Forge", "variables_states", string.Join(";", varStates));
|
|
}
|
|
|
|
public override void _SetWindowLayout(ConfigFile configuration)
|
|
{
|
|
if (_statescriptGraphEditorDock is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Variant tabsValue = configuration.GetValue("Forge", "open_tabs", string.Empty);
|
|
Variant active = configuration.GetValue("Forge", "active_tab", -1);
|
|
|
|
var tabsString = tabsValue.AsString();
|
|
if (string.IsNullOrEmpty(tabsString))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var paths = tabsString.Split(';', StringSplitOptions.RemoveEmptyEntries);
|
|
var activeIndex = active.AsInt32();
|
|
|
|
bool[]? variablesStates = null;
|
|
Variant varStatesValue = configuration.GetValue("Forge", "variables_states", string.Empty);
|
|
var varString = varStatesValue.AsString();
|
|
|
|
if (!string.IsNullOrEmpty(varString))
|
|
{
|
|
var parts = varString.Split(';');
|
|
variablesStates = new bool[parts.Length];
|
|
for (var i = 0; i < parts.Length; i++)
|
|
{
|
|
variablesStates[i] = bool.TryParse(parts[i], out var v) && v;
|
|
}
|
|
}
|
|
|
|
_statescriptGraphEditorDock.RestoreFromPaths(paths, activeIndex, variablesStates);
|
|
}
|
|
|
|
private static void EnsureForgeDataExists()
|
|
{
|
|
if (ResourceLoader.Exists(ForgeData.ForgeDataResourcePath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var forgeData = new ForgeData();
|
|
Error error = ResourceSaver.Save(forgeData, ForgeData.ForgeDataResourcePath);
|
|
|
|
if (error != Error.Ok)
|
|
{
|
|
GD.PrintErr($"Failed to create ForgeData resource: {error}");
|
|
return;
|
|
}
|
|
|
|
EditorInterface.Singleton.GetResourceFilesystem().Scan();
|
|
GD.Print("Created default ForgeData resource at ", ForgeData.ForgeDataResourcePath);
|
|
}
|
|
|
|
private static void CallAssetRepairTool()
|
|
{
|
|
AssetRepairTool.RepairAllAssetsTags();
|
|
}
|
|
|
|
private void OnResourcesReimported(string[] resources)
|
|
{
|
|
foreach (var path in resources)
|
|
{
|
|
if (!ResourceLoader.Exists(path))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var fileType = EditorInterface.Singleton.GetResourceFilesystem().GetFileType(path);
|
|
if (fileType != "StatescriptGraph" && fileType != "Resource")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Resource resource = ResourceLoader.Load(path);
|
|
if (resource is StatescriptGraph graph)
|
|
{
|
|
_statescriptGraphEditorDock?.OpenGraph(graph);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|