Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
3.0KB

  1. #if UNITY_NATIVE
  2. using System.Runtime.CompilerServices;
  3. using Svelto.DataStructures;
  4. namespace Svelto.ECS.Native
  5. {
  6. public readonly struct NativeEntityFactory
  7. {
  8. internal NativeEntityFactory(AtomicNativeBags addOperationQueue, int operationIndex, EnginesRoot.EntityReferenceMap entityLocator)
  9. {
  10. _operationIndex = operationIndex;
  11. _addOperationQueue = addOperationQueue;
  12. _entityLocator = entityLocator;
  13. }
  14. /// <summary>
  15. /// TODO is this still true?:
  16. ///
  17. /// var entity1Init = nativeFactory.BuildEntity(new EGID(1, Group.TestGroupA), threadIndex);
  18. /// var entity2Init = nativeFactory.BuildEntity(new EGID(2, Group.TestGroupA), threadIndex);
  19. /// and expect that entity1Init is still valid and I have to invalidate it
  20. /// I think I fixed it, but needs more test
  21. /// However we should remove atomicBags and use svelto dictionar
  22. /// </summary>
  23. /// <param name="eindex"></param>
  24. /// <param name="exclusiveBuildGroup"></param>
  25. /// <param name="threadIndex"></param>
  26. /// <returns></returns>
  27. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  28. public NativeEntityInitializer BuildEntity(uint eindex, ExclusiveBuildGroup exclusiveBuildGroup, int threadIndex)
  29. {
  30. EntityReference reference = _entityLocator.ClaimReference();
  31. NativeBag bagPerEntityPerThread = _addOperationQueue.GetBag(threadIndex + 1);
  32. bagPerEntityPerThread.Enqueue(
  33. _operationIndex); //each native operation is stored in an array, each request to perform a native operation in a queue. _index is the index of the operation in the array that will be dequeued later
  34. bagPerEntityPerThread.Enqueue(new EGID(eindex, exclusiveBuildGroup));
  35. bagPerEntityPerThread.Enqueue(reference);
  36. //NativeEntityInitializer is quite a complex beast. It holds the starting values of the component set by the user. These components must be later dequeued and in order to know how many components
  37. //must be dequeued, a count must be used. The space to hold the count is then reserved in the queue and index will be used access the count later on through NativeEntityInitializer so it can increment it.
  38. //index is not the number of components of the entity, it's just the number of components that the user decide to initialise
  39. bagPerEntityPerThread.ReserveEnqueue<uint>(out var index) = 0;
  40. return new NativeEntityInitializer(bagPerEntityPerThread, index, reference);
  41. }
  42. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  43. public NativeEntityInitializer BuildEntity(EGID egid, int threadIndex)
  44. {
  45. return BuildEntity(egid.entityID, egid.groupID, threadIndex);
  46. }
  47. readonly EnginesRoot.EntityReferenceMap _entityLocator;
  48. readonly AtomicNativeBags _addOperationQueue;
  49. readonly int _operationIndex;
  50. }
  51. }
  52. #endif