From 9b3379d060546a9f3891586fb0bf73339b3d1366 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 29 Mar 2023 23:59:26 +0800 Subject: [PATCH] add templates --- src/Templates.meta | 8 + src/Templates/Component.cs.txt | 10 ++ src/Templates/Component.cs.txt.meta | 7 + src/Templates/ComponentExtended.cs.txt | 20 +++ src/Templates/ComponentExtended.cs.txt.meta | 7 + src/Templates/Runner.cs.txt | 20 +++ src/Templates/Runner.cs.txt.meta | 7 + src/Templates/RunnerExtended.cs.txt | 48 ++++++ src/Templates/RunnerExtended.cs.txt.meta | 7 + src/Templates/Startup.cs.txt | 66 ++++++++ src/Templates/Startup.cs.txt.meta | 7 + src/Templates/System.cs.txt | 18 +++ src/Templates/System.cs.txt.meta | 7 + src/Templates/SystemExtended.cs.txt | 55 +++++++ src/Templates/SystemExtended.cs.txt.meta | 7 + src/Templates/TemplateGenerator.cs | 157 ++++++++++++++++++++ src/Templates/TemplateGenerator.cs.meta | 11 ++ 17 files changed, 462 insertions(+) create mode 100644 src/Templates.meta create mode 100644 src/Templates/Component.cs.txt create mode 100644 src/Templates/Component.cs.txt.meta create mode 100644 src/Templates/ComponentExtended.cs.txt create mode 100644 src/Templates/ComponentExtended.cs.txt.meta create mode 100644 src/Templates/Runner.cs.txt create mode 100644 src/Templates/Runner.cs.txt.meta create mode 100644 src/Templates/RunnerExtended.cs.txt create mode 100644 src/Templates/RunnerExtended.cs.txt.meta create mode 100644 src/Templates/Startup.cs.txt create mode 100644 src/Templates/Startup.cs.txt.meta create mode 100644 src/Templates/System.cs.txt create mode 100644 src/Templates/System.cs.txt.meta create mode 100644 src/Templates/SystemExtended.cs.txt create mode 100644 src/Templates/SystemExtended.cs.txt.meta create mode 100644 src/Templates/TemplateGenerator.cs create mode 100644 src/Templates/TemplateGenerator.cs.meta diff --git a/src/Templates.meta b/src/Templates.meta new file mode 100644 index 0000000..3a33ef8 --- /dev/null +++ b/src/Templates.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7675bea928846c54d9eaefb0905778b9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/Component.cs.txt b/src/Templates/Component.cs.txt new file mode 100644 index 0000000..4c620c1 --- /dev/null +++ b/src/Templates/Component.cs.txt @@ -0,0 +1,10 @@ +using UnityEngine; +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + public struct #SCRIPTNAME# + { + // add your data here + } +} diff --git a/src/Templates/Component.cs.txt.meta b/src/Templates/Component.cs.txt.meta new file mode 100644 index 0000000..5776180 --- /dev/null +++ b/src/Templates/Component.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d8dcd63282111b24a94372328500c37a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/ComponentExtended.cs.txt b/src/Templates/ComponentExtended.cs.txt new file mode 100644 index 0000000..ef17f2a --- /dev/null +++ b/src/Templates/ComponentExtended.cs.txt @@ -0,0 +1,20 @@ +using UnityEngine; +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + // setting the color of the visualization in the debug window + //[DebugHide] + [DebugColor(DebugColor.Red)] + public struct #SCRIPTNAME# : IEcsComponentReset<#SCRIPTNAME#> + { + // add your data here + public float value; + + public void Reset(ref #SCRIPTNAME# component) + { + // setting custom default values + value = 5f; + } + } +} diff --git a/src/Templates/ComponentExtended.cs.txt.meta b/src/Templates/ComponentExtended.cs.txt.meta new file mode 100644 index 0000000..18a5ee9 --- /dev/null +++ b/src/Templates/ComponentExtended.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3dd75a8f9967d9440bbe2dcc30168b2f +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/Runner.cs.txt b/src/Templates/Runner.cs.txt new file mode 100644 index 0000000..f59c162 --- /dev/null +++ b/src/Templates/Runner.cs.txt @@ -0,0 +1,20 @@ +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + public interface I#SCRIPTNAME# : IEcsSystem + { + public void Do(); + } + + public class #SCRIPTNAME#Runner : EcsRunner, I#SCRIPTNAME# + { + public void Do() + { + foreach (var target in targets) + { + target.Do(); + } + } + } +} diff --git a/src/Templates/Runner.cs.txt.meta b/src/Templates/Runner.cs.txt.meta new file mode 100644 index 0000000..dd937ef --- /dev/null +++ b/src/Templates/Runner.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 67fb4cee9fff4bc48a1a6009a762959c +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/RunnerExtended.cs.txt b/src/Templates/RunnerExtended.cs.txt new file mode 100644 index 0000000..a662392 --- /dev/null +++ b/src/Templates/RunnerExtended.cs.txt @@ -0,0 +1,48 @@ +using UnityEngine; +using DCFApixels.DragonECS; +#if DEBUG +using Unity.Profiling; +#endif + +namespace #NAMESPACE# +{ + public interface I#SCRIPTNAME# : IEcsSystem + { + public void Do(); + } + + // setting the color of the visualization in the debug window + //[DebugHide] + [DebugColor(DebugColor.Red)] + public class #SCRIPTNAME#Runner : EcsRunner, I#SCRIPTNAME# + { + private ProfilerMarker[] _profilerMarkers; + + public void Do() + { + for (int i = 0; i < targets.Length; i++) + { +#if DEBUG + _profilerMarkers[i].Begin(); +#endif + targets[i].Do(); +#if DEBUG + _profilerMarkers[i].End(); +#endif + } + } + +#if DEBUG + // will be called after changing "targets" + protected override void OnSetup() + { + // create an array of profiler markers for each system in "targets" + _profilerMarkers = new ProfilerMarker[targets.Length]; + for (int i = 0; i < targets.Length; i++) + { + _profilerMarkers[i] = new ProfilerMarker(ProfilerCategory.Scripts, $"EcsRunner.{targets[i].GetType().Name}.{nameof(Do)}"); + } + } +#endif + } +} diff --git a/src/Templates/RunnerExtended.cs.txt.meta b/src/Templates/RunnerExtended.cs.txt.meta new file mode 100644 index 0000000..b6d30aa --- /dev/null +++ b/src/Templates/RunnerExtended.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3c196b8082fad1f4ea6038a881414ce4 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/Startup.cs.txt b/src/Templates/Startup.cs.txt new file mode 100644 index 0000000..8edb9c7 --- /dev/null +++ b/src/Templates/Startup.cs.txt @@ -0,0 +1,66 @@ +using UnityEngine; +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + sealed class #SCRIPTNAME# : MonoBehaviour + { + private EcsWorld _world; + private EcsSystems _systems; + + private void Start() + { + // is needed to integrate the internal debugging tool with the unity environment + UnityDebugService.Init(); + + _world = new EcsWorld(); + _systems = EcsSystems.New() + // register your systems here, for example: + // .Add (new TestSystem1 ()) + // .Add (new TestSystem2 ()) + + // inject worlds here, for example: + .Inject(_world) + //.Inject(new EcsWorld()) + + // with Inject you can also inject other data, for example: + //.Inject(new SharedData()) +#if UNITY_EDITOR + // add debug systems for this EcsSystems here + .Add(new SystemsDebugSystem()) +#endif + .BuildAndInit(); + } + + private void Update() + { + _systems?.Run(); + } + + private void LateUpdate() + { + _systems?.LateRun(); + } + + private void FixedUpdate() + { + _systems?.FixedRun(); + } + + private void OnDestroy() + { + // don't forget to clear data + if (_systems != null) + { + _systems.Destroy(); + _systems = null; + } + + if (_world != null) + { + _world.Destroy(); + _world = null; + } + } + } +} \ No newline at end of file diff --git a/src/Templates/Startup.cs.txt.meta b/src/Templates/Startup.cs.txt.meta new file mode 100644 index 0000000..29c847c --- /dev/null +++ b/src/Templates/Startup.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5af8205794231544eafe9b43c30c5d83 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/System.cs.txt b/src/Templates/System.cs.txt new file mode 100644 index 0000000..fa05e0d --- /dev/null +++ b/src/Templates/System.cs.txt @@ -0,0 +1,18 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + public class #SCRIPTNAME# : IEcsRunSystem, IEcsInject> + { + private EcsWorld _world; + public void Inject(EcsWorld obj) => _world = obj; + + public void Run(EcsSystems systems) + { + // will be called on each EcsSystems.Run() call + } + } +} diff --git a/src/Templates/System.cs.txt.meta b/src/Templates/System.cs.txt.meta new file mode 100644 index 0000000..110bc68 --- /dev/null +++ b/src/Templates/System.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3bbff7d1071aadf4f93df0a0fb6078e9 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/SystemExtended.cs.txt b/src/Templates/SystemExtended.cs.txt new file mode 100644 index 0000000..a7a2eb7 --- /dev/null +++ b/src/Templates/SystemExtended.cs.txt @@ -0,0 +1,55 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using DCFApixels.DragonECS; + +namespace #NAMESPACE# +{ + // setting the color of the visualization in the debug window + //[DebugHide] + [DebugColor(DebugColor.Red)] + public class #SCRIPTNAME# : + IEcsPreInitSystem, + IEcsInitSystem, + IEcsRunSystem, + IEcsLateRunSystem, + IEcsFixedRunSystem, + IEcsDestroySystem, + IEcsInject> + { + private EcsWorld _world; + public void Inject(EcsWorld obj) => _world = obj; + + public void PreInit(EcsSystems systems) + { + // will be called once during EcsSystems.Init() call and before Init(EcsSystems systems). + } + + public void Init(EcsSystems systems) + { + // will be called once during EcsSystems.Init() call and after PreInit(EcsSystems systems). + } + + public void Run(EcsSystems systems) + { + // will be called on each EcsSystems.Run() call + } + + public void LateRun(EcsSystems systems) + { + // will be called on each EcsSystems.LateRun() call + } + + public void FixedRun(EcsSystems systems) + { + // will be called on each EcsSystems.FixedRun() call + } + + public void Destroy(EcsSystems systems) + { + // will be called once during EcsSystems.Destroy() call + } + + //Use Runners to implement additional messages + } +} diff --git a/src/Templates/SystemExtended.cs.txt.meta b/src/Templates/SystemExtended.cs.txt.meta new file mode 100644 index 0000000..3e800cd --- /dev/null +++ b/src/Templates/SystemExtended.cs.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fab30d6906127c040a3cbb3bd17e05c6 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Templates/TemplateGenerator.cs b/src/Templates/TemplateGenerator.cs new file mode 100644 index 0000000..d1f7a0c --- /dev/null +++ b/src/Templates/TemplateGenerator.cs @@ -0,0 +1,157 @@ +#if UNITY_EDITOR +using System; +using System.IO; +using System.Text; +using UnityEditor; +using UnityEditor.ProjectWindowCallback; +using UnityEngine; + +namespace DCFApixels.DragonECS.Editors +{ + public sealed class TemplateGenerator + { + private const int MENU_ITEM_PRIORITY = -198; + + private const string TITLE = "DragonECS Template Generator"; + + private const string MENU_ITEM_PATH = "Assets/Create/DragonECS/"; + + private const string NAMESPACE_TAG = "#NAMESPACE#"; + private const string SCRIPTANAME_TAG = "#SCRIPTNAME#"; + + #region Properties + private static Texture2D ScriptIcon => EditorGUIUtility.IconContent("cs Script Icon").image as Texture2D; + private static string GetCurrentFilePath([System.Runtime.CompilerServices.CallerFilePath] string fileName = null) + { + return Path.GetFullPath(Path.Combine(fileName, "../")); + } + private static string TemplatesPath => GetCurrentFilePath(); + #endregion + + #region GenerateMethods + [MenuItem(MENU_ITEM_PATH + "[Template]Startup", false, MENU_ITEM_PRIORITY)] + public static void CreateSturtupScript() => CreateScript("Startup"); + + [MenuItem(MENU_ITEM_PATH + "[Template]System", false, MENU_ITEM_PRIORITY)] + public static void CreateSystemSimpleScript() => CreateScript("System"); + + [MenuItem(MENU_ITEM_PATH + "[Template]Component", false, MENU_ITEM_PRIORITY)] + public static void CreateComponentSimpleScript() => CreateScript("Component"); + + [MenuItem(MENU_ITEM_PATH + "[Template]Runner", false, MENU_ITEM_PRIORITY)] + public static void CreateRunnerSimpleScript() => CreateScript("Runner"); + + [MenuItem(MENU_ITEM_PATH + "[Template]System Extended", false, MENU_ITEM_PRIORITY)] + public static void CreateSystemScript() => CreateScript("SystemExtended"); + + [MenuItem(MENU_ITEM_PATH + "[Template]Component Extended", false, MENU_ITEM_PRIORITY)] + public static void CreateComponentScript() => CreateScript("ComponentExtended"); + + [MenuItem(MENU_ITEM_PATH + "[Template]Runner Extended", false, MENU_ITEM_PRIORITY)] + public static void CreateRunnerScript() => CreateScript("RunnerExtended"); + + + private static void CreateScript(string templateName) + { + CreateAndRenameAsset($"{GetAssetPath()}/Ecs{templateName}.cs", name => GenerateEndWrtieScript($"{templateName}.cs.txt", name)); + } + #endregion + + private static void GenerateEndWrtieScript(string templateFileName, string generatedFileName) + { + string script; + try + { + script = File.ReadAllText(Path.Combine(TemplatesPath, templateFileName)); + } + catch (Exception exception) + { + EditorUtility.DisplayDialog(TITLE, $"[ERROR] Template {templateFileName} cannot be read.\r\n{exception.Message}", "Close"); + return; + } + + var ns = EditorSettings.projectGenerationRootNamespace.Trim(); + if (string.IsNullOrEmpty(ns)) + { + ns = "Client"; + } + + script = script.Replace(NAMESPACE_TAG, ns); + script = script.Replace(SCRIPTANAME_TAG, NormalizeClassName(Path.GetFileNameWithoutExtension(generatedFileName))); + + try + { + File.WriteAllText(AssetDatabase.GenerateUniqueAssetPath(generatedFileName), script); + } + catch (Exception exception) + { + EditorUtility.DisplayDialog(TITLE, $"[ERROR] The result was not written to the file.\r\n{exception.Message}", "Close"); + return; + } + if (EditorPrefs.GetBool("kAutoRefresh")) AssetDatabase.Refresh(); + } + + private static string NormalizeClassName(string className) + { + StringBuilder result = new StringBuilder(); + bool isUpper = true; + foreach (var c in className) + { + if (char.IsLetterOrDigit(c)) + { + result.Append(isUpper ? char.ToUpperInvariant(c) : c); + isUpper = false; + } + else + { + isUpper = true; + } + } + return result.ToString(); + } + + private static string GetAssetPath() + { + var path = AssetDatabase.GetAssetPath(Selection.activeObject); + if (!string.IsNullOrEmpty(path) && AssetDatabase.Contains(Selection.activeObject)) + { + if (!AssetDatabase.IsValidFolder(path)) + { + path = Path.GetDirectoryName(path); + } + } + else + { + path = "Assets"; + } + return path; + } + + private static void CreateAndRenameAsset(string pathName, Action onSuccess) + { + var action = ScriptableObject.CreateInstance(); + action.Callback = onSuccess; + ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, action, pathName, ScriptIcon, null); + } + + #region Utils + private sealed class CustomEndNameAction : EndNameEditAction + { + [NonSerialized] + public Action Callback; + + public override void Action(int instanceId, string pathName, string resourceFile) + { + if (string.IsNullOrEmpty(pathName)) + { + EditorUtility.DisplayDialog(TITLE, "Invalid filename", "Close"); + return; + } + Callback?.Invoke(pathName); + } + } + #endregion + } +} +#endif + diff --git a/src/Templates/TemplateGenerator.cs.meta b/src/Templates/TemplateGenerator.cs.meta new file mode 100644 index 0000000..7ddaa6a --- /dev/null +++ b/src/Templates/TemplateGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 98b537892f3da62409c7f6322323af10 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: