diff --git a/Scripts/Editor/Singleton/LanLib.Singleton.Editor.asmdef b/Scripts/Editor/Singleton/LanLib.Singleton.Editor.asmdef
index 7d433df..77e4a49 100644
--- a/Scripts/Editor/Singleton/LanLib.Singleton.Editor.asmdef
+++ b/Scripts/Editor/Singleton/LanLib.Singleton.Editor.asmdef
@@ -1,6 +1,6 @@
{
"name": "LanLib.Singleton.Editor",
- "rootNamespace": "",
+ "rootNamespace": "LanLib.Singleton.EditorUtilities",
"references": [
"LanLib.Singleton"
],
diff --git a/Scripts/Editor/UpdateManager.meta b/Scripts/Editor/UpdateManager.meta
new file mode 100644
index 0000000..aa37ed8
--- /dev/null
+++ b/Scripts/Editor/UpdateManager.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: ddd256eeb3444789b4c8a242eb4ccb95
+timeCreated: 1706154518
\ No newline at end of file
diff --git a/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs b/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs
new file mode 100644
index 0000000..6dcd843
--- /dev/null
+++ b/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using LanLib.UpdateManager.Jobs;
+using UnityEditor;
+using UnityEngine;
+
+namespace LanLib.UpdateManager.EditorUtilities
+{
+ [CustomEditor(typeof(AJobBehaviour<>), true)]
+ [CanEditMultipleObjects]
+ public class AJobBehaviourEditor : Editor
+ {
+ private GUIStyle TopAnchoredLabel => _topAnchoredLabel != null
+ ? _topAnchoredLabel
+ : (_topAnchoredLabel = new GUIStyle(EditorStyles.label)
+ {
+ alignment = TextAnchor.UpperLeft
+ });
+
+ private GUIStyle _topAnchoredLabel;
+
+ public override bool HasPreviewGUI()
+ {
+ return Application.isPlaying
+ && !serializedObject.isEditingMultipleObjects
+ && ((MonoBehaviour)target).isActiveAndEnabled;
+ }
+
+ public override GUIContent GetPreviewTitle()
+ {
+ return new GUIContent($"{target.GetType().Name} Job Data");
+ }
+
+ public override void OnInteractivePreviewGUI(Rect r, GUIStyle background)
+ {
+ PropertyInfo prop = target.GetType().GetProperty("JobData");
+ GUI.Label(r, JsonUtility.ToJson(prop.GetValue(target), true), TopAnchoredLabel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs.meta b/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs.meta
new file mode 100644
index 0000000..f7e9ef0
--- /dev/null
+++ b/Scripts/Editor/UpdateManager/AJobBehaviourEditor.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: e128a8c16c784b51aab1dddfb8b8329a
+timeCreated: 1706154581
\ No newline at end of file
diff --git a/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef b/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef
new file mode 100644
index 0000000..c6886ae
--- /dev/null
+++ b/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef
@@ -0,0 +1,18 @@
+{
+ "name": "LanLib.UpdateManager.Editor",
+ "rootNamespace": "LanLib.UpdateManager.EditorUtilities",
+ "references": [
+ "LanLib.UpdateManager"
+ ],
+ "includePlatforms": [
+ "Editor"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": false,
+ "precompiledReferences": [],
+ "autoReferenced": true,
+ "defineConstraints": [],
+ "versionDefines": [],
+ "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef.meta b/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef.meta
new file mode 100644
index 0000000..52caf16
--- /dev/null
+++ b/Scripts/Editor/UpdateManager/LanLib.UpdateManager.Editor.asmdef.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 83d7ca5b7a6e4b21980fc187b907d443
+timeCreated: 1706154533
\ No newline at end of file
diff --git a/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs b/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs
new file mode 100644
index 0000000..40530ae
--- /dev/null
+++ b/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs
@@ -0,0 +1,91 @@
+using System;
+using LanLib.UpdateManager.Jobs.Internal;
+using UnityEngine;
+
+namespace LanLib.UpdateManager.Jobs
+{
+ ///
+ /// abstract class with automatic registration in .
+ ///
+ ///
+ /// Instances will register themselves for job scheduling in the OnEnable message and unregister in the OnDisable message.
+ ///
+ ///
+ public abstract class AJobBehaviour : MonoBehaviour, ITransformJobUpdatable
+ where TData : struct, IUpdateTransformJob
+ {
+ ///
+ /// Whether job data should be synchronized every frame.
+ /// By default, returns false.
+ ///
+ ///
+ /// Override in subclasses implementing and return true
+ /// to automatically register objects for job data synchronization every frame.
+ ///
+ public virtual bool SynchronizeJobDataEveryFrame => false;
+
+ protected virtual void OnEnable()
+ {
+ this.RegisterInManager(SynchronizeJobDataEveryFrame);
+ }
+
+ protected virtual void OnDisable()
+ {
+ this.UnregisterInManager();
+ }
+
+ public Transform Transform => transform;
+
+ ///
+ /// Returns the job data for the first job run.
+ ///
+ ///
+ /// Override this in child classes to use data other than in the first scheduled job run.
+ ///
+ ///
+ public virtual TData InitialJobData => default;
+
+ ///
+ /// Shortcut for UpdateTransformJobManager<TData>.Instance.GetData(this).
+ ///
+ ///
+ public TData JobData => this.GetJobData();
+
+#if UNITY_EDITOR
+ ///
+ /// Whether job data should be synchronized in the OnValidate message.
+ /// By default, returns true.
+ ///
+ ///
+ /// Override in subclasses implementing and return false
+ /// to avoid automatic job data synchronization during OnValidate.
+ ///
+ protected virtual bool SynchronizeJobDataOnValidate => true;
+
+ ///
+ /// Synchronizes job data on Play mode if returns true.
+ ///
+ protected virtual void OnValidate()
+ {
+ if (Application.isPlaying && SynchronizeJobDataOnValidate)
+ {
+ this.SynchronizeJobDataOnce();
+ }
+ }
+#endif
+ }
+
+ ///
+ /// Alias for .
+ ///
+ ///
+ /// Deprecated: use instead and implement
+ /// in job definition to compile jobs with Burst.
+ ///
+ [Obsolete("Use AJobBehaviour<> and implement IBurstUpdateTransformJob<> in job definition instead.")]
+ public abstract class AJobBehaviour : AJobBehaviour
+ where TData : struct, IUpdateTransformJob
+ where TJob : struct, IInternalUpdateTransformJob
+ {
+ }
+}
\ No newline at end of file
diff --git a/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs.meta b/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs.meta
new file mode 100644
index 0000000..ef2c24e
--- /dev/null
+++ b/Scripts/Runtime/UpdateManager/Jobs/AJobBehaviour.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 72e7d96662e042d29ae18768a2ea8600
+timeCreated: 1706154817
\ No newline at end of file