diff --git a/Assets/TEngine/Runtime/ECS/ArrayPool.cs b/Assets/TEngine/Runtime/ECS/ArrayPool.cs index c03086c1..ec955c1b 100644 --- a/Assets/TEngine/Runtime/ECS/ArrayPool.cs +++ b/Assets/TEngine/Runtime/ECS/ArrayPool.cs @@ -11,11 +11,11 @@ namespace TEngine internal class HashSetDebugView where T : IIndex { - private readonly ArrayPool m_Set; + private readonly ArrayPool _set; public HashSetDebugView(ArrayPool set) { - m_Set = set ?? throw new ArgumentNullException(nameof(set)); + _set = set ?? throw new ArgumentNullException(nameof(set)); } [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] @@ -23,7 +23,7 @@ namespace TEngine { get { - return m_Set.ToArray(); + return _set.ToArray(); } } } @@ -34,8 +34,8 @@ namespace TEngine { internal T[] Items = new T[256]; internal bool[] Buckets = new bool[256]; - private int m_Index; - private int count; + private int _index; + private int _count; public T this[int index] { @@ -53,7 +53,7 @@ namespace TEngine { get { - return count; + return _count; } } @@ -93,11 +93,11 @@ namespace TEngine } } - Items[m_Index] = item; - Buckets[m_Index] = true; - item.Index = m_Index; - m_Index++; - if (m_Index >= Items.Length) + Items[_index] = item; + Buckets[_index] = true; + item.Index = _index; + _index++; + if (_index >= Items.Length) { T[] newItems = new T[Items.Length * 2]; bool[] newBuckets = new bool[Items.Length * 2]; @@ -106,7 +106,7 @@ namespace TEngine Items = newItems; Buckets = newBuckets; } - count = m_Index; + _count = _index; } } } diff --git a/Assets/TEngine/Runtime/ECS/Attribute.meta b/Assets/TEngine/Runtime/ECS/Attribute.meta new file mode 100644 index 00000000..96db231d --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Attribute.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 49e862743b5e66f49a708ca914634041 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs b/Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs new file mode 100644 index 00000000..89924498 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace TEngine +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class BaseAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/IFixedUpdate.cs.meta b/Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs.meta similarity index 83% rename from Assets/TEngine/Runtime/ECS/IFixedUpdate.cs.meta rename to Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs.meta index 448ce4a6..d4314927 100644 --- a/Assets/TEngine/Runtime/ECS/IFixedUpdate.cs.meta +++ b/Assets/TEngine/Runtime/ECS/Attribute/BaseAttribute.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7fb8a7b6d364a024e8a49a0a731de201 +guid: 951727040b1247947a8009f67e241b60 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs b/Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs new file mode 100644 index 00000000..de280567 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace TEngine +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public class ObjectSystemAttribute : BaseAttribute + { + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/ECSActor.cs.meta b/Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs.meta similarity index 83% rename from Assets/TEngine/Runtime/ECS/ECSActor.cs.meta rename to Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs.meta index f0150236..5b1543ec 100644 --- a/Assets/TEngine/Runtime/ECS/ECSActor.cs.meta +++ b/Assets/TEngine/Runtime/ECS/Attribute/ObjectSystemAttribute.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 34a977c48d3bdb144b7c923a702164b0 +guid: fc4379fdd792a8f40a239d9222598c93 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/TEngine/Runtime/ECS/Demo/ECSDemoApp.cs b/Assets/TEngine/Runtime/ECS/Demo/ECSDemoApp.cs index dddbdea3..cf28533c 100644 --- a/Assets/TEngine/Runtime/ECS/Demo/ECSDemoApp.cs +++ b/Assets/TEngine/Runtime/ECS/Demo/ECSDemoApp.cs @@ -7,14 +7,23 @@ public class EcsDemoApp : MonoBehaviour void Start() { - var entity = EcsSystem.Instance.Create(); - EcsActor actor = entity.AddComponent(); - actor.Name = typeof(EcsActor).ToString(); + var entity = Entity.Create(); + EcsGameObject actor = entity.AddComponent(); + actor.Name = typeof(EcsGameObject).ToString(); actor.gameObject = Instantiate(@object); actor.transform = actor.gameObject.GetComponent(); entity.AddComponent(); - + entity.CheckDebugInfo(actor.gameObject); Debug.Log(entity.ToString()); + + var entity2 = Entity.Create(); + EcsGameObject actor2 = entity2.AddComponent(); + actor2.Name = typeof(EcsGameObject).ToString(); + actor2.gameObject = Instantiate(@object); + actor2.transform = actor2.gameObject.GetComponent(); + entity2.AddComponent(); + entity2.CheckDebugInfo(actor2.gameObject); + Debug.Log(entity2.ToString()); } void Update() diff --git a/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity b/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity new file mode 100644 index 00000000..e16c0fc9 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity @@ -0,0 +1,342 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &38966529 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 38966531} + - component: {fileID: 38966530} + m_Layer: 0 + m_Name: EcsSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &38966530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 38966529} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fb5cf3287e9bf3949820b50049e4bd8c, type: 3} + m_Name: + m_EditorClassIdentifier: + object: {fileID: 3159855139361589346, guid: 5417ada688c10cf4cb2a929e4f5a5b84, type: 3} +--- !u!4 &38966531 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 38966529} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &152798934 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 152798936} + - component: {fileID: 152798935} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &152798935 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 152798934} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &152798936 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 152798934} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &770039736 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 770039739} + - component: {fileID: 770039738} + - component: {fileID: 770039737} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &770039737 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770039736} + m_Enabled: 1 +--- !u!20 &770039738 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770039736} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &770039739 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770039736} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity.meta b/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity.meta new file mode 100644 index 00000000..4af3e96f --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Demo/EcsDemo.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 41f405cfa9201e24380d1eb0d7702562 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab b/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab new file mode 100644 index 00000000..3a2a3c82 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab @@ -0,0 +1,32 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3159855139361589346 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8488366394885562912} + m_Layer: 0 + m_Name: EcsUnit + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8488366394885562912 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3159855139361589346} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab.meta b/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab.meta new file mode 100644 index 00000000..1fe35860 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/Demo/EcsUnit.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5417ada688c10cf4cb2a929e4f5a5b84 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/ECSComponent.cs b/Assets/TEngine/Runtime/ECS/ECSComponent.cs index e2eaa2b7..4f522518 100644 --- a/Assets/TEngine/Runtime/ECS/ECSComponent.cs +++ b/Assets/TEngine/Runtime/ECS/ECSComponent.cs @@ -4,11 +4,8 @@ /// Ecs构架可以将此组件从Entity上移除这个组件并丢入对象池,给其他此刻需要此组件的Entity使用, /// 因此可以节省大量的内存反复创建和释放, 这也是Ecs的特性可以大量重复使用组件 /// - public class EcsComponent:EcsObject + public class EcsComponent : EcsObject { -#pragma warning disable IDE1006 public Entity Entity { get; set; } -#pragma warning restore IDE1006 } -} - +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/ECSObject.cs b/Assets/TEngine/Runtime/ECS/ECSObject.cs index e871b832..7460a8ce 100644 --- a/Assets/TEngine/Runtime/ECS/ECSObject.cs +++ b/Assets/TEngine/Runtime/ECS/ECSObject.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.Serialization; namespace TEngine { @@ -8,13 +9,42 @@ namespace TEngine /// public class EcsObject { - internal int HashCode; + public int InstanceId + { + get; + protected set; + } + + internal int HashCode + { + get; + private set; + } internal EcsSystem System; + + [IgnoreDataMember] + public bool IsDisposed => this.InstanceId == 0; + public EcsObject() { HashCode = GetType().GetHashCode(); + InstanceId = EcsSystem.Instance.CurInstanceId; + EcsSystem.Instance.CurInstanceId++; + } + + public virtual void Dispose() + { + if (InstanceId != 0) + { + EcsSystem.Instance.EcsObjects.Remove(InstanceId); + } + else + { + throw new Exception($"{this.ToString()} Instance is 0 but still Dispose"); + } + InstanceId = 0; } public virtual void Awake() { } @@ -24,7 +54,7 @@ namespace TEngine /// /// Remove The EcsEntity or Component And Throw the EcsObject to ArrayPool When AddComponent Or Create Can Use Again /// - /// + /// EcsEntity/Component/System /// 此对象是否可以复用,复用会将对象丢入System对象池中 等待再次使用,如果是Entity对象,并且不复用的话,则把Entity所使用的组件也不复用 public static void Destroy(EcsObject ecsObject, bool reuse = true) { diff --git a/Assets/TEngine/Runtime/ECS/ECSSystem.cs b/Assets/TEngine/Runtime/ECS/ECSSystem.cs index 50b33fb8..c9940d8d 100644 --- a/Assets/TEngine/Runtime/ECS/ECSSystem.cs +++ b/Assets/TEngine/Runtime/ECS/ECSSystem.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; namespace TEngine @@ -32,6 +33,9 @@ namespace TEngine /// internal readonly Dictionary> ObjectPool = new Dictionary>(); internal readonly ArrayPool Entities = new ArrayPool(); + internal readonly Dictionary EcsObjects = new Dictionary(); + internal readonly Dictionary UpdateSystems = new Dictionary(); + internal int CurInstanceId = 1000; public void AddEntity(Entity entity) { @@ -59,13 +63,14 @@ namespace TEngine stack = new Stack(); ObjectPool.Add(type, stack); Instantiate: T ecsObject = new T(); + EcsObjects.Add(ecsObject.InstanceId,ecsObject); return ecsObject; } public void Push(EcsObject ecsObject) { int type = ecsObject.HashCode; - + ecsObject.Dispose(); if (ObjectPool.TryGetValue(type, out Stack stack)) { stack.Push(ecsObject); @@ -94,24 +99,6 @@ namespace TEngine /// /// 线程池是否并行 public void Update(bool worker = false) - { - Run(worker); - } - - /// - /// 更新Ecs物理系统 - /// - /// 线程池是否并行 - public void FixedUpdate(bool worker = false) - { - RunFixed(worker); - } - - /// - /// 运行Ecs系统 - /// - /// 线程池是否并行 - public void Run(bool worker = false) { int count = Entities.Count; if (!worker) @@ -148,7 +135,11 @@ namespace TEngine } } - public void RunFixed(bool worker = false) + /// + /// 更新Ecs物理系统 + /// + /// 线程池是否并行 + public void FixedUpdate(bool worker = false) { int count = Entities.Count; if (!worker) @@ -237,6 +228,6 @@ namespace TEngine return elements.ToArray(); } #endregion - } -} + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/ECSActor.cs b/Assets/TEngine/Runtime/ECS/EcsGameObject.cs similarity index 75% rename from Assets/TEngine/Runtime/ECS/ECSActor.cs rename to Assets/TEngine/Runtime/ECS/EcsGameObject.cs index 85eb357a..c76efd0b 100644 --- a/Assets/TEngine/Runtime/ECS/ECSActor.cs +++ b/Assets/TEngine/Runtime/ECS/EcsGameObject.cs @@ -3,11 +3,10 @@ /// /// Ecs Actor /// - public class EcsActor : EcsComponent + public class EcsGameObject : EcsComponent { public string Name; public UnityEngine.GameObject gameObject; public UnityEngine.Transform transform; - public uint ActorID; } } \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/HotfixComponent.cs.meta b/Assets/TEngine/Runtime/ECS/EcsGameObject.cs.meta similarity index 83% rename from Assets/TEngine/Runtime/ECS/HotfixComponent.cs.meta rename to Assets/TEngine/Runtime/ECS/EcsGameObject.cs.meta index 0017d198..5189b3eb 100644 --- a/Assets/TEngine/Runtime/ECS/HotfixComponent.cs.meta +++ b/Assets/TEngine/Runtime/ECS/EcsGameObject.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c0ac8b7fabe2bae499a568608191eb57 +guid: 2e71316dca3cb664d964935745d3b851 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/TEngine/Runtime/ECS/Entity.cs b/Assets/TEngine/Runtime/ECS/Entity.cs index 66675915..eac8e801 100644 --- a/Assets/TEngine/Runtime/ECS/Entity.cs +++ b/Assets/TEngine/Runtime/ECS/Entity.cs @@ -12,11 +12,11 @@ namespace TEngine IsFromPool = 1, IsRegister = 1 << 1, IsComponent = 1 << 2, - IsCreated = 1 << 3, - IsNew = 1 << 4, + IsUsing = 1 << 3, + IsDispose = 1 << 4, } - public class Entity : EcsObject, IIndex + public partial class Entity : EcsObject, IIndex { [IgnoreDataMember] private EntityStatus status = EntityStatus.None; @@ -39,7 +39,6 @@ namespace TEngine } } - #endregion [SerializeField] @@ -78,176 +77,6 @@ namespace TEngine } } - public void RmvComponent() where T : EcsComponent, new() - { - for (int i = 0; i < Components.Count; i++) - { - if (Components[i] is T component) - { - if (component is IUpdate update) - { - Updates.Remove(update); - } - else if (component is IFixedUpdate fixedUpdate) - { - FixedUpdates.Remove(fixedUpdate); - } - System.Push(component); - - CanUpdate = Updates.Count > 0; - - CanFixedUpdate = FixedUpdates.Count > 0; - } - } - -#if UNITY_EDITOR - CheckDebugInfo(); -#endif - } - - public void RmvComponent(Type componentType) - { - for (int i = 0; i < Components.Count; i++) - { - if (Components[i].GetType() == componentType) - { - - if (componentType is IUpdate update) - { - Updates.Remove(update); - - CanUpdate = Updates.Count > 0; - } - else if (componentType is IFixedUpdate fixedUpdate) - { - FixedUpdates.Remove(fixedUpdate); - - CanFixedUpdate = FixedUpdates.Count > 0; - } - //if (componentType is EcsComponent component) - //{ - // System.Push(component); - //} - } - } -#if UNITY_EDITOR - CheckDebugInfo(); -#endif - } - - public T AddComponent() where T : EcsComponent, new() - { -#if UNITY_EDITOR - CheckDebugInfo(); -#endif - T component = System.Get(); - component.Entity = this; - component.System = System; - Components.Add(component); - component.Awake(); - if (component is IUpdate update) - { - Updates.Add(update); - } - else if (component is IFixedUpdate fixedUpdate) - { - FixedUpdates.Add(fixedUpdate); - } - CanUpdate = Updates.Count > 0; - CanFixedUpdate = FixedUpdates.Count > 0; - return component; - } - - public EcsComponent AddComponent(EcsComponent component) - { -#if UNITY_EDITOR - CheckDebugInfo(); -#endif - component.Entity = this; - component.System = System; - Components.Add(component); - component.Awake(); - if (component is IUpdate update) - { - Updates.Add(update); - } - else if (component is IFixedUpdate fixedUpdate) - { - FixedUpdates.Add(fixedUpdate); - } - CanUpdate = Updates.Count > 0; - CanFixedUpdate = FixedUpdates.Count > 0; - return component; - } - - public T GetComponent() where T : EcsComponent - { - for (int i = 0; i < Components.Count; i++) - { - if (Components[i] is T type) - { - return type; - } - } - - return null; - } - - public EcsComponent GetComponent(Type componentType) - { - for (int i = 0; i < Components.Count; i++) - { - if (Components[i].GetType() == componentType) - { - return Components[i]; - } - } - - return null; - } - - public T[] GetComponents() where T : EcsComponent - { - List elements = new List(); - for (int i = 0; i < Components.Count; i++) - { - if (Components[i] is T type) - { - elements.Add(type); - } - } - return elements.ToArray(); - } - - public List GetComponentsList() where T : EcsComponent - { - List elements = new List(); - for (int i = 0; i < Components.Count; i++) - { - if (Components[i] is T type) - { - elements.Add(type); - } - } - return elements; - } - - public EcsComponent[] GetComponents(Type comType) - { - List elements = new List(); - for (int i = 0; i < Components.Count; i++) - { - { - if (Components[i].GetType() == comType) - { - elements.Add(Components[i]); - } - } - } - return elements.ToArray(); - } - - public override string ToString() { string str = "["; @@ -257,7 +86,7 @@ namespace TEngine } str = str.TrimEnd(','); str += "]"; - return $"{GetType().Name} Components: {str}"; + return $"{GetType().Name} InstanceId {this.InstanceId} Components: {str}"; } @@ -284,11 +113,6 @@ namespace TEngine #if UNITY_EDITOR //var actorEntity = this as Entity; - //if (actorEntity == null) - //{ - // return; - //} - //if (actorEntity.gameObject == null) //{ // return; @@ -304,5 +128,13 @@ namespace TEngine //} #endif } + + #region Static + public static T Create() where T : Entity, new() + { + var entity = EcsSystem.Instance.Create(); + return entity; + } + #endregion } } diff --git a/Assets/TEngine/Runtime/ECS/EntityExt.cs b/Assets/TEngine/Runtime/ECS/EntityExt.cs new file mode 100644 index 00000000..51fe5c1c --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/EntityExt.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TEngine +{ + partial class Entity + { + public void RmvComponent() where T : EcsComponent, new() + { + for (int i = 0; i < Components.Count; i++) + { + if (Components[i] is T component) + { + if (component is IUpdate update) + { + Updates.Remove(update); + } + else if (component is IFixedUpdate fixedUpdate) + { + FixedUpdates.Remove(fixedUpdate); + } + System.Push(component); + + CanUpdate = Updates.Count > 0; + + CanFixedUpdate = FixedUpdates.Count > 0; + } + } + +#if UNITY_EDITOR + CheckDebugInfo(); +#endif + } + + public void RmvComponent(Type componentType) + { + for (int i = 0; i < Components.Count; i++) + { + if (Components[i].GetType() == componentType) + { + + if (componentType is IUpdate update) + { + Updates.Remove(update); + + CanUpdate = Updates.Count > 0; + } + else if (componentType is IFixedUpdate fixedUpdate) + { + FixedUpdates.Remove(fixedUpdate); + + CanFixedUpdate = FixedUpdates.Count > 0; + } + //if (componentType is EcsComponent component) + //{ + // System.Push(component); + //} + } + } +#if UNITY_EDITOR + CheckDebugInfo(); +#endif + } + + public T AddComponent() where T : EcsComponent, new() + { +#if UNITY_EDITOR + CheckDebugInfo(); +#endif + T component = System.Get(); + component.Entity = this; + component.System = System; + Components.Add(component); + component.Awake(); + if (component is IUpdate update) + { + Updates.Add(update); + } + else if (component is IFixedUpdate fixedUpdate) + { + FixedUpdates.Add(fixedUpdate); + } + CanUpdate = Updates.Count > 0; + CanFixedUpdate = FixedUpdates.Count > 0; + return component; + } + + public EcsComponent AddComponent(EcsComponent component) + { +#if UNITY_EDITOR + CheckDebugInfo(); +#endif + component.Entity = this; + component.System = System; + Components.Add(component); + component.Awake(); + if (component is IUpdate update) + { + Updates.Add(update); + } + else if (component is IFixedUpdate fixedUpdate) + { + FixedUpdates.Add(fixedUpdate); + } + CanUpdate = Updates.Count > 0; + CanFixedUpdate = FixedUpdates.Count > 0; + return component; + } + + public T GetComponent() where T : EcsComponent + { + for (int i = 0; i < Components.Count; i++) + { + if (Components[i] is T type) + { + return type; + } + } + + return null; + } + + public EcsComponent GetComponent(Type componentType) + { + for (int i = 0; i < Components.Count; i++) + { + if (Components[i].GetType() == componentType) + { + return Components[i]; + } + } + + return null; + } + + public T[] GetComponents() where T : EcsComponent + { + List elements = new List(); + for (int i = 0; i < Components.Count; i++) + { + if (Components[i] is T type) + { + elements.Add(type); + } + } + return elements.ToArray(); + } + + public List GetComponentsList() where T : EcsComponent + { + List elements = new List(); + for (int i = 0; i < Components.Count; i++) + { + if (Components[i] is T type) + { + elements.Add(type); + } + } + return elements; + } + + public EcsComponent[] GetComponents(Type comType) + { + List elements = new List(); + for (int i = 0; i < Components.Count; i++) + { + { + if (Components[i].GetType() == comType) + { + elements.Add(Components[i]); + } + } + } + return elements.ToArray(); + } + + } +} diff --git a/Assets/TEngine/Runtime/ECS/EntityExt.cs.meta b/Assets/TEngine/Runtime/ECS/EntityExt.cs.meta new file mode 100644 index 00000000..15b99ab7 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/EntityExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db2d67ed7f48ae44fb071c9663fe1c90 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/HotfixComponent.cs b/Assets/TEngine/Runtime/ECS/HotfixComponent.cs deleted file mode 100644 index 4d7b1dda..00000000 --- a/Assets/TEngine/Runtime/ECS/HotfixComponent.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace TEngine -{ - public class HotfixComponent : EcsComponent,IUpdate - { - public object[] Values; - public Action OnAwake, OnUpdate, OnDestroyExt; - - public override void Awake() - { - OnAwake?.Invoke(); - } - - void IUpdate.Update() - { - OnUpdate?.Invoke(); - } - - public override void OnDestroy() - { - OnDestroyExt?.Invoke(); - OnAwake = null; - OnUpdate = null; - OnDestroyExt = null; - } - } -} - diff --git a/Assets/TEngine/Runtime/ECS/IFixedUpdate.cs b/Assets/TEngine/Runtime/ECS/IFixedUpdate.cs deleted file mode 100644 index 6bfb112d..00000000 --- a/Assets/TEngine/Runtime/ECS/IFixedUpdate.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace TEngine -{ - /// - /// Ecs组件更新接口(减少组件for循环开销) - /// - public interface IFixedUpdate - { - void FixedUpdate(); - } -} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs b/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs new file mode 100644 index 00000000..902ca7c1 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs @@ -0,0 +1,154 @@ +using System; + +namespace TEngine +{ + public interface IAwake + { + } + + public interface IAwake + { + } + + public interface IAwake + { + } + + public interface IAwake + { + } + + public interface IAwake + { + } + + public interface IAwakeSystem : ISystemType + { + void Run(object o); + } + + public interface IAwakeSystem : ISystemType + { + void Run(object o, T t); + } + + public interface IAwakeSystem : ISystemType + { + void Run(object o, T t, U u); + } + + public interface IAwakeSystem : ISystemType + { + void Run(object o, T t, U u, V v); + } + + public interface IAwakeSystem : ISystemType + { + void Run(object o, T t, U u, V v, W w); + } + + [ObjectSystem] + public abstract class AwakeSystem : IAwakeSystem where T : IAwake + { + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IAwakeSystem); + } + + public void Run(object o) + { + this.Awake((T)o); + } + + public abstract void Awake(T self); + } + + [ObjectSystem] + public abstract class AwakeSystem : IAwakeSystem where T : IAwake + { + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IAwakeSystem); + } + + public void Run(object o, A a) + { + this.Awake((T)o, a); + } + + public abstract void Awake(T self, A a); + } + + [ObjectSystem] + public abstract class AwakeSystem : IAwakeSystem where T : IAwake + { + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IAwakeSystem); + } + + public void Run(object o, A a, B b) + { + this.Awake((T)o, a, b); + } + + public abstract void Awake(T self, A a, B b); + } + + [ObjectSystem] + public abstract class AwakeSystem : IAwakeSystem where T : IAwake + { + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IAwakeSystem); + } + + public void Run(object o, A a, B b, C c) + { + this.Awake((T)o, a, b, c); + } + + public abstract void Awake(T self, A a, B b, C c); + } + + [ObjectSystem] + public abstract class AwakeSystem : IAwakeSystem where T : IAwake + { + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IAwakeSystem); + } + + public void Run(object o, A a, B b, C c, D d) + { + this.Awake((T)o, a, b, c, d); + } + + public abstract void Awake(T self, A a, B b, C c, D d); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs.meta b/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs.meta new file mode 100644 index 00000000..764e94d1 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/System/IAwakeSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8b44f8b7436d5f842b74580708345602 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs b/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs new file mode 100644 index 00000000..83de2c2b --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs @@ -0,0 +1,37 @@ +using System; + +namespace TEngine +{ + /// + /// Ecs组件物理更新接口(减少组件for循环开销) + /// + public interface IFixedUpdate + { + void FixedUpdate(); + } + + public interface IFixedUpdateSystem : ISystemType + { + void Run(object o); + } + + public abstract class FixedUpdateSystem : IFixedUpdateSystem where T : IFixedUpdate + { + public void Run(object o) + { + this.FixedUpdate((T)o); + } + + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IUpdateSystem); + } + + public abstract void FixedUpdate(T self); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs.meta b/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs.meta new file mode 100644 index 00000000..4f545368 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/System/IFixedUpdateSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a5d5fe02a754ab04a994132d573121b2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Runtime/ECS/System/ILateUpdateSystem.cs b/Assets/TEngine/Runtime/ECS/System/ILateUpdateSystem.cs new file mode 100644 index 00000000..21ec2131 --- /dev/null +++ b/Assets/TEngine/Runtime/ECS/System/ILateUpdateSystem.cs @@ -0,0 +1,37 @@ +using System; + +namespace TEngine +{ + /// + /// Ecs组件物理更新接口(减少组件for循环开销) + /// + public interface ILateUpdate + { + void LateUpdate(); + } + + public interface ILateUpdateSystem : ISystemType + { + void Run(object o); + } + + public abstract class LateUpdateSystem : ILateUpdateSystem where T : ILateUpdate + { + public void Run(object o) + { + this.LateUpdate((T)o); + } + + public Type Type() + { + return typeof(T); + } + + public Type SystemType() + { + return typeof(IUpdateSystem); + } + + public abstract void LateUpdate(T self); + } +} \ No newline at end of file