Esempio n. 1
0
        public MainPage()
        {
            InitializeComponent();

            SoundPlayer.FillDictionary(App.Current.Resources.MergedDictionaries[0]);
            SoundPlayer.BackgroundMusic.FillBgDictionary(App.Current.Resources.MergedDictionaries[1]);
            TextHandler.FillDictionary(App.Current.Resources.MergedDictionaries[2]);

            this.GotFocus  += MainPageGotFocus;
            this.LostFocus += MainPageLostFocus;

            _keyHandler = new KeyHandler(this);

            _menuEngine           = new MenuEngine(this.gameSurface);
            _menuEngine.Updated  += MenuEngineUpdated;
            _levelEngine          = new LevelEngine(new Canvas());
            _levelEngine.Renewed += LevelEngineRenewed;
            _hudEngine            = new HudEngine(new Canvas());
            _scoreEngine          = new ScoreEngine(new Canvas(), 10);

            Level.Player = Player = new Player();

            _renderNotifier = new RenderNotifier(this);
            _renderNotifier.AddObservedChild(this.gameSurface);
            _renderNotifier.RenderComplete += RenderNotifierRenderComplete;

            _mainLoop         = new CompositionTargetGameLoop();
            _mainLoop.Update += MainLoopUpdate;
        }
Esempio n. 2
0
 public void SetSequence(EnemyDeathEngine enemyDeathEngine,
                         ScoreEngine scoreEngine,
                         DamageSoundEngine damageSoundEngine,
                         EnemyAnimationEngine enemyAnimationEngine,
                         EnemySpawnerEngine enemySpawnerEngine)
 {
     base.SetSequence(
         new Steps              //sequence of steps, this is a dictionary!
         (
             new Step
     {
         @from = enemyDeathEngine,
         to    = new To
                 (
             //TIP: use GO To Type Declaration to go directly to the Class code of the
             //engine instance
             scoreEngine, damageSoundEngine
                 )
     },
             new Step
     {
         //second step
         @from = enemyAnimationEngine,
         //after the death animation is actually finished
         to = new To
              (
             enemySpawnerEngine                        //call the spawner engine
              )
     }
         )
         );
 }
Esempio n. 3
0
        public LevelHolder(LevelEngine levelEngine, HudEngine hudEngine, ScoreEngine scoreEngine)
            : base(_menu)
        {
            if (levelEngine == null)
            {
                throw new ArgumentNullException("No LevelEngine defined!");
            }
            _levelEngine                  = levelEngine;
            _levelEngine.Started         += LevelEngineStarted;
            _levelEngine.BeforeNextLevel += LevelEngineBeforeNextLevel;
            _levelEngine.Finished        += LevelEngineFinished;

            if (hudEngine == null)
            {
                throw new ArgumentNullException("No HudEngine defined!");
            }
            _hudEngine          = hudEngine;
            _hudEngine.TimesUp += TimesUp;

            if (scoreEngine == null)
            {
                throw new ArgumentNullException("No ScoreEngine defined!");
            }
            _scoreEngine = scoreEngine;

            ConnectPlayer();

            _levelSurface = _menu.FindName("levelSurface") as Canvas;
            if (_levelSurface == null)
            {
                throw new NotImplementedException("levelSurface canvas not implemented");
            }
            _levelSurface.Children.Add(_levelEngine.Container);

            _hudSurface = _menu.FindName("hudSurface") as Canvas;
            if (_hudSurface == null)
            {
                throw new NotImplementedException("hudSurface canvas not implemented");
            }
            _hudSurface.Children.Add(_hudEngine.Container);

            this.Shown += LevelHolderShown;
        }
