diff --git a/Runtime/Scripts/MonoBehaviours/WorldBehaviour.cs b/Runtime/Scripts/MonoBehaviours/WorldBehaviour.cs index be892be..df0d834 100644 --- a/Runtime/Scripts/MonoBehaviours/WorldBehaviour.cs +++ b/Runtime/Scripts/MonoBehaviours/WorldBehaviour.cs @@ -103,12 +103,10 @@ private void AddSystemToGroup(ComponentSystemGroup group, ComponentSystemBase sy switch (group) { case IList lcsg: lcsg.Add(system); - break; - case ComponentSystemGroup csg: - csg.AddSystemToUpdateList(system); - break; + return; default: - throw new Exception("Group must be compatible."); + group.AddSystemToUpdateList(system); + return; } } } diff --git a/Runtime/Scripts/Systems/Groups/ListComponentSystemGroup.cs b/Runtime/Scripts/Systems/Groups/ListComponentSystemGroup.cs index dc27c6f..8dc61d5 100644 --- a/Runtime/Scripts/Systems/Groups/ListComponentSystemGroup.cs +++ b/Runtime/Scripts/Systems/Groups/ListComponentSystemGroup.cs @@ -2,16 +2,30 @@ using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Reflection; using Unity.Entities; using UnityEngine; namespace Software10101.DOTS.Systems.Groups { + /// + /// Component system group that acts like a List. Not compatible with unmanaged systems. + /// public abstract class ListComponentSystemGroup : ComponentSystemGroup, IList, IReadOnlyList, IList { + private List _underlyingSystemsToUpdate; + private static readonly FieldInfo UnderlyingSystemsToUpdateField = typeof(ComponentSystemGroup).GetField( + "m_systemsToUpdate", + BindingFlags.Instance | BindingFlags.NonPublic); + + private List _underlyingSystemsToRemove; + private static readonly FieldInfo UnderlyingSystemsToRemoveField = typeof(ComponentSystemGroup).GetField( + "m_systemsToRemove", + BindingFlags.Instance | BindingFlags.NonPublic); + private ComponentSystemBase[] _systems = new ComponentSystemBase[0]; private readonly List _mutableSystemsList = new List(); private bool _systemsListDirtyFlag = false; @@ -24,12 +38,39 @@ public abstract class ListComponentSystemGroup : public override IEnumerable Systems => _systems; + protected override void OnCreate() { + _underlyingSystemsToUpdate = (List)UnderlyingSystemsToUpdateField.GetValue(this); + _underlyingSystemsToRemove = (List)UnderlyingSystemsToRemoveField.GetValue(this); + } + protected override void OnUpdate() { + if (_underlyingSystemsToUpdate.Count > 0) { + _mutableSystemsList.AddRange(_underlyingSystemsToUpdate); + _underlyingSystemsToUpdate.Clear(); + _systemsListDirtyFlag = true; + } + + if (_underlyingSystemsToRemove.Count > 0) { + _underlyingSystemsToRemove.ForEach(system => _mutableSystemsList.Remove(system)); + _underlyingSystemsToRemove.Clear(); + _systemsListDirtyFlag = true; + } + if (_systemsListDirtyFlag) { _systemsListDirtyFlag = false; _systems = _mutableSystemsList.ToArray(); } + if (UpdateCallback == null) { + UpdateAllSystems(); + } else { + while (UpdateCallback(this)) { + UpdateAllSystems(); + } + } + } + + private void UpdateAllSystems() { int count = _systems.Length; int index; diff --git a/package.json b/package.json index 4431b7b..f00818e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.10101software.dots.hybridsimulation", "description": "A framework for using FixedUpdate in a simulation world which is linked to a GameObject-based presentation layer.", - "version": "0.4.0", + "version": "0.4.1", "unity": "2020.1", "displayName": "DOTS Hybrid Simulation Worlds", "dependencies": {