public bool MoveNext() { var inner = Inner.Span; while (true) { // If the user set Current to default, this mean we need to decrease the index if (current == default) { index--; } if (!canMove && !MoveInnerNext()) { return(false); } var entitySpan = Board.GetEntities(inner[InnerIndex]); if (entitySpan.Length <= index) { canMove = false; continue; } current = new GameEntityHandle(entitySpan[index++]); return(true); } }
public void AddingRemovingPerformance() { using var world = new GameWorld(); var component1 = world.RegisterComponent("Component1", new SingleComponentBoard(sizeof(int), 0)); for (var i = 0; i != 4; i++) { var entities = new GameEntityHandle[1000]; world.CreateEntityBulk(entities); var sw = new Stopwatch(); sw.Start(); foreach (var ent in entities) { world.AddComponent(ent, component1); } sw.Stop(); if (i != 0) { Console.WriteLine($"Add -> {sw.Elapsed.TotalMilliseconds}ms"); } sw.Restart(); foreach (var ent in entities) { world.RemoveComponent(ent, component1); } sw.Stop(); if (i != 0) { Console.WriteLine($"Remove -> {sw.Elapsed.TotalMilliseconds}ms"); } } }
public void TestBulk() { var lowest = TimeSpan.MaxValue; var entities = new GameEntityHandle[entityCount]; for (var iteration = 0; iteration != 100; iteration++) { var world = new GameWorld(); var sw = new Stopwatch(); var componentType = world.AsComponentType <Component>(); sw.Start(); world.CreateEntityBulk(entities); for (var i = 0; i != entityCount; i++) { var ent = entities[i]; world.AddComponent(ent, componentType); world.RemoveEntity(ent); } sw.Stop(); if (lowest > sw.Elapsed) { lowest = sw.Elapsed; } } Console.WriteLine($"{lowest.TotalMilliseconds}ms"); }
public void TestMillionEntitySystem() { const int size = 100_000; var gameWorld = new GameWorld(); var entities = new GameEntityHandle[size]; gameWorld.CreateEntityBulk(entities); var componentType = gameWorld.AsComponentType<IntComponent>(); for (var i = 0; i < size; i++) { gameWorld.AddComponent(entities[i], componentType); } var sw = new Stopwatch(); var lowest = TimeSpan.MaxValue; using var runner = new ThreadBatchRunner(1f); runner.StartPerformanceCriticalSection(); var query = new EntityQuery(gameWorld, new[] {componentType}); var system = new ArchetypeSystem<int>((in ReadOnlySpan<GameEntityHandle> entities, in SystemState<int> state) => { var accessor = new ComponentDataAccessor<IntComponent>(state.World); foreach (ref readonly var entity in entities) accessor[entity].Value++; }, query);
public ref T this[GameEntityHandle gameEntity] { #if DEBUG [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (Links.Length < gameEntity.Id + 1) { throw new IndexOutOfRangeException($"<{typeof(T).Name}> Links smaller! Length={Links.Length} < Index={gameEntity.Id}"); } if (Source.Length < Links[(int)gameEntity.Id].Assigned + 1) { throw new IndexOutOfRangeException($"<{typeof(T).Name}> Source smaller! Length={Source.Length} < Index={Links[(int) gameEntity.Id].Assigned}"); } return(ref Source[Links[(int)gameEntity.Id].Assigned]);
public void AddingRemovingMultiComponentPerformance() { using var world = new GameWorld(); var component1 = world.RegisterComponent("Component1", new SingleComponentBoard(sizeof(int), 0)); var component2 = world.RegisterComponent("Component2", new SingleComponentBoard(sizeof(int), 0)); var component3 = world.RegisterComponent("Component3", new SingleComponentBoard(sizeof(int), 0)); var component4 = world.RegisterComponent("Component4", new SingleComponentBoard(sizeof(int), 0)); for (var i = 0; i != 4; i++) { var entities = new GameEntityHandle[1000]; world.CreateEntityBulk(entities); var sw = new Stopwatch(); sw.Start(); Span <ComponentType> span = stackalloc [] { component1, component2, component3, component4 }; foreach (var ent in entities) { world.AddMultipleComponent(ent, span); } sw.Stop(); if (i != 0) { Console.WriteLine($"Add -> {sw.Elapsed.TotalMilliseconds}ms"); } sw.Restart(); foreach (var ent in entities) { world.RemoveMultipleComponent(ent, span); } sw.Stop(); if (i != 0) { Console.WriteLine($"Remove -> {sw.Elapsed.TotalMilliseconds}ms"); } } }
public bool MoveNext() { while (true) { if (!canMove && !MoveInnerNext()) { return(false); } var entitySpan = Inner.Board.GetEntities(Inner.Current.Id); if (entitySpan.Length <= index) { canMove = false; continue; } Current = new GameEntityHandle(entitySpan[index++]); return(true); } }
public static uint UpdateArchetype(ArchetypeBoardContainer archetypeBoard, ComponentTypeBoardContainer componentTypeBoard, EntityBoardContainer entityBoard, GameEntityHandle entityHandle) { var typeSpan = componentTypeBoard.Registered; var foundIndex = 0; Span <uint> founds = stackalloc uint[typeSpan.Length]; for (var i = 0; i != typeSpan.Length; i++) { var metadataSpan = entityBoard.GetComponentColumn(typeSpan[i].Id); /*if (metadataSpan.Length <= entityHandle.Id) TODO:: if it bug again, just uncomment this * continue;*/ if (metadataSpan[(int)entityHandle.Id].Valid) { founds[foundIndex++] = typeSpan[i].Id; } } if (foundIndex > 128) { throw new InvalidOperationException("What are you trying to do with " + foundIndex + " components?"); } var archetype = archetypeBoard.GetOrCreateRow(founds.Slice(0, foundIndex), true); var currentArchetype = entityBoard.ArchetypeColumn[(int)entityHandle.Id]; if (currentArchetype.Id != archetype) { entityBoard.AssignArchetype(entityHandle.Id, archetype); if (currentArchetype.Id > 0) { archetypeBoard.RemoveEntity(currentArchetype.Id, entityHandle.Id); } archetypeBoard.AddEntity(archetype, entityHandle.Id); } return(archetype); }
public static bool RemoveComponentReference(ComponentBoardBase componentBoard, ComponentType componentType, EntityBoardContainer entityBoard, GameEntityHandle entityHandle) { // todo: we need to have a real method for removing the component metadata on the column. var previousComponentId = entityBoard.AssignComponentReference(entityHandle.Id, componentType.Id, 0); if (previousComponentId > 0) { var refs = componentBoard.RemoveReference(previousComponentId, entityHandle); // nobody reference this component anymore, let's remove the row if (refs == 0) { componentBoard.DeleteRow(previousComponentId); } return(true); } return(false); }
public static void SetOwner(ComponentBoardBase componentBoard, ComponentReference componentReference, GameEntityHandle entityHandle) { componentBoard.OwnerColumn[(int)componentReference.Id] = entityHandle; }
public static bool AssignComponent(ComponentBoardBase componentBoard, ComponentReference componentReference, EntityBoardContainer entityBoard, GameEntityHandle entityHandle) { componentBoard.AddReference(componentReference.Id, entityHandle); var previousComponentId = entityBoard.AssignComponentReference(entityHandle.Id, componentReference.Type.Id, componentReference.Id); if (previousComponentId > 0) { var refs = componentBoard.RemoveReference(previousComponentId, entityHandle); // nobody reference this component anymore, let's remove the row if (refs == 0) { componentBoard.DeleteRow(previousComponentId); } return(false); } return(true); }