#if UNITY_NATIVE using System; using Svelto.Common; using Svelto.DataStructures; using Svelto.ECS.DataStructures; namespace Svelto.ECS { public partial class EnginesRoot { //todo: I very likely don't need to create one for each native entity factory, the same can be reused readonly AtomicNativeBags _addOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent); readonly AtomicNativeBags _removeOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent); readonly AtomicNativeBags _swapOperationQueue = new AtomicNativeBags(Common.Allocator.Persistent); NativeEntityRemove ProvideNativeEntityRemoveQueue(string memberName) where T : IEntityDescriptor, new() { //todo: remove operation array and store entity descriptor hash in the return value //todo I maybe able to provide a _nativeSwap.SwapEntity _nativeRemoveOperations.Add( new NativeOperationRemove(EntityDescriptorTemplate.descriptor.componentsToBuild, TypeCache.type, memberName)); return new NativeEntityRemove(_removeOperationQueue, _nativeRemoveOperations.count - 1); } NativeEntitySwap ProvideNativeEntitySwapQueue(string memberName) where T : IEntityDescriptor, new() { //todo: remove operation array and store entity descriptor hash in the return value _nativeSwapOperations.Add( new NativeOperationSwap(EntityDescriptorTemplate.descriptor.componentsToBuild, TypeCache.type, memberName)); return new NativeEntitySwap(_swapOperationQueue, _nativeSwapOperations.count - 1); } NativeEntityFactory ProvideNativeEntityFactoryQueue(string memberName) where T : IEntityDescriptor, new() { //todo: remove operation array and store entity descriptor hash in the return value _nativeAddOperations.Add( new NativeOperationBuild(EntityDescriptorTemplate.descriptor.componentsToBuild, TypeCache.type)); return new NativeEntityFactory(_addOperationQueue, _nativeAddOperations.count - 1); } void NativeOperationSubmission(in PlatformProfiler profiler) { using (profiler.Sample("Native Remove/Swap Operations")) { for (int i = 0; i < _removeOperationQueue.count; i++) { ref var buffer = ref _removeOperationQueue.GetBuffer(i); while (buffer.IsEmpty() == false) { var componentsIndex = buffer.Dequeue(); var entityEGID = buffer.Dequeue(); var nativeRemoveOperation = _nativeRemoveOperations[componentsIndex]; CheckRemoveEntityID(entityEGID, nativeRemoveOperation.entityDescriptorType); QueueEntitySubmitOperation(new EntitySubmitOperation( EntitySubmitOperationType.Remove, entityEGID, entityEGID , nativeRemoveOperation.components)); } } for (int i = 0; i < _swapOperationQueue.count; i++) { ref var buffer = ref _swapOperationQueue.GetBuffer(i); while (buffer.IsEmpty() == false) { var componentsIndex = buffer.Dequeue(); var entityEGID = buffer.Dequeue(); var componentBuilders = _nativeSwapOperations[componentsIndex].components; CheckRemoveEntityID(entityEGID.@from, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller ); CheckAddEntityID(entityEGID.to, _nativeSwapOperations[componentsIndex].entityDescriptorType, _nativeSwapOperations[componentsIndex].caller); QueueEntitySubmitOperation(new EntitySubmitOperation( EntitySubmitOperationType.Swap, entityEGID.@from, entityEGID.to , componentBuilders)); } } } using (profiler.Sample("Native Add Operations")) { for (int i = 0; i < _addOperationQueue.count; i++) { ref var buffer = ref _addOperationQueue.GetBuffer(i); while (buffer.IsEmpty() == false) { var componentsIndex = buffer.Dequeue(); var egid = buffer.Dequeue(); var componentCounts = buffer.Dequeue(); EntityComponentInitializer init = BuildEntity(egid, _nativeAddOperations[componentsIndex].components, _nativeAddOperations[componentsIndex].entityDescriptorType); //only called if Init is called on the initialized (there is something to init) while (componentCounts > 0) { componentCounts--; var typeID = buffer.Dequeue(); IFiller entityBuilder = EntityComponentIDMap.GetTypeFromID(typeID); //after the typeID, I expect the serialized component entityBuilder.FillFromByteArray(init, buffer); } } } } } void AllocateNativeOperations() { _nativeRemoveOperations = new FasterList(); _nativeSwapOperations = new FasterList(); _nativeAddOperations = new FasterList(); } FasterList _nativeRemoveOperations; FasterList _nativeSwapOperations; FasterList _nativeAddOperations; } readonly struct DoubleEGID { internal readonly EGID from; internal readonly EGID to; public DoubleEGID(EGID from1, EGID to1) { from = from1; to = to1; } } readonly struct NativeOperationBuild { internal readonly IComponentBuilder[] components; internal readonly Type entityDescriptorType; public NativeOperationBuild(IComponentBuilder[] descriptorComponentsToBuild, Type entityDescriptorType) { this.entityDescriptorType = entityDescriptorType; components = descriptorComponentsToBuild; } } readonly struct NativeOperationRemove { internal readonly IComponentBuilder[] components; internal readonly Type entityDescriptorType; internal readonly string caller; public NativeOperationRemove(IComponentBuilder[] descriptorComponentsToRemove, Type entityDescriptorType, string caller) { this.caller = caller; components = descriptorComponentsToRemove; this.entityDescriptorType = entityDescriptorType; } } readonly struct NativeOperationSwap { internal readonly IComponentBuilder[] components; internal readonly Type entityDescriptorType; internal readonly string caller; public NativeOperationSwap(IComponentBuilder[] descriptorComponentsToSwap, Type entityDescriptorType, string caller) { this.caller = caller; components = descriptorComponentsToSwap; this.entityDescriptorType = entityDescriptorType; } } } #endif