/// <summary>
/// Before to start a review of Svelto.ECS terminologies:
/// - Entity:
///     it must be a real and concrete entity that you can explain
///     in terms of game design. The name of each entity should reflect
///     a specific concept from the game design domain
/// - IComponents:
///     Components must be seen as data holders. There are implementing
///     exceptions, but logically it must be still see as a group
///     of readable or writeable data.
///     In Svelto.ECS components are always interfaces declaring
///     Setters and Getters of ValueTypes. DispatchOnSet
///     and DispatchOnChange must not be seen as events, but
///     as pushing of data instead of data polling, similar
///     to the concept of DataBinding.
/// - Implementors:
///     Being components interfaces, they must be implemented through
///     Implementors. The relation Implementors to Components
///     is not 1:1 so that you can, if logic, group several
///     components in one implementor. This allows to easily
///     share data between components. Implementors also act
///     as bridge between the platform and Svelto.ECS.
///     Since Components can hold only value types, Implementors
///     are the objects that can interact directly with the platform
///     objects, I.E.: RigidBody, Transform and so on.
///     Note: IComponents must hold only valuetypes for
///     code design purposes and not optmization purposes.
///     The reason is that all the logic must lie in the engines
///     so Components cannot hold references to instances that can
///     expose functions with logic.
/// - Engines:
///     Where all the logic lies. Engines operates on EntityViews
/// - EntityViews:
///     EntityViews maps EntityComponents. The Engines can't
///     access directly to each entity (as a single set of components), but
///     through a component sets defined by EntityView.
///     They act as a component filters and expose only the entity components
///     that the Engine is interested in.
///     EntityViews are actually defined by the need of the Engine so they
///     come together with the engine and in the same namespace of the engine.
/// - EntityStructs:
///     In order to write Data Oriented Cache Friendly code, Svelto.ECS
///     also support EntityStructs. Please check other examples to
///     understand how to use them. However know that this kind of
///     optimizations is very limited to special circumstances
///     so the flexibility of EntityViews is most of the times what you need.
/// - EntityDescriptors:
///     Gives a way to formalize your Entity in svelto.ECS, it also
///     groups the EntityViews that must be generated once the
///     Entity is built
/// </summary>
        void SetupEnginesAndEntities()
        {
            //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot
            //as it is, therefore the composition root must hold a reference or it will be
            //GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to inject the EntityViews. You shouldn't use a custom one unless you know what you
            //are doing or you are not working with Unity.
            _enginesRoot = new EnginesRoot(new UnitySumbmissionEntityViewScheduler());
            //Engines root can never be held by anything else than the context itself to avoid leaks
            //That's why the EntityFactory and EntityFunctions are generated.
            //The EntityFactory can be injected inside factories (or engine acting as factories)
            //to build new entities dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including
            //removing an entity. I couldn't find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();
            //GameObjectFactory allows to create GameObjects without using the Static
            //method GameObject.Instantiate. While it seems a complication
            //it's important to keep the engines testable and not
            //coupled with hard dependencies references (read my articles to understand
            //how dependency injection works and why solving dependencies
            //with static classes and singletons is a terrible mistake)
            GameObjectFactory factory = new GameObjectFactory();
            //the ISequencer is one of the 3 official ways available in Svelto.ECS
            //to communicate. They are mainly used for two specific cases:
            //1) specify a strict execution order between engines (engine logic
            //is executed horizontally instead than vertically, I will talk about this
            //in my articles). 2) filter a data token passed as parameter through
            //engines. The ISequencer is also not the common way to communicate
            //between engines
            Sequencer playerDamageSequence = new Sequencer();
            Sequencer enemyDamageSequence  = new Sequencer();

            //wrap non testable unity static classes, so that
            //can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependecies must be solved at this point
            //through constructor injection.
            var playerHealthEngine    = new HealthEngine(playerDamageSequence);
            var playerShootingEngine  = new PlayerGunShootingEngine(enemyDamageSequence, rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time);
            //HealthEngine is a different object for the enemy because it uses a different sequence
            var enemyHealthEngine   = new HealthEngine(enemyDamageSequence);
            var enemyAttackEngine   = new EnemyAttackEngine(playerDamageSequence, time);
            var enemyMovementEngine = new EnemyMovementEngine();
            var enemySpawnerEngine  = new EnemySpawnerEngine(factory, _entityFactory);
            var enemyDeathEngine    = new EnemyDeathEngine(entityFunctions);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementaton is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            playerDamageSequence.SetSequence(
                new Steps              //sequence of steps, this is a dictionary!
            {
                {                      //first step
                    enemyAttackEngine, //this step can be triggered only by this engine through the Next function
                    new To             //this step can lead only to one branch
                    {
                        //this is the only engine that will be called when enemyAttackEngine triggers Next()
                        new IStep[] { playerHealthEngine }
                    }
                },
                {                       //second step
                    playerHealthEngine, //this step can be triggered only by this engine through the Next function
                    new To              //once the playerHealthEngine calls step, all these engines will be called at once
                                        //depending by the condition a different set of engines will be triggered. The
                                        //order of the engines triggered is guaranteed.
                    {
                        //these engines will be called when the Next function is called with the DamageCondition.damage set
                        { DamageCondition.Damage, new IStep[] { hudEngine, damageSoundEngine } },
                        //these engines will be called when the Next function is called with the DamageCondition.dead set
                        { DamageCondition.Dead, new IStep[] {
                              hudEngine, damageSoundEngine,
                              playerMovementEngine, playerAnimationEngine,
                              enemyAnimationEngine, playerDeathEngine
                          } }
                    }
                }
            }
                );

            enemyDamageSequence.SetSequence(
                new Steps
            {
                {
                    playerShootingEngine,
                    new To
                    {
                        //in every case go to enemyHealthEngine
                        new IStep[] { enemyHealthEngine }
                    }
                },
                {
                    enemyHealthEngine,
                    new To
                    {
                        { DamageCondition.Damage, new IStep[] { enemyAnimationEngine, damageSoundEngine } },
                        { DamageCondition.Dead, new IStep[] { scoreEngine, enemyMovementEngine,
                                                              enemyAnimationEngine, enemySpawnerEngine,
                                                              damageSoundEngine, enemyDeathEngine } },
                    }
                }
            }
                );

            //Mandatory step to make engines work
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(playerHealthEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyHealthEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }
Esempio n. 5
0
        public string Answer(string userId, string utterance)
        {
            BotContext context = this.GetValidContext(userId);

            bool isSingleContact = this.IsSingleContact(ref utterance);

            if (context == null)
            {
                LUInfo luInfo = Understand(utterance, isSingleContact);
                if (luInfo.GetType() == typeof(TestLUInfo))
                {
                    context = InitTFContext(userId, (TestLUInfo)luInfo);
                }
                else if (luInfo.GetType() == typeof(ExamLUInfo))
                {
                    context = InitESContext(userId, (ExamLUInfo)luInfo);
                }
                else if (luInfo.GetType() == typeof(ScoreLUInfo))
                {
                    context = InitScoreContext(userId, (ScoreLUInfo)luInfo);
                }
                else
                {
                    context = initPSAContext(userId, luInfo);
                }

                cManager.CreateContext(context, userId);
            }
            else
            {
                if (context.type == ContextType.TaskFlowContext && isSingleContact)
                {
                    TaskFlowContext tfContext = (TaskFlowContext)context;
                    context = updateTFContext(ref tfContext, utterance);
                }
                else if (context.type == ContextType.ExamSuitContext && isSingleContact)
                {
                    ExamSuitContext esContext = (ExamSuitContext)context;
                    context = updateESContext(ref esContext, utterance);
                }
                else if (context.type == ContextType.ScoreContext && isSingleContact)
                {
                    ScoreContext scContext = (ScoreContext)context;
                    context = updateSCContext(ref scContext, utterance);
                }
                else
                {
                    LUInfo luInfo = Understand(utterance, isSingleContact);

                    if (context.type == ContextType.PSAContext)
                    {
                        PSAContext psacontext = (PSAContext)context;
                        context = updatePSAContext(ref psacontext, luInfo);
                    }
                    else
                    {
                        return("[Error]: Unknown Context Type.");
                    }
                }
            }

            string answer = null;

            switch (context.type)
            {
            case ContextType.ScoreContext:
                ScoreEngine  engineS   = new ScoreEngine();
                ScoreContext scContext = (ScoreContext)context;

                answer = engineS.Answer(userId, ref scContext);

                if (scContext.IsInTesting)
                {
                    cManager.UpdateContext(scContext, userId);
                }
                else
                {
                    cManager.RemoveContext(userId);
                }
                break;

            case ContextType.PSAContext:
                ChatTableEngine engine     = new ChatTableEngine();
                PSAContext      psacontext = (PSAContext)context;

                answer = engine.Answer(userId, ref psacontext);

                cManager.UpdateContext(psacontext, userId);
                break;

            case ContextType.TaskFlowContext:
                TestEngine      engineT   = new TestEngine();
                TaskFlowContext tfContext = (TaskFlowContext)context;

                answer = engineT.Answer(userId, ref tfContext);

                if (tfContext.IsInTesting)
                {
                    cManager.UpdateContext(tfContext, userId);
                }
                else
                {
                    cManager.RemoveContext(userId);
                }
                break;

            case ContextType.ExamSuitContext:

                ExamSuitContext esContext = (ExamSuitContext)context;
                DICSExamSrv     taskSrv   = new DICSExamSrv();

                string userInput = esContext.UserInput;

                switch (esContext.status)
                {
                case ESStatus.Started:
                    ExamSuitContext cachedContext = this.GetCachedESContext(userId);
                    answer = taskSrv.StartTest(ref esContext, cachedContext);
                    break;

                case ESStatus.Restarted:
                    answer = taskSrv.ContinueOrRefresh(ref esContext, userInput);
                    break;

                case ESStatus.OnGoing:
                    answer = taskSrv.ReceiveUserAnswer(ref esContext, userInput);
                    break;
                }

                if (esContext.status == ESStatus.Finished || esContext.status == ESStatus.Aborded)
                {
                    cManager.RemoveContext(userId);
                }
                else if (esContext.status == ESStatus.Paused)
                {
                    cManager.StoreESContext(esContext, userId);
                    cManager.RemoveContext(userId);
                }
                else
                {
                    cManager.UpdateContext(esContext, userId);
                }

                break;
            }

            return(answer);
        }
Esempio n. 6
0
        /// <summary>
/// Before to start a review of Svelto.ECS terminologies:
/// - Entity:
///     it must be a real and concrete entity that you can explain
///     in terms of game design. The name of each entity should reflect
///     a specific concept from the game design domain
/// - Engines (Systems):
///     Where all the logic lies. Engines operates on EntityViews or EntityStructs
/// - EntityViews and EntitiyViewStructs:
///     EntityViews maps Entity Components. The Engines can't
///     access directly to each entity (as a single set of components), but
///     through component sets defined by the EntityView.
///     They act as component filters and expose only the entity components
///     that the Engine is interested in.
///     EntityViews are actually defined with the Engine so they
///     come together with the engine and in the same namespace of the engine.
///     EntityViewStructs should always be used, while EntityViews as
///     class use should be considered an exception.
/// - Component Interfaces:
///     Components must be seen as data holders. There may be implementation
///     exceptions, but the interface must declare a group
///     of readable and/or writeable data.
///     In Svelto.ECS components are always interfaces declaring
///     Setters and Getters of Value Types. DispatchOnSet
///     and DispatchOnChange must not be seen as events, but
///     as pushing of data instead of data polling, similar
///     to the concept of DataBinding.
/// - Implementors:
///     Being components interfaces, they must be implemented through
///     Implementors. The relation Implementors to Components
///     is not 1:1 so that you can group several
///     components into fewer implementors. This allows to easily
///     share data between components. Implementors also act
///     as bridge between the platform and Svelto.ECS.
///     Since Components can hold only value types, Implementors
///     are the objects that can interact directly with the platform
///     objects, I.E.: RigidBody, Transform and so on.
///     Note: IComponents must hold only valuetypes for
///     code design purposes and not optmization purposes.
///     The reason is that all the logic must lie in the engines
///     so Components cannot hold references to instances that can
///     expose functions with logic.
/// - EntityStructs:
///     In order to write Data Oriented Cache Friendly and allocation 0 code, Svelto.ECS
///     also supports EntityStructs.
/// - EntityDescriptors:
///     Gives a way to formalize your Entity in svelto.ECS, it also
///     defoines the EntityViews, EntityStructs and EntityViewStructs that must be generated once the
///     Entity is built
/// </summary>
        void SetupEngines()
        {
            //The Engines Root is the core of Svelto.ECS. You must NEVER inject the EngineRoot
            //as it is, therefore the composition root must hold a reference or it will be
            //GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to inject the EntityViews. You shouldn't use a custom one unless you know what you
            //are doing or you are not working with Unity.
            _enginesRoot = new EnginesRoot(new UnityEntitySubmissionScheduler());
            //Engines root can never be held by anything else than the context itself to avoid leaks
            //That's why the EntityFactory and EntityFunctions are generated.
            //The EntityFactory can be injected inside factories (or engine acting as factories)
            //to build new entities dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including
            //removing an entity. I couldn't find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();

            //the ISequencer is one of the 2 official ways available in Svelto.ECS
            //to communicate. They are mainly used for two specific cases:
            //1) specify a strict execution order between engines (engine logic
            //is executed horizontally instead than vertically, I will talk about this
            //in my articles). 2) filter a data token passed as parameter through
            //engines. The ISequencer is also not the common way to communicate
            //between engines
            PlayerDeathSequencer playerDeathSequence = new PlayerDeathSequencer();
            EnemyDeathSequencer  enemyDeathSequence  = new EnemyDeathSequencer();

            //wrap non testable unity static classes, so that
            //can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependencies must be solved at this point
            //through constructor injection.
            var playerShootingEngine  = new PlayerGunShootingEngine(rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(playerDeathSequence, entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions);
            var enemyAttackEngine    = new EnemyAttackEngine(time);
            var enemyMovementEngine  = new EnemyMovementEngine();

            //GameObjectFactory allows to create GameObjects without using the Static
            //method GameObject.Instantiate. While it seems a complication
            //it's important to keep the engines testable and not
            //coupled with hard dependencies references (read my articles to understand
            //how dependency injection works and why solving dependencies
            //with static classes and singletons is a terrible mistake)
            GameObjectFactory factory = new GameObjectFactory();
            //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged
            IEnemyFactory enemyFactory       = new EnemyFactory(factory, _entityFactory);
            var           enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions);
            var           enemyDeathEngine   = new EnemyDeathEngine(entityFunctions, enemyDeathSequence);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementation is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            //These two sequencers are a real stretch and are shown only for explanatory purposes.
            //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively
            //to guarantee the order of execution of the involved engines.
            //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines
            //do not need to be executed in specific order.
            //a Sequencer can:
            //- ensure the order of execution through one step only (one step executes in order several engines)
            //- ensure the order of execution through several steps. Each engine inside each step has the responsibility
            //to trigger the next step through the use of the Next() function
            //- create paths with branches and loop using the Condition parameter.
            playerDeathSequence.SetSequence(
                new Steps //sequence of steps, this is a dictionary!
            {
                {
                    /*from: */ playerDeathEngine,    //when the player dies
                    /*to:   */ new To <PlayerDeathCondition>
                    //all these engines in the list will be called in order (which in this
                    //case was not important at all, so stretched!!)
                    {
                        { PlayerDeathCondition.Death, playerMovementEngine, playerAnimationEngine, enemyAnimationEngine, damageSoundEngine, hudEngine }
                    }
                }
            }
                );

            enemyDeathSequence.SetSequence(
                new Steps
            {
                {     //first step
                    enemyDeathEngine,
                    new To <EnemyDeathCondition>
                    {
                        //TIP: use GO To Type Declaration to go directly to the Class code of the
                        //engine instance
                        { EnemyDeathCondition.Death, scoreEngine, enemyAnimationEngine }
                    }
                },
                {                         //second step
                    enemyAnimationEngine, //after the death animation is actually finished
                    new To <EnemyDeathCondition>
                    {
                        { EnemyDeathCondition.Death, enemySpawnerEngine }    //call the spawner engine
                    }
                }
            }
                );

            //All the logic of the game must lie inside engines
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            _enginesRoot.AddEngine(playerDeathEngine);

            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine());
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(new CharactersDeathEngine());
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }
Esempio n. 7
0
 public Form1()
 {
     InitializeComponent();
     ScoreEngine = new ScoreEngine();
 }
