diff --git a/packages/com.seaube.ecsact/Editor/EcsactUnitySyncDebugWindow.cs b/packages/com.seaube.ecsact/Editor/EcsactUnitySyncDebugWindow.cs index 1170e2d..e19a801 100644 --- a/packages/com.seaube.ecsact/Editor/EcsactUnitySyncDebugWindow.cs +++ b/packages/com.seaube.ecsact/Editor/EcsactUnitySyncDebugWindow.cs @@ -29,7 +29,7 @@ public static EcsactUnitySyncGameObjectPreview CreateInstance() { protected override void OnEnable() { base.OnEnable(); scene = EditorSceneManager.NewPreviewScene(); - pool = EntityGameObjectPool.CreateInstance(); + pool = EntityGameObjectPool.CreateInstance(null!); pool.targetScene = scene; if(Camera.main != null) { diff --git a/packages/com.seaube.ecsact/Runtime/EcsactUnitySync.cs b/packages/com.seaube.ecsact/Runtime/EcsactUnitySync.cs index 78f4bdb..39d4474 100644 --- a/packages/com.seaube.ecsact/Runtime/EcsactUnitySync.cs +++ b/packages/com.seaube.ecsact/Runtime/EcsactUnitySync.cs @@ -374,6 +374,39 @@ public static IEnumerable GetInterfaces } } + public static IEnumerable GetInitComponentIds + ( System.Type type + ) + { + if(onInitComponentsMap.TryGetValue(type, out var compIds)) { + foreach(var compId in compIds) { + yield return compId; + } + } + } + + public static IEnumerable GetRemoveComponentIds + ( System.Type type + ) + { + if(onInitComponentsMap.TryGetValue(type, out var compIds)) { + foreach(var compId in compIds) { + yield return compId; + } + } + } + + public static IEnumerable GetRequiredComponentIds + ( System.Type type + ) + { + if(requiredComponentsMap.TryGetValue(type, out var compIds)) { + foreach(var compId in compIds) { + yield return compId; + } + } + } + public static void ClearRegisteredMonoBehaviourTypes() { knownComponentIds.Clear(); knownComponentTypes.Clear(); @@ -474,15 +507,6 @@ private static void EndMonoBehaviourRegistration ( Type monoBehaviourType ) { - var compIds = new ComponentIdsList(); - var reqCompIds = new ComponentIdsList(); - - reqCompIds.UnionWith(requiredComponentsMap[monoBehaviourType]); - compIds.UnionWith(onInitComponentsMap[monoBehaviourType]); - compIds.UnionWith(onUpdateComponentsMap[monoBehaviourType]); - compIds.UnionWith(onRemoveComponentsMap[monoBehaviourType]); - - } private static void RegisterRequiredInterface diff --git a/packages/com.seaube.ecsact/Runtime/EntityGameObjectPool.cs b/packages/com.seaube.ecsact/Runtime/EntityGameObjectPool.cs index 1827b96..65efbc2 100644 --- a/packages/com.seaube.ecsact/Runtime/EntityGameObjectPool.cs +++ b/packages/com.seaube.ecsact/Runtime/EntityGameObjectPool.cs @@ -12,11 +12,42 @@ namespace Ecsact.UnitySync { public class EntityGameObjectPool : ScriptableObject { + public abstract class EntitySource { + public abstract object GetComponent + ( System.Int32 entityId + , System.Int32 componentId + ); + public abstract bool HasComponent + ( System.Int32 entityId + , System.Int32 componentId + ); + } - public static EntityGameObjectPool CreateInstance() { - return (EntityGameObjectPool)ScriptableObject.CreateInstance( + public static EntityGameObjectPool CreateInstance + ( EntitySource entitySource + ) + { + var pool = (EntityGameObjectPool)ScriptableObject.CreateInstance( typeof(EntityGameObjectPool) ); + + pool._entitySource = entitySource; + + return pool; + } + + private EntitySource? _entitySource; + private EntitySource entitySource { + get { + UnityEngine.Debug.Assert( + _entitySource != null, + "entitySource is unset. Please use " + + "EntityGameObjectPool.CreateInstance when creating an " + + "EntityGameObjectPool instance.", + this + ); + return _entitySource!; + } } private List entityComponentIds; @@ -155,11 +186,26 @@ public void InitComponent if(onInitEntity != null) { onInitEntity.OnInitEntity(entityId); } + var initCompIds = UnitySyncMonoBehaviours.GetInitComponentIds(type); + foreach(var initCompId in initCompIds) { + if(initCompId == componentId) continue; + if(!entitySource.HasComponent(entityId, initCompId)) continue; + + var initComponent = entitySource.GetComponent( + entityId, + initCompId + ); + UnitySyncMonoBehaviours.InvokeOnInit( + newMonoBehaviour, + initCompId, + in initComponent + ); + } } } gameObject = gameObject ?? GetEntityGameObject(entityId); - + if(gameObject != null) { UnitySyncMonoBehaviours.InvokeOnInit( gameObject, @@ -188,18 +234,13 @@ public void UpdateComponent ) { var gameObject = GetEntityGameObject(entityId); - if(gameObject == null) { - throw new System.ArgumentException( - $"EntityGameObjectPool.UpdateComponent called before " + - $"EntityGameObjectPool.InitComponent. entityId={entityId}" + if(gameObject != null) { + UnitySyncMonoBehaviours.InvokeOnUpdate( + gameObject, + componentId, + in component ); } - - UnitySyncMonoBehaviours.InvokeOnUpdate( - gameObject, - componentId, - in component - ); } public void RemoveComponent @@ -237,6 +278,35 @@ public void RemoveComponent ); var gameObject = entityGameObjects[entityId]!; + + var allMonoBehaviourTypes = UnitySyncMonoBehaviours.GetTypes( + nextCompIds + ); + + foreach(var type in addedTypes) { + var newMonoBehaviour = (MonoBehaviour)gameObject.AddComponent(type); + IOnInitEntity? onInitEntity = newMonoBehaviour as IOnInitEntity; + if(onInitEntity != null) { + onInitEntity.OnInitEntity(entityId); + } + + var initCompIds = UnitySyncMonoBehaviours.GetInitComponentIds(type); + foreach(var initCompId in initCompIds) { + if(initCompId == componentId) continue; + if(!entitySource.HasComponent(entityId, initCompId)) continue; + + var initComponent = entitySource.GetComponent( + entityId, + initCompId + ); + UnitySyncMonoBehaviours.InvokeOnInit( + newMonoBehaviour, + initCompId, + in initComponent + ); + } + } + UnitySyncMonoBehaviours.InvokeOnRemove( gameObject, componentId, @@ -253,22 +323,6 @@ in component } } - foreach(var type in addedTypes) { - var newMonoBehaviour = (MonoBehaviour)gameObject.AddComponent(type); - IOnInitEntity? onInitEntity = newMonoBehaviour as IOnInitEntity; - if(onInitEntity != null) { - onInitEntity.OnInitEntity(entityId); - } - UnitySyncMonoBehaviours.InvokeOnInit( - newMonoBehaviour, - componentId, - in component - ); - } - - var allMonoBehaviourTypes = UnitySyncMonoBehaviours.GetTypes( - nextCompIds - ); if(!allMonoBehaviourTypes.Any()) { gameObject.SetActive(false); gameObject.name = $"entity ({entityId})";