From 8f3ed6ba952b1dd1f457b305d82c8165a324bc48 Mon Sep 17 00:00:00 2001 From: Sophia Pearson Date: Tue, 24 May 2022 14:59:58 +0200 Subject: addons: implement automatic class exporter --- addons/ClassExporter/Plugin.cs | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 addons/ClassExporter/Plugin.cs (limited to 'addons/ClassExporter/Plugin.cs') diff --git a/addons/ClassExporter/Plugin.cs b/addons/ClassExporter/Plugin.cs new file mode 100644 index 0000000..72df4bf --- /dev/null +++ b/addons/ClassExporter/Plugin.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Godot; + +#if TOOLS + +namespace Texty.addons.ClassExporter +{ + [Tool] + public class Plugin : EditorPlugin + { + private const string LoadTypesMenuItem = "Load types"; + private const string ReloadTypesMenuItem = "Reload types"; + private readonly List _types = new List(); + + public override void _EnterTree() + { + Connect("resource_saved", this, nameof(OnResourceSaved)); + AddToolMenuItem(LoadTypesMenuItem, this, nameof(OnReloadTypes), false); + AddToolMenuItem(ReloadTypesMenuItem, this, nameof(OnReloadTypes), true); + RegisterTypes(); + } + + public override void _ExitTree() + { + DeRegisterTypes(); + RemoveToolMenuItem(LoadTypesMenuItem); + RemoveToolMenuItem(ReloadTypesMenuItem); + Disconnect("resource_saved", this, nameof(OnResourceSaved)); + } + + // ReSharper disable once UnusedParameter.Local + private void OnResourceSaved(Resource resource) + { + RegisterTypes(); + } + + private void OnReloadTypes(bool reload) + { + if (reload) DeRegisterTypes(); + RegisterTypes(); + } + + private void RegisterTypes() + { + var assembly = Assembly.GetExecutingAssembly(); + var newTypes = from type in assembly.GetTypes() + where type.IsSubclassOf(typeof(Resource)) || type.IsSubclassOf(typeof(Node)) + where !type.IsSubclassOf(typeof(EditorPlugin)) + where !_types.Contains(type) + select new RegistrableType(type); + + foreach (var type in newTypes) + { + GD.Print($"Exporting class {type.Name}: {type.Script.ResourcePath}"); + AddCustomType(type.Name, type.Base, type.Script, null); + _types.Add(type.Type); + } + } + + private void DeRegisterTypes() + { + _types.ForEach(type => RemoveCustomType(type.Name)); + _types.Clear(); + } + + private readonly struct RegistrableType + { + public RegistrableType(Type type) + { + Type = type; + } + + public readonly Type Type; + + public CSharpScript Script + { + get + { + var components = (Type.FullName ?? "").Split('.'); + var path = string.Join("/", components.Skip(1)) + ".cs"; + return ResourceLoader.Load(path); + } + } + + public string Name => Type.Name; + public string Base => Type.BaseType?.Name ?? ""; + } + } +} + +#endif \ No newline at end of file -- cgit v1.2.3