Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        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");
                }
            }
        }
Exemplo n.º 3
0
        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");
        }
Exemplo n.º 4
0
        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);
Exemplo n.º 5
0
        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]);
Exemplo n.º 6
0
        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");
                }
            }
        }
Exemplo n.º 7
0
        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);
            }
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
 public static void SetOwner(ComponentBoardBase componentBoard, ComponentReference componentReference, GameEntityHandle entityHandle)
 {
     componentBoard.OwnerColumn[(int)componentReference.Id] = entityHandle;
 }
Exemplo n.º 11
0
        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);
        }