Beispiel #1
0
        public void Tick()
        {
            if (Engine == null)
            {
                return;
            }

            if (_commands.Count > 0)
            {
                _logger.Info("Executing tick with {0} commands.", _commands.Count);
            }

            var input = new EngineTickInput(_commands);

            _commands.Clear();

            var tick = Engine.Tick(input);

            tick.Start();
            tick.Wait();
            Engine.Synchronize();

            foreach (var resultEvent in tick.Result.Events)
            {
                EngineEvent?.Invoke(this, new GameEngineEventArgs(resultEvent, Engine));
            }
        }
Beispiel #2
0
        public Task<EngineTickResult> Tick(EngineTickInput input)
        {
            if (_state != States.Idle)
            {
                throw new InvalidOperationException($"RuntimeEngine cannot Tick() while while in state `{_state}`");
            }

            _state = States.Updating;

            var tick = new Task<EngineTickResult>(() =>
            {
                // Clear the "RemovedEntities" list from last frame.
                EntityService.CommitRemoved();
                
                // TODO: This is probably not deterministic. Update order is not guaranteeed for multithreaded bursts
                // Also this many loops is nasty.
               foreach (var updateBurst in SystemUpdateScheduler.UpdateBursts)
               {
                   foreach (var sys in updateBurst.Systems)
                   {
                       foreach (var commandHandler in sys.CommandHandlers)
                       {
                            foreach (var command in input.Commands)
                            {
                                if (commandHandler.CanHandle(command))
                                {
                                    commandHandler.OnCommand(command);
                                }
                            }
                        }
                   }
               }
                
                // Update all systems
                foreach (var updateBurst in SystemUpdateScheduler.UpdateBursts)
                {
                    // Lock the entity access gate if this is a multi-threaded burst.
                    AddEntityAccessGate.IsLocked = updateBurst.Systems.Count > 1;
                    // TODO: This still won't be enough to guarantee entity ID consistency.
                    // across different machines, since entity tick is also multithreaded.

                    Parallel.ForEach(updateBurst.Systems, (system) =>
                    {
                        if (system.HasTick)
                        {
                            ((Triggers.IOnTick)system.System).OnTick();
                        }

                        if (system.HasEntityTick)
                        {
                            Parallel.ForEach(system.Entities, (entity) =>
                            {
                                ((Triggers.IOnEntityTick) system.System).OnTick(entity);
                            });
                        }
                    });
                }

                // Add any entities from this frame to the system manager
                if (EntityService.AddedEntities.Count > 0)
                {
                    SystemManager.AddEntities(EntityService.AddedEntities);
                }

                // Process the removal from systems of any entities that were removed in this frame.
                if (EntityService.RemovedEntities.Count > 0)
                {
                    SystemManager.RemoveEntities(EntityService.RemovedEntities);
                }

                // Gather all the events that were added during this update step
                var events = EventQueue.DequeueAll();

                _state = States.AwaitingSync;
                return new EngineTickResult(events);
            });

            return tick;
        }
Beispiel #3
0
        public Task <EngineTickResult> Tick(EngineTickInput input)
        {
            if (_state != States.Idle)
            {
                throw new InvalidOperationException($"RuntimeEngine cannot Tick() while while in state `{_state}`");
            }

            _state = States.Updating;

            var tick = new Task <EngineTickResult>(() =>
            {
                // Clear the "RemovedEntities" list from last frame.
                EntityService.CommitRemoved();

                // TODO: This is probably not deterministic. Update order is not guaranteeed for multithreaded bursts
                // Also this many loops is nasty.
                foreach (var updateBurst in SystemUpdateScheduler.UpdateBursts)
                {
                    foreach (var sys in updateBurst.Systems)
                    {
                        foreach (var commandHandler in sys.CommandHandlers)
                        {
                            foreach (var command in input.Commands)
                            {
                                if (commandHandler.CanHandle(command))
                                {
                                    commandHandler.OnCommand(command);
                                }
                            }
                        }
                    }
                }

                // Update all systems
                foreach (var updateBurst in SystemUpdateScheduler.UpdateBursts)
                {
                    // Lock the entity access gate if this is a multi-threaded burst.
                    AddEntityAccessGate.IsLocked = updateBurst.Systems.Count > 1;
                    // TODO: This still won't be enough to guarantee entity ID consistency.
                    // across different machines, since entity tick is also multithreaded.

                    Parallel.ForEach(updateBurst.Systems, system =>
                    {
                        if (system.HasTick)
                        {
                            ((Triggers.IOnTick)system.System).OnTick();
                        }

                        if (system.HasEntityTick)
                        {
                            Parallel.ForEach(system.Entities,
                                             entity => { ((Triggers.IOnEntityTick)system.System).OnTick(entity); });
                        }
                    });
                }

                // Add any entities from this frame to the system manager
                if (EntityService.AddedEntities.Count > 0)
                {
                    SystemManager.AddEntities(EntityService.AddedEntities);
                }

                // Process the removal from systems of any entities that were removed in this frame.
                if (EntityService.RemovedEntities.Count > 0)
                {
                    SystemManager.RemoveEntities(EntityService.RemovedEntities);
                }

                // Gather all the events that were added during this update step
                var events = EventQueue.DequeueAll();

                _state = States.AwaitingSync;
                return(new EngineTickResult(events));
            });

            return(tick);
        }