Esempio n. 8
0
 public CalculateRiskProfileService(ScoreEngine scoreEngine)
 {
     _scoreEngine = scoreEngine;
 }
Esempio n. 9
0
        /// <summary>
        ///     Before to start, let's review some of the Svelto.ECS terms:
        ///     - Entity:
        ///     it must be a real and concrete entity that you can explain in terms of game design. The name of each
        ///     entity should reflect a specific concept from the game design domain
        ///     - Engines (Systems):
        ///     Where all the logic lies. Engines operates on EntityViewStructs and EntityStructs
        ///     - EntityStructs:
        ///     EntityStructs is the preferred way to store entity data. They are just plain structs of pure data (no
        ///     objects)
        ///     - EntityViewStructs:
        ///     EntityViewStructs are used to wrap Objects that come from OOP libraries. You will never use it unless
        ///     you are forced to mix your ECS code with OOP code because of external libraries or platforms.
        ///     The Objects are known to svelto through Component Interfaces.
        ///     - Component Interfaces:
        ///     Components must be seen as data holders. In Svelto.ECS components are always interfaces declaring
        ///     Setters and Getters of Value Types coming from the Objects they wrap
        ///     - Implementors:
        ///     The components interfaces must be implemented through Implementors and the implementors are the
        ///     Objects you need to wrap.
        ///     - EntityDescriptors:
        ///     Gives a way to formalise your Entity, it also defines the EntityStructs and EntityViewStructs that must
        ///     be generated once the Entity is built
        /// </summary>
        void SetupEngines()
        {
            //The Engines Root is the core of Svelto.ECS. You shouldn't inject the EngineRoot,
            //therefore the composition root must hold a reference or it will be GCed.
            //the UnitySumbmissionEntityViewScheduler is the scheduler that is used by the EnginesRoot to know
            //when to submit the entities. Custom ones can be created for special cases.
            _unityEntitySubmissionScheduler = new UnityEntitySubmissionScheduler();
            _enginesRoot = new EnginesRoot(_unityEntitySubmissionScheduler);
            //The EntityFactory can be injected inside factories (or engine acting as factories) to build new entities
            //dynamically
            _entityFactory = _enginesRoot.GenerateEntityFactory();
            //The entity functions is a set of utility operations on Entities, including removing an entity. I couldn't
            //find a better name so far.
            var entityFunctions = _enginesRoot.GenerateEntityFunctions();

            //Sequencers are the official way to guarantee order between engines, but may not be the best way for
            //your product.
            var playerDeathSequence = new PlayerDeathSequencer();
            var enemyDeathSequence  = new EnemyDeathSequencer();

            //wrap non testable unity static classes, so that can be mocked if needed.
            IRayCaster rayCaster = new RayCaster();
            ITime      time      = new Time();

            //Player related engines. ALL the dependencies must be solved at this point through constructor injection.
            var playerShootingEngine  = new PlayerGunShootingEngine(rayCaster, time);
            var playerMovementEngine  = new PlayerMovementEngine(rayCaster, time);
            var playerAnimationEngine = new PlayerAnimationEngine();
            var playerDeathEngine     = new PlayerDeathEngine(playerDeathSequence, entityFunctions);

            //Enemy related engines
            var enemyAnimationEngine = new EnemyAnimationEngine(time, enemyDeathSequence, entityFunctions);
            var enemyAttackEngine    = new EnemyAttackEngine(time);
            var enemyMovementEngine  = new EnemyMovementEngine();

            //GameObjectFactory allows to create GameObjects without using the Static method GameObject.Instantiate.
            //While it seems a complication it's important to keep the engines testable and not coupled with hard
            //dependencies
            var gameObjectFactory = new GameObjectFactory();
            //Factory is one of the few patterns that work very well with ECS. Its use is highly encouraged
            var enemyFactory       = new EnemyFactory(gameObjectFactory, _entityFactory);
            var enemySpawnerEngine = new EnemySpawnerEngine(enemyFactory, entityFunctions);
            var enemyDeathEngine   = new EnemyDeathEngine(entityFunctions, enemyDeathSequence);

            //hud and sound engines
            var hudEngine         = new HUDEngine(time);
            var damageSoundEngine = new DamageSoundEngine();
            var scoreEngine       = new ScoreEngine();

            //The ISequencer implementation is very simple, but allows to perform
            //complex concatenation including loops and conditional branching.
            //These two sequencers are a real stretch and are shown only for explanatory purposes.
            //Please do not see sequencers as a way to dispatch or broadcast events, they are meant only and exclusively
            //to guarantee the order of execution of the involved engines.
            //For this reason the use of sequencers is and must be actually rare, as perfectly encapsulated engines
            //do not need to be executed in specific order.
            //a Sequencer can:
            //- ensure the order of execution through one step only (one step executes in order several engines)
            //- ensure the order of execution through several steps. Each engine inside each step has the responsibility
            //to trigger the next step through the use of the Next() function
            //- create paths with branches and loop using the Condition parameter.
            playerDeathSequence.SetSequence(playerDeathEngine, playerMovementEngine, playerAnimationEngine,
                                            enemyAnimationEngine, damageSoundEngine, hudEngine);

            enemyDeathSequence.SetSequence(enemyDeathEngine, scoreEngine, damageSoundEngine, enemyAnimationEngine,
                                           enemySpawnerEngine);


            //All the logic of the game must lie inside engines
            //Player engines
            _enginesRoot.AddEngine(playerMovementEngine);
            _enginesRoot.AddEngine(playerAnimationEngine);
            _enginesRoot.AddEngine(playerShootingEngine);
            _enginesRoot.AddEngine(new PlayerInputEngine());
            _enginesRoot.AddEngine(new PlayerGunShootingFXsEngine());
            _enginesRoot.AddEngine(playerDeathEngine);
            _enginesRoot.AddEngine(new PlayerSpawnerEngine(gameObjectFactory, _entityFactory));


            //enemy engines
            _enginesRoot.AddEngine(enemySpawnerEngine);
            _enginesRoot.AddEngine(enemyAttackEngine);
            _enginesRoot.AddEngine(enemyMovementEngine);
            _enginesRoot.AddEngine(enemyAnimationEngine);
            _enginesRoot.AddEngine(enemyDeathEngine);
            //other engines
            _enginesRoot.AddEngine(new ApplyingDamageToTargetsEngine());
            _enginesRoot.AddEngine(new CameraFollowTargetEngine(time));
            _enginesRoot.AddEngine(new CharactersDeathEngine());
            _enginesRoot.AddEngine(damageSoundEngine);
            _enginesRoot.AddEngine(hudEngine);
            _enginesRoot.AddEngine(scoreEngine);
        }