Program Listing for File engine.hpp

Return to documentation for file (/home/runner/work/Legion-Engine/Legion-Engine/legion/engine/core/engine/engine.hpp)

#pragma once
#include <core/platform/platform.hpp>
#include <core/engine/module.hpp>
#include <core/types/primitives.hpp>
#include <core/types/meta.hpp>
#include <core/ecs/ecsregistry.hpp>
#include <core/scheduling/scheduler.hpp>
#include <core/events/eventbus.hpp>
#include <core/defaults/coremodule.hpp>
#include <core/logging/logging.hpp>
#include <core/ecs/component_handle.hpp>
#include <core/scenemanagement/scenemanager.hpp>

#include <map>
#include <vector>
#include <memory>

namespace legion::core
{
    class Engine
    {
    private:
        std::vector<char*> m_cliargs;
        std::map<priority_type, std::vector<std::unique_ptr<Module>>, std::greater<>> m_modules;

        events::EventBus m_eventbus;
        ecs::EcsRegistry m_ecs;
        scheduling::Scheduler m_scheduler;

    public:

        inline static events::EventBus* eventbus;

        Engine(int argc, char** argv) : m_modules(), m_eventbus(), m_ecs(&m_eventbus), m_cliargs(argv, argv + argc),
#if defined(LEGION_LOW_POWER)
            m_scheduler(&m_eventbus, true, LEGION_MIN_THREADS)
#else
            m_scheduler(&m_eventbus, false, LEGION_MIN_THREADS)
#endif
        {
            log::setup();
            eventbus = &m_eventbus;
            Module::m_eventBus = &m_eventbus;
            Module::m_ecs = &m_ecs;
            Module::m_scheduler = &m_scheduler;
            SystemBase::m_eventBus = &m_eventbus;
            SystemBase::m_ecs = &m_ecs;
            SystemBase::m_scheduler = &m_scheduler;
            ecs::component_handle_base::m_registry = &m_ecs;
            ecs::component_handle_base::m_eventBus = &m_eventbus;
            scenemanagement::SceneManager::m_ecs = &m_ecs;

            reportModule<CoreModule>();
        }

        ~Engine()
        {
            m_modules.clear();
        }

        template <class ModuleType, class... Args CNDOXY(inherits_from<ModuleType, Module> = 0)>
        void reportModule(Args&&...args)
        {
            std::unique_ptr<Module> module = std::make_unique<ModuleType>(std::forward<Args>(args)...);
            module->m_ecs = &m_ecs;
            module->m_scheduler = &m_scheduler;
            module->m_eventBus = &m_eventbus;

            const priority_type priority = module->priority();
            m_modules[priority].emplace_back(std::move(module));
        }

        void init()
        {
            for (const auto& [priority, moduleList] : m_modules)
                for (auto& module : moduleList)
                    module->setup();

            for (const auto& [priority, moduleList] : m_modules)
                for (auto& module : moduleList)
                    module->init();
        }

        void run()
        {
            m_scheduler.run();
        }

        std::vector<char*>& getCliArgs() {
            return m_cliargs;
        }

    };
}