#include "engine/core/engine_module_api.hpp" #include #include #include #include #include #include #include #include #include #include std::uint16_t MscEngine::REV = 1; MscEngine::MscEngine(std::vector> modules) { std::unordered_map registry; for (const auto &module : modules) { if (!module) continue; auto [it, inserted] = registry.try_emplace(module->getName(), module->getRev()); if (!inserted) { throw std::runtime_error("Duplicate module detected: " + module->getName()); } } for (const auto &module : modules) { if (!module) continue; for (const auto &[dep_name, range] : module->getDependencies()) { auto it = registry.find(dep_name); if (it == registry.end()) { throw std::runtime_error("Module " + module->getName() + " requires missing module: " + dep_name); } int current_rev = it->second; if (!range.isSatisfied(current_rev)) { throw std::runtime_error( "Module " + module->getName() + " requires " + dep_name + " in range [" + std::to_string(range.minRevision) + " <-> " + std::to_string(range.maxRevision) + "], but got rev" + std::to_string(current_rev)); } } module.get()->onInitialize(*this); } _modules = std::move(modules); } void MscEngine::start() { if (_isRunning) return; _isRunning = true; _lastUpdate = clock::now(); for (auto &m : _modules) m->onStart(*this); constexpr auto tickDuration = std::chrono::milliseconds(50); auto nextTick = clock::now(); using UpdateFn = std::function; std::vector updateFns; updateFns.reserve(_modules.size()); for (auto &m : _modules) updateFns.emplace_back([m](IMscEngineModuleAPI &engine, IMscEngineModuleAPI::clock::duration dt) { m->onUpdate(engine, dt); }); while (_isRunning) { nextTick += tickDuration; const auto currentTick = clock::now(); const auto dt = currentTick - _lastUpdate; // TODO: process for (auto upd : updateFns) upd(*this, dt); _lastUpdate = currentTick; std::this_thread::sleep_until(nextTick); if (clock::now() > nextTick + std::chrono::seconds(1)) nextTick = clock::now(); } for (auto &m : _modules) m->onStop(*this); } void MscEngine::stop() { if (!_isRunning) return; _isRunning = false; } MscEventBus &MscEngine::getBus() { return _bus; } std::unordered_map MscEngine::getLoadedModules() const { std::unordered_map result; for (const auto &module : _modules) { if (!module) continue; auto mod = module.get(); result[mod->getName()] = mod->getRev(); } return result; } std::shared_ptr &MscEngine::getModule(const std::string &name) { for (auto &module : _modules) { if (module.get()->getName() == name) return module; } throw std::runtime_error("Module not found: " + name); } std::unique_ptr MscEngine::createDBProvider() { return std::make_unique(); } std::unique_ptr MscEngine::createDBProvider(const std::string &filepath) { return std::make_unique(filepath); } void MscEngine::requestStop() { this->stop(); // TODO: заменить на флаг }