mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-04-08 05:42:59 +02:00
reworked the general update strategy interface
This commit is contained in:
parent
b8a5cd7cf4
commit
efad254193
@ -15,11 +15,11 @@ add_subdirectory(organizer_scene)
|
|||||||
if(NOT MM_HEADLESS)
|
if(NOT MM_HEADLESS)
|
||||||
add_subdirectory(sdl_service)
|
add_subdirectory(sdl_service)
|
||||||
add_subdirectory(simple_sdl_renderer)
|
add_subdirectory(simple_sdl_renderer)
|
||||||
add_subdirectory(opengl_renderer)
|
|
||||||
add_subdirectory(opengl_primitives)
|
add_subdirectory(opengl_primitives)
|
||||||
|
add_subdirectory(opengl_renderer)
|
||||||
|
add_subdirectory(imgui)
|
||||||
add_subdirectory(input)
|
add_subdirectory(input)
|
||||||
add_subdirectory(sound)
|
add_subdirectory(sound)
|
||||||
add_subdirectory(imgui)
|
|
||||||
add_subdirectory(tilemap)
|
add_subdirectory(tilemap)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -7,13 +7,12 @@ add_library(engine
|
|||||||
src/mm/engine.cpp
|
src/mm/engine.cpp
|
||||||
|
|
||||||
src/mm/update_strategies/update_strategy.hpp
|
src/mm/update_strategies/update_strategy.hpp
|
||||||
|
src/mm/update_strategies/dummy.hpp
|
||||||
|
|
||||||
src/mm/services/service.hpp
|
src/mm/services/service.hpp
|
||||||
|
|
||||||
src/mm/update_strategies/dependency_check_decorater.hpp
|
src/mm/update_strategies/sequential_strategy.hpp
|
||||||
|
src/mm/update_strategies/sequential_strategy.cpp
|
||||||
src/mm/update_strategies/default_strategy.hpp
|
|
||||||
src/mm/update_strategies/default_strategy.cpp
|
|
||||||
|
|
||||||
src/mm/services/scene_service_interface.hpp
|
src/mm/services/scene_service_interface.hpp
|
||||||
src/mm/services/scene_service_interface.cpp
|
src/mm/services/scene_service_interface.cpp
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "./engine.hpp"
|
#include "./engine.hpp"
|
||||||
|
|
||||||
#include <mm/update_strategies/default_strategy.hpp>
|
#include <mm/update_strategies/sequential_strategy.hpp>
|
||||||
|
#include <mm/update_strategies/dummy.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -29,8 +30,10 @@ void Engine::setup(void) {
|
|||||||
Engine::Engine(void) {
|
Engine::Engine(void) {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
_update_strategy = std::make_unique<MM::UpdateStrategies::SingleThreadedDefault>();
|
_update_strategy = std::make_unique<MM::UpdateStrategies::Sequential>();
|
||||||
LOG_INFO("defaulting to SingleThreadedDefault UpdateStrategy");
|
LOG_INFO("defaulting to Sequential (single threaded) UpdateStrategy");
|
||||||
|
//_update_strategy = std::make_unique<MM::UpdateStrategies::Dummy>();
|
||||||
|
//LOG_WARN("Dummy UpdateStrategy [TESTING]");
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::~Engine(void) {
|
Engine::~Engine(void) {
|
||||||
@ -59,48 +62,12 @@ void Engine::cleanup(void) {
|
|||||||
|
|
||||||
void Engine::update(void) {
|
void Engine::update(void) {
|
||||||
FrameMarkStart("update")
|
FrameMarkStart("update")
|
||||||
//if (_update_functions_modified) {
|
|
||||||
//ZoneScopedN("MM::Engine::update::sort_update_functions")
|
|
||||||
//std::sort(_update_functions.begin(), _update_functions.end(), [](const auto& a, const auto& b) { return a->priority > b->priority; });
|
|
||||||
//_update_functions_modified = false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{
|
|
||||||
//ZoneScopedN("MM::Engine::update::traverseUpdateFunctions")
|
|
||||||
//traverseUpdateFunctions(_update_functions);
|
|
||||||
//}
|
|
||||||
|
|
||||||
_update_strategy->doUpdate(*this);
|
_update_strategy->doUpdate(*this);
|
||||||
|
|
||||||
FrameMarkEnd("update")
|
FrameMarkEnd("update")
|
||||||
}
|
}
|
||||||
|
|
||||||
//void Engine::fixedUpdate(void) {
|
|
||||||
//FrameMarkStart("fixedUpdate")
|
|
||||||
////if (_fixed_update_functions_modified) {
|
|
||||||
////ZoneScopedN("MM::Engine::fixedUpdate::sort_update_functions")
|
|
||||||
|
|
||||||
////std::sort(_fixed_update_functions.begin(), _fixed_update_functions.end(), [](const auto& a, const auto& b) { return a->priority > b->priority; });
|
|
||||||
////_fixed_update_functions_modified = false;
|
|
||||||
////}
|
|
||||||
|
|
||||||
////{
|
|
||||||
////ZoneScopedN("MM::Engine::fixedUpdate::traverseUpdateFunctions")
|
|
||||||
////traverseUpdateFunctions(_fixed_update_functions);
|
|
||||||
////}
|
|
||||||
|
|
||||||
////if (!_fixed_defered.empty()) {
|
|
||||||
////ZoneScopedN("MM::Engine::fixedUpdate::defered")
|
|
||||||
////for (auto& fn : _fixed_defered) {
|
|
||||||
////fn(*this);
|
|
||||||
////}
|
|
||||||
|
|
||||||
////_fixed_defered.clear();
|
|
||||||
////}
|
|
||||||
|
|
||||||
//FrameMarkEnd("fixedUpdate")
|
|
||||||
//}
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
|
|
||||||
@ -136,14 +103,20 @@ bool Engine::enableService(entt::id_type s_t) {
|
|||||||
|
|
||||||
_service_enable_order.emplace_back(s_t); // TODO: make sure
|
_service_enable_order.emplace_back(s_t); // TODO: make sure
|
||||||
|
|
||||||
ss_entry->first = ss_entry->second.get()->enable(*this);
|
{ // tasking
|
||||||
|
std::vector<UpdateStrategies::TaskInfo> task_array;
|
||||||
|
|
||||||
_update_strategy->enableService(s_t); // after service::enable()
|
ss_entry->first = ss_entry->second.get()->enable(*this, task_array);
|
||||||
|
if (ss_entry->first) {
|
||||||
|
_update_strategy->enableService(s_t, std::move(task_array));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ss_entry->first;
|
return ss_entry->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not found
|
// not found
|
||||||
|
// TODO: improve this
|
||||||
assert(false && "first add Service");
|
assert(false && "first add Service");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -158,7 +131,6 @@ void Engine::disableService(entt::id_type s_t) {
|
|||||||
s_entry->first = false;
|
s_entry->first = false;
|
||||||
|
|
||||||
s_entry->second.get()->disable(*this);
|
s_entry->second.get()->disable(*this);
|
||||||
//_service_enable_order.emplace_back(service_family::type<T>);
|
|
||||||
auto it = std::find(_service_enable_order.begin(), _service_enable_order.end(), s_t);
|
auto it = std::find(_service_enable_order.begin(), _service_enable_order.end(), s_t);
|
||||||
if (it != _service_enable_order.end()) {
|
if (it != _service_enable_order.end()) {
|
||||||
_service_enable_order.erase(it);
|
_service_enable_order.erase(it);
|
||||||
@ -170,6 +142,7 @@ void Engine::disableService(entt::id_type s_t) {
|
|||||||
bool Engine::provide(entt::id_type I, entt::id_type T) {
|
bool Engine::provide(entt::id_type I, entt::id_type T) {
|
||||||
if (!_services.count(T)) {
|
if (!_services.count(T)) {
|
||||||
// TODO: log error
|
// TODO: log error
|
||||||
|
assert(false && "cant provide something that does not exist!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,44 +26,21 @@ namespace Services {
|
|||||||
class Engine {
|
class Engine {
|
||||||
friend Services::ImGuiEngineTools;
|
friend Services::ImGuiEngineTools;
|
||||||
|
|
||||||
private:
|
|
||||||
//using service_family = entt::family<struct internal_service_family>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//using service_family_type = service_family::family_type;
|
using service_id_type = entt::id_type; // alias, for future proof
|
||||||
|
|
||||||
|
// UpdateStrategy
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<UpdateStrategies::UpdateStrategy> _update_strategy;
|
std::unique_ptr<UpdateStrategies::UpdateStrategy> _update_strategy;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpdateStrategies::UpdateStrategy& getUpdateStrategy(void) { return *_update_strategy; }
|
UpdateStrategies::UpdateStrategy& getUpdateStrategy(void) { return *_update_strategy; }
|
||||||
|
|
||||||
|
// state
|
||||||
private:
|
private:
|
||||||
volatile bool _is_running = false;
|
volatile bool _is_running = false;
|
||||||
|
// ... just realisied: i never needed a getter ...
|
||||||
|
|
||||||
private:
|
|
||||||
void setup(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Engine(void);
|
|
||||||
|
|
||||||
explicit Engine(std::unique_ptr<UpdateStrategies::UpdateStrategy> us) {
|
|
||||||
setup();
|
|
||||||
_update_strategy = std::move(us);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
~Engine(void);
|
|
||||||
|
|
||||||
// called from destructor or explicitly
|
|
||||||
void cleanup(void);
|
|
||||||
|
|
||||||
void update(void);
|
|
||||||
|
|
||||||
void run(void); // calls update() until stopped
|
|
||||||
void stop(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<entt::id_type> _service_add_order; // ?
|
std::vector<entt::id_type> _service_add_order; // ?
|
||||||
std::vector<entt::id_type> _service_enable_order; // ?
|
std::vector<entt::id_type> _service_enable_order; // ?
|
||||||
|
|
||||||
@ -75,6 +52,29 @@ class Engine {
|
|||||||
>>
|
>>
|
||||||
> _services;
|
> _services;
|
||||||
|
|
||||||
|
|
||||||
|
// private state helper
|
||||||
|
private:
|
||||||
|
void setup(void);
|
||||||
|
|
||||||
|
// ctr dtr ...
|
||||||
|
public:
|
||||||
|
Engine(void);
|
||||||
|
~Engine(void);
|
||||||
|
|
||||||
|
explicit Engine(std::unique_ptr<UpdateStrategies::UpdateStrategy> us) {
|
||||||
|
setup();
|
||||||
|
_update_strategy = std::move(us);
|
||||||
|
}
|
||||||
|
|
||||||
|
// called from destructor or explicitly (if eg "global", u need dis)
|
||||||
|
void cleanup(void);
|
||||||
|
|
||||||
|
void update(void);
|
||||||
|
|
||||||
|
void run(void); // calls update() until stopped
|
||||||
|
void stop(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr static auto type(void) {
|
constexpr static auto type(void) {
|
||||||
@ -96,12 +96,6 @@ class Engine {
|
|||||||
|
|
||||||
_service_add_order.emplace_back(type<T>());
|
_service_add_order.emplace_back(type<T>());
|
||||||
|
|
||||||
// add updates to update strategy
|
|
||||||
_update_strategy->registerService(
|
|
||||||
type<T>(),
|
|
||||||
ss_entry.get()->second->registerUpdates()
|
|
||||||
);
|
|
||||||
|
|
||||||
return (T&)*ss_entry.get()->second.get();
|
return (T&)*ss_entry.get()->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,13 +148,8 @@ class Engine {
|
|||||||
return provide(type<I>(), type<T>());
|
return provide(type<I>(), type<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: reimplement???
|
// TODO: remove service
|
||||||
//template<typename I>
|
|
||||||
//void removeProvider(void) {
|
//void removeProvider(void) {
|
||||||
//if (auto it = _implementation_provider.find(service_family::type<I>); it != _implementation_provider.end()) {
|
|
||||||
//_implementation_provider.erase(it);
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM
|
} // MM
|
||||||
|
@ -11,9 +11,11 @@ namespace MM {
|
|||||||
using System = std::function<void(::MM::Scene&, float)>;
|
using System = std::function<void(::MM::Scene&, float)>;
|
||||||
|
|
||||||
// opaque way to add a System to a Scene
|
// opaque way to add a System to a Scene
|
||||||
|
[[deprecated("use organizer")]]
|
||||||
void AddSystemToScene(::MM::Scene& scene, ::MM::System fn);
|
void AddSystemToScene(::MM::Scene& scene, ::MM::System fn);
|
||||||
|
|
||||||
// opaque way to iterate over the Systems
|
// opaque way to iterate over the Systems
|
||||||
|
[[deprecated("use organizer")]]
|
||||||
void EachSystemInScene(::MM::Scene& scene, std::function<void(::MM::Scene&, ::MM::System&)> fn);
|
void EachSystemInScene(::MM::Scene& scene, std::function<void(::MM::Scene&, ::MM::System&)> fn);
|
||||||
|
|
||||||
} // MM
|
} // MM
|
||||||
@ -35,7 +37,7 @@ namespace MM::Services {
|
|||||||
|
|
||||||
// adds a System to current Scene.
|
// adds a System to current Scene.
|
||||||
// default impl. will use getScene() !
|
// default impl. will use getScene() !
|
||||||
inline virtual void addSystemToScene(::MM::System fn) {
|
virtual void addSystemToScene(::MM::System fn) {
|
||||||
::MM::AddSystemToScene(getScene(), std::move(fn));
|
::MM::AddSystemToScene(getScene(), std::move(fn));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ namespace MM {
|
|||||||
|
|
||||||
class Engine;
|
class Engine;
|
||||||
namespace UpdateStrategies {
|
namespace UpdateStrategies {
|
||||||
struct UpdateCreationInfo;
|
struct TaskInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Services {
|
namespace Services {
|
||||||
@ -17,14 +17,12 @@ namespace MM {
|
|||||||
|
|
||||||
virtual const char* name(void) = 0;
|
virtual const char* name(void) = 0;
|
||||||
|
|
||||||
virtual bool enable(Engine& engine) = 0;
|
// tasks are to be filled in by the service impl
|
||||||
|
virtual bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) = 0;
|
||||||
virtual void disable(Engine& engine) = 0;
|
virtual void disable(Engine& engine) = 0;
|
||||||
|
|
||||||
// optional, only if service actually needs to be part of the update loop
|
|
||||||
virtual std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) { return {}; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Services
|
} // Services
|
||||||
|
|
||||||
} //MM
|
} // MM
|
||||||
|
|
||||||
|
@ -1,236 +0,0 @@
|
|||||||
#include "./default_strategy.hpp"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
namespace MM::UpdateStrategies {
|
|
||||||
|
|
||||||
#define __L_ASSERT(cond) if (!(cond)) { return false; }
|
|
||||||
|
|
||||||
SingleThreadedDefault::Graph& SingleThreadedDefault::getGraph(update_phase_t type) {
|
|
||||||
using type_t = update_phase_t;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case type_t::PRE:
|
|
||||||
return _pre_graph;
|
|
||||||
case type_t::MAIN:
|
|
||||||
return _main_graph;
|
|
||||||
case type_t::POST:
|
|
||||||
return _post_graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _main_graph; // unreachable
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<update_key_t>& SingleThreadedDefault::getActiveSet(update_phase_t type) {
|
|
||||||
using type_t = update_phase_t;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case type_t::PRE:
|
|
||||||
return _pre_active;
|
|
||||||
case type_t::MAIN:
|
|
||||||
return _main_active;
|
|
||||||
case type_t::POST:
|
|
||||||
return _post_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _main_active; // unreachable
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleThreadedDefault::runType(MM::Engine& engine, update_phase_t type) {
|
|
||||||
auto aset = getActiveSet(type); // copy
|
|
||||||
const auto& graph = getGraph(type);
|
|
||||||
|
|
||||||
while (!aset.empty()) {
|
|
||||||
for (const auto key : aset) {
|
|
||||||
// check if dependencies are resolved (or dont exist)
|
|
||||||
bool resolved = true;
|
|
||||||
for (const auto deps : graph.at(key)) {
|
|
||||||
if (aset.count(deps)) {
|
|
||||||
resolved = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolved) {
|
|
||||||
// do task
|
|
||||||
_tasks[key].fn(engine);
|
|
||||||
|
|
||||||
// delete task from set
|
|
||||||
aset.erase(key);
|
|
||||||
|
|
||||||
break; // this might be optional but makes the delete easy
|
|
||||||
} else {
|
|
||||||
// continue the for / dont do anything with this task yet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SingleThreadedDefault::~SingleThreadedDefault(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::registerService(const entt::id_type s_id, std::vector<UpdateCreationInfo>&& info_array) {
|
|
||||||
__L_ASSERT(_service_tasks.count(s_id) == 0);
|
|
||||||
|
|
||||||
// early out
|
|
||||||
if (info_array.empty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& service_tasks = _service_tasks[s_id];
|
|
||||||
|
|
||||||
for (const UpdateCreationInfo& reg_e : info_array) {
|
|
||||||
// test if already exists
|
|
||||||
__L_ASSERT(_tasks.count(reg_e.key) == 0);
|
|
||||||
// also the graphs
|
|
||||||
__L_ASSERT(_pre_graph.count(reg_e.key) == 0);
|
|
||||||
__L_ASSERT(_main_graph.count(reg_e.key) == 0);
|
|
||||||
__L_ASSERT(_post_graph.count(reg_e.key) == 0);
|
|
||||||
|
|
||||||
// also the enabled taks
|
|
||||||
__L_ASSERT(_pre_active.count(reg_e.key) == 0);
|
|
||||||
__L_ASSERT(_main_active.count(reg_e.key) == 0);
|
|
||||||
__L_ASSERT(_post_active.count(reg_e.key) == 0);
|
|
||||||
|
|
||||||
// potentially check for cicles (can be done by provided decorator)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const UpdateCreationInfo& reg_e : info_array) {
|
|
||||||
// add to tasks
|
|
||||||
{
|
|
||||||
auto& new_task = _tasks[reg_e.key];
|
|
||||||
new_task.name = reg_e.name;
|
|
||||||
new_task.fn = reg_e.fn;
|
|
||||||
new_task.phase = reg_e.phase;
|
|
||||||
new_task.auto_enable = reg_e.auto_enable;
|
|
||||||
|
|
||||||
new_task.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add relation to service
|
|
||||||
service_tasks.emplace_back(reg_e.key);
|
|
||||||
|
|
||||||
// fill in dependencies
|
|
||||||
auto& graph = getGraph(reg_e.phase);
|
|
||||||
graph[reg_e.key].insert(reg_e.dependencies.begin(), reg_e.dependencies.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::enable(const update_key_t key) {
|
|
||||||
__L_ASSERT(_tasks.count(key) == 1);
|
|
||||||
__L_ASSERT(_tasks[key].enabled == false);
|
|
||||||
|
|
||||||
auto ret = getActiveSet(_tasks[key].phase).emplace(key);
|
|
||||||
_tasks[key].enabled = true;
|
|
||||||
|
|
||||||
return ret.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::disable(const update_key_t key) {
|
|
||||||
__L_ASSERT(_tasks.count(key) == 1);
|
|
||||||
__L_ASSERT(_tasks[key].enabled == true);
|
|
||||||
|
|
||||||
auto& aset = getActiveSet(_tasks[key].phase);
|
|
||||||
|
|
||||||
__L_ASSERT(aset.count(key) == 1);
|
|
||||||
|
|
||||||
aset.erase(key);
|
|
||||||
|
|
||||||
_tasks[key].enabled = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::enableService(const entt::id_type s_id) {
|
|
||||||
bool succ = true;
|
|
||||||
for (const auto id : _service_tasks[s_id]) {
|
|
||||||
auto& task = _tasks[id];
|
|
||||||
|
|
||||||
// there should be no task running, if the service is no enabled!!
|
|
||||||
assert(!task.enabled);
|
|
||||||
|
|
||||||
if (task.auto_enable) {
|
|
||||||
succ &= enable(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return succ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::disableService(const entt::id_type s_id) {
|
|
||||||
bool succ = true;
|
|
||||||
for (const auto id : _service_tasks[s_id]) {
|
|
||||||
auto& task = _tasks[id];
|
|
||||||
|
|
||||||
if (task.auto_enable) {
|
|
||||||
assert(task.enabled); // this should never happen
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task.enabled) {
|
|
||||||
succ &= disable(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return succ;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SingleThreadedDefault::depend(const update_key_t A, const update_key_t B) {
|
|
||||||
// TODO: error checking lol
|
|
||||||
|
|
||||||
if (_tasks.count(A) == 0) {
|
|
||||||
return false; // can not add a dependecy of a non existing task
|
|
||||||
// TODO: or do we?
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_tasks.count(B) == 1) {
|
|
||||||
if (_tasks[A].phase != _tasks[B].phase) {
|
|
||||||
// cross graph tasks are not allowed
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& graph = getGraph(_tasks[A].phase);
|
|
||||||
auto ret = graph[A].emplace(B);
|
|
||||||
return ret.second; // returns whether it was inserted (or already existed)
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleThreadedDefault::doUpdate(MM::Engine& engine) {
|
|
||||||
// pre
|
|
||||||
runType(engine, update_phase_t::PRE);
|
|
||||||
|
|
||||||
// main
|
|
||||||
runType(engine, update_phase_t::MAIN);
|
|
||||||
|
|
||||||
// post
|
|
||||||
runType(engine, update_phase_t::POST);
|
|
||||||
|
|
||||||
// simulate async
|
|
||||||
for (size_t i = 0; !_async_queue.empty() && i < _max_async_per_tick; i++) {
|
|
||||||
_async_queue.back()(engine);
|
|
||||||
_async_queue.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_deferred_queue.empty()) {
|
|
||||||
for (auto&& fn : _deferred_queue) {
|
|
||||||
fn(engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
_deferred_queue.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleThreadedDefault::addDeferred(std::function<void(Engine&)> function) {
|
|
||||||
_deferred_queue.emplace_back(std::move(function));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SingleThreadedDefault::addAsync(std::function<void(Engine&)> function) {
|
|
||||||
_async_queue.emplace_back(std::move(function));
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef __L_ASSERT
|
|
||||||
|
|
||||||
} // MM::UpdateStrategies
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "./update_strategy.hpp"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
// fwd
|
|
||||||
namespace MM::Services {
|
|
||||||
class ImGuiEngineTools;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MM::UpdateStrategies {
|
|
||||||
|
|
||||||
class SingleThreadedDefault : public MM::UpdateStrategies::UpdateStrategy {
|
|
||||||
friend MM::Services::ImGuiEngineTools;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Task {
|
|
||||||
std::string name;
|
|
||||||
std::function<void(Engine&)> fn;
|
|
||||||
update_phase_t phase;
|
|
||||||
bool auto_enable;
|
|
||||||
|
|
||||||
bool enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<update_key_t, Task> _tasks;
|
|
||||||
|
|
||||||
// the tasks a service has registered
|
|
||||||
std::unordered_map<entt::id_type, std::vector<update_key_t>> _service_tasks;
|
|
||||||
|
|
||||||
// tasks dependencies
|
|
||||||
using Graph = std::unordered_map<update_key_t, std::set<update_key_t>>;
|
|
||||||
// TODO: do vector for perf?
|
|
||||||
|
|
||||||
Graph _pre_graph;
|
|
||||||
Graph _main_graph;
|
|
||||||
Graph _post_graph;
|
|
||||||
|
|
||||||
std::set<update_key_t> _pre_active;
|
|
||||||
std::set<update_key_t> _main_active;
|
|
||||||
std::set<update_key_t> _post_active;
|
|
||||||
|
|
||||||
std::vector<std::function<void(Engine&)>> _deferred_queue;
|
|
||||||
std::vector<std::function<void(Engine&)>> _async_queue;
|
|
||||||
const size_t _max_async_per_tick = 5; // prevent blocking, this should be finetuned
|
|
||||||
|
|
||||||
private:
|
|
||||||
Graph& getGraph(update_phase_t phase);
|
|
||||||
std::set<update_key_t>& getActiveSet(update_phase_t phase);
|
|
||||||
|
|
||||||
void runType(MM::Engine& engine, update_phase_t phase);
|
|
||||||
|
|
||||||
public:
|
|
||||||
SingleThreadedDefault(void) = default;
|
|
||||||
virtual ~SingleThreadedDefault(void);
|
|
||||||
|
|
||||||
const char* name(void) override { return "SingleThreadedDefault"; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool registerService(const entt::id_type s_id, std::vector<UpdateCreationInfo>&& info_array) override;
|
|
||||||
|
|
||||||
bool enableService(const entt::id_type s_id) override;
|
|
||||||
bool disableService(const entt::id_type s_id) override;
|
|
||||||
|
|
||||||
void doUpdate(MM::Engine& engine) override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool enable(const update_key_t key) override;
|
|
||||||
bool disable(const update_key_t key) override;
|
|
||||||
|
|
||||||
bool depend(const update_key_t A, const update_key_t B) override;
|
|
||||||
|
|
||||||
void addDeferred(std::function<void(Engine&)> function) override;
|
|
||||||
|
|
||||||
void addAsync(std::function<void(Engine&)> function) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // MM::UpdateStrategies
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "./update_strategy.hpp"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace MM::UpdateStrategies {
|
|
||||||
|
|
||||||
// checks for cyles
|
|
||||||
template<class T>
|
|
||||||
class DependencyCheckDecorator : public T {
|
|
||||||
static_assert(std::is_base_of_v<UpdateStrategy, T>);
|
|
||||||
|
|
||||||
public:
|
|
||||||
//DependencyCheckDecorator(void) = default;
|
|
||||||
|
|
||||||
//template<typename ...Args>
|
|
||||||
//DependencyCheckDecorator(Args... args) : T(args) {
|
|
||||||
//}
|
|
||||||
|
|
||||||
virtual ~DependencyCheckDecorator(void) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void doUpdate(MM::Engine& engine) override {
|
|
||||||
T::doUpdate(engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool registerService(const entt::id_type s_id, std::vector<UpdateCreationInfo>&& info_array) override {
|
|
||||||
return T::registerService(s_id, std::move(info_array));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enableService(const entt::id_type s_id) override {
|
|
||||||
return T::enableService(s_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool disableService(const entt::id_type s_id) override {
|
|
||||||
return T::disableService(s_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool enable(const update_key_t key) override {
|
|
||||||
return T::enable(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool disable(const update_key_t key) override {
|
|
||||||
return T::disable(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool depend(const update_key_t A, const update_key_t B) override {
|
|
||||||
return T::depend(A, B);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // MM::UpdateStrategies
|
|
||||||
|
|
28
framework/engine/src/mm/update_strategies/dummy.hpp
Normal file
28
framework/engine/src/mm/update_strategies/dummy.hpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "./update_strategy.hpp"
|
||||||
|
|
||||||
|
// Rezz x Deadmau5 - hypnocurrency
|
||||||
|
|
||||||
|
namespace MM::UpdateStrategies {
|
||||||
|
|
||||||
|
// does nothing, even less then a mock class
|
||||||
|
// for testing only!
|
||||||
|
class Dummy : public UpdateStrategy {
|
||||||
|
public:
|
||||||
|
~Dummy(void) {}
|
||||||
|
|
||||||
|
const char* name(void) override { return "Dummy"; }
|
||||||
|
|
||||||
|
protected: // the engine facing interface
|
||||||
|
bool enableService(const entt::id_type, std::vector<TaskInfo>&&) override { return true; }
|
||||||
|
bool disableService(const entt::id_type) override { return true; }
|
||||||
|
void doUpdate(MM::Engine&) override {}
|
||||||
|
|
||||||
|
public: // the user facing interface
|
||||||
|
void addDeferred(std::function<void(Engine&)>) override {}
|
||||||
|
void addAsync(std::function<void(Engine&)>) override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // MM::UpdateStrategies
|
||||||
|
|
@ -0,0 +1,126 @@
|
|||||||
|
#include "./sequential_strategy.hpp"
|
||||||
|
|
||||||
|
#include "./tasking_utils.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <tracy/Tracy.hpp>
|
||||||
|
|
||||||
|
namespace MM::UpdateStrategies {
|
||||||
|
|
||||||
|
//#define __L_ASSERT(cond) if (!(cond)) { return false; }
|
||||||
|
void Sequential::doGraphSequential(MM::Engine& engine, const std::set<update_key_t>& tasks) {
|
||||||
|
Graph graph = build_task_graph(tasks,
|
||||||
|
[this](update_key_t key) -> const TaskInfo& {
|
||||||
|
return _tasks.at(key);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
walk_graph_sequential(graph, [this, &engine](update_key_t task_id ) {
|
||||||
|
_tasks.at(task_id)._fn(engine);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Sequential::~Sequential(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sequential::enableService(const entt::id_type service_id, std::vector<TaskInfo>&& task_array) {
|
||||||
|
if (_service_tasks.count(service_id)) {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& service = _service_tasks[service_id];
|
||||||
|
|
||||||
|
for (const auto& task : task_array) {
|
||||||
|
_tasks.emplace(task._key, task);
|
||||||
|
service.emplace(task._key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sequential::disableService(const entt::id_type service_id) {
|
||||||
|
if (!_service_tasks.count(service_id)) {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto task_id : _service_tasks[service_id]) {
|
||||||
|
_tasks.erase(task_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
_service_tasks.erase(service_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequential::doUpdate(MM::Engine& engine) {
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate")
|
||||||
|
// TODO: caching
|
||||||
|
std::set<update_key_t> pre_tasks;
|
||||||
|
std::set<update_key_t> main_tasks;
|
||||||
|
std::set<update_key_t> post_tasks;
|
||||||
|
|
||||||
|
for (const auto& [task_id, task] : _tasks) {
|
||||||
|
switch (task._phase) {
|
||||||
|
case update_phase_t::PRE:
|
||||||
|
pre_tasks.emplace(task_id);
|
||||||
|
break;
|
||||||
|
case update_phase_t::MAIN:
|
||||||
|
main_tasks.emplace(task_id);
|
||||||
|
break;
|
||||||
|
case update_phase_t::POST:
|
||||||
|
post_tasks.emplace(task_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // pre
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate::pre")
|
||||||
|
doGraphSequential(engine, pre_tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // main
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate::main")
|
||||||
|
doGraphSequential(engine, main_tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // post
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate::post")
|
||||||
|
doGraphSequential(engine, post_tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // simulate async
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate::async")
|
||||||
|
for (size_t i = 0; !_async_queue.empty() && i < _max_async_per_tick; i++) {
|
||||||
|
_async_queue.back()(engine);
|
||||||
|
_async_queue.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ZoneScopedN("MM::UpdateStrategies::Sequential::doUpdate::deferred")
|
||||||
|
if (!_deferred_queue.empty()) {
|
||||||
|
for (auto&& fn : _deferred_queue) {
|
||||||
|
fn(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
_deferred_queue.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequential::addDeferred(std::function<void(Engine&)> function) {
|
||||||
|
_deferred_queue.emplace_back(std::move(function));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequential::addAsync(std::function<void(Engine&)> function) {
|
||||||
|
_async_queue.emplace_back(std::move(function));
|
||||||
|
}
|
||||||
|
|
||||||
|
//#undef __L_ASSERT
|
||||||
|
|
||||||
|
} // MM::UpdateStrategies
|
||||||
|
|
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "./update_strategy.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
// HACK: welp
|
||||||
|
// fwd
|
||||||
|
namespace MM::Services {
|
||||||
|
class ImGuiEngineTools;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MM::UpdateStrategies {
|
||||||
|
|
||||||
|
class Sequential : public MM::UpdateStrategies::UpdateStrategy {
|
||||||
|
friend MM::Services::ImGuiEngineTools;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<update_key_t, TaskInfo> _tasks;
|
||||||
|
|
||||||
|
// the tasks a service has registered
|
||||||
|
std::unordered_map<entt::id_type, std::set<update_key_t>> _service_tasks;
|
||||||
|
|
||||||
|
std::vector<std::function<void(Engine&)>> _deferred_queue;
|
||||||
|
std::vector<std::function<void(Engine&)>> _async_queue;
|
||||||
|
|
||||||
|
private: // utils
|
||||||
|
void doGraphSequential(MM::Engine& engine, const std::set<update_key_t>& tasks);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Sequential(void) = default;
|
||||||
|
virtual ~Sequential(void);
|
||||||
|
|
||||||
|
const char* name(void) override { return "Sequential"; }
|
||||||
|
|
||||||
|
protected: // engine facing interface
|
||||||
|
bool enableService(const entt::id_type s_id, std::vector<TaskInfo>&& task_array) override;
|
||||||
|
bool disableService(const entt::id_type s_id) override;
|
||||||
|
|
||||||
|
void doUpdate(MM::Engine& engine) override;
|
||||||
|
|
||||||
|
public: // user facing interface
|
||||||
|
void addDeferred(std::function<void(Engine&)> function) override;
|
||||||
|
|
||||||
|
void addAsync(std::function<void(Engine&)> function) override;
|
||||||
|
|
||||||
|
size_t _max_async_per_tick = 5; // prevent blocking, this should be finetuned
|
||||||
|
|
||||||
|
protected: // engine tools interface
|
||||||
|
void forEachTask(std::function<bool(TaskInfo&)> fn) override {
|
||||||
|
for (auto&& t : _tasks) {
|
||||||
|
if (!fn(t.second)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // MM::UpdateStrategies
|
||||||
|
|
73
framework/engine/src/mm/update_strategies/tasking_utils.hpp
Normal file
73
framework/engine/src/mm/update_strategies/tasking_utils.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mm/update_strategies/update_strategy.hpp>
|
||||||
|
|
||||||
|
namespace MM::UpdateStrategies {
|
||||||
|
|
||||||
|
// all tasks and it dependencies
|
||||||
|
using Graph = std::unordered_map<update_key_t, std::set<update_key_t>>;
|
||||||
|
|
||||||
|
template<typename FN>
|
||||||
|
void walk_graph_sequential(const Graph& graph, FN&& fn) {
|
||||||
|
// set of all tasks, each completed task will be removed from this until none are left
|
||||||
|
std::set<update_key_t> unworked_node_set{};
|
||||||
|
for (auto it = graph.begin(); it != graph.end(); it++) {
|
||||||
|
unworked_node_set.emplace(it->first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check for inf-loops
|
||||||
|
while (!unworked_node_set.empty()) {
|
||||||
|
for (auto node_it = unworked_node_set.begin(); node_it != unworked_node_set.end();) {
|
||||||
|
// check if deps are resolved
|
||||||
|
bool resolved = true;
|
||||||
|
for (const auto dep : graph.at(*node_it)) {
|
||||||
|
if (unworked_node_set.count(dep)) {
|
||||||
|
resolved = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolved) {
|
||||||
|
// to task
|
||||||
|
fn(*node_it);
|
||||||
|
|
||||||
|
node_it = unworked_node_set.erase(node_it);
|
||||||
|
} else {
|
||||||
|
node_it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TaskGet>
|
||||||
|
Graph build_task_graph(const std::set<update_key_t>& tasks, TaskGet&& task_get) {
|
||||||
|
Graph graph;
|
||||||
|
|
||||||
|
// phase 1: create all tasks
|
||||||
|
for (const auto task_id : tasks) {
|
||||||
|
graph[task_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
// phase 2: do all dependencies (and dependents)
|
||||||
|
for (const auto task_id : tasks) {
|
||||||
|
auto& graph_node = graph[task_id];
|
||||||
|
|
||||||
|
{ // dependencies
|
||||||
|
//graph_node.merge(task_get(task_id)._dependencies);
|
||||||
|
const auto& dependencies = task_get(task_id)._dependencies;
|
||||||
|
graph_node.insert(dependencies.cbegin(), dependencies.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
// dependents
|
||||||
|
for (const auto dependent : task_get(task_id)._dependents) {
|
||||||
|
if (graph.count(dependent)) {
|
||||||
|
graph[dependent].emplace(task_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MM::UpdateStrategies
|
||||||
|
|
@ -2,37 +2,89 @@
|
|||||||
|
|
||||||
#include "../engine_fwd.hpp"
|
#include "../engine_fwd.hpp"
|
||||||
|
|
||||||
|
#include <entt/core/hashed_string.hpp>
|
||||||
|
|
||||||
#include <mm/services/service.hpp>
|
#include <mm/services/service.hpp>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
// fwd / hack
|
||||||
|
namespace MM::Services {
|
||||||
|
class ImGuiEngineTools;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MM::UpdateStrategies {
|
namespace MM::UpdateStrategies {
|
||||||
|
|
||||||
using update_key_t = entt::id_type;
|
using update_key_t = entt::id_type;
|
||||||
|
|
||||||
enum class update_phase_t {
|
enum update_phase_t {
|
||||||
PRE, // for on-main-thread
|
PRE = 0, // for on-main-thread
|
||||||
MAIN,
|
MAIN,
|
||||||
POST // for on-main-thread
|
POST // for on-main-thread
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UpdateCreationInfo {
|
struct TaskInfo {
|
||||||
update_key_t key; // key for dependencies
|
update_key_t _key; // key for dependencies
|
||||||
|
std::string _name; // unhashed key
|
||||||
|
|
||||||
std::string name; // for debugging
|
update_phase_t _phase = update_phase_t::MAIN;
|
||||||
|
|
||||||
std::function<void(Engine&)> fn; // the actual payload
|
// updates we make dependents
|
||||||
|
std::set<update_key_t> _dependents {};
|
||||||
update_phase_t phase = update_phase_t::MAIN;
|
|
||||||
|
|
||||||
bool auto_enable = true; // whether this update is enabled with the service
|
|
||||||
|
|
||||||
// this update also depends on (in the same phase)
|
// this update also depends on (in the same phase)
|
||||||
std::vector<update_key_t> dependencies {};
|
std::set<update_key_t> _dependencies {};
|
||||||
|
|
||||||
|
std::function<void(Engine&)> _fn; // the actual payload
|
||||||
|
|
||||||
|
public: // construction and assignment
|
||||||
|
TaskInfo(void) = delete;
|
||||||
|
TaskInfo(const TaskInfo&) = default;
|
||||||
|
TaskInfo(TaskInfo&&) = default;
|
||||||
|
|
||||||
|
// TODO: is this right??
|
||||||
|
TaskInfo& operator=(const TaskInfo&) = default;
|
||||||
|
TaskInfo& operator=(TaskInfo&&) = default;
|
||||||
|
|
||||||
|
explicit TaskInfo(const std::string_view key_in) {
|
||||||
|
key(key_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // builder interface
|
||||||
|
// TODO: does this need to be public?
|
||||||
|
TaskInfo& key(const std::string_view key) {
|
||||||
|
_name = key;
|
||||||
|
_key = entt::hashed_string::value(key.data(), key.size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default phase is main
|
||||||
|
TaskInfo& phase(const update_phase_t phase) {
|
||||||
|
_phase = phase;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Fn>
|
||||||
|
TaskInfo& fn(Fn&& fn) {
|
||||||
|
_fn = fn;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskInfo& precede(const std::string_view key) {
|
||||||
|
_dependents.emplace(entt::hashed_string::value(key.data(), key.size()));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskInfo& succeed(const std::string_view key) {
|
||||||
|
_dependencies.emplace(entt::hashed_string::value(key.data(), key.size()));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// pure virtual interface for managing the update logic of the engine
|
// pure virtual interface for managing the update(-task) logic of the engine
|
||||||
class UpdateStrategy {
|
class UpdateStrategy {
|
||||||
public:
|
public:
|
||||||
virtual ~UpdateStrategy(void) {}
|
virtual ~UpdateStrategy(void) {}
|
||||||
@ -42,30 +94,17 @@ class UpdateStrategy {
|
|||||||
protected: // the engine facing interface
|
protected: // the engine facing interface
|
||||||
friend ::MM::Engine;
|
friend ::MM::Engine;
|
||||||
|
|
||||||
// TODO: return something?
|
|
||||||
virtual bool registerService(const entt::id_type s_id, std::vector<UpdateCreationInfo>&& info_array) = 0;
|
|
||||||
|
|
||||||
// returns true on success
|
// returns true on success
|
||||||
// failure conditions may include:
|
// failure conditions may include:
|
||||||
// - already en/dis-abled
|
// - already en/dis-abled
|
||||||
// - is auto_enable
|
// - impossible dependencies?
|
||||||
// - impossible dependencies
|
virtual bool enableService(const entt::id_type s_id, std::vector<TaskInfo>&& task_array) = 0;
|
||||||
virtual bool enableService(const entt::id_type s_id) = 0;
|
|
||||||
virtual bool disableService(const entt::id_type s_id) = 0;
|
virtual bool disableService(const entt::id_type s_id) = 0;
|
||||||
|
|
||||||
// runs one update
|
// runs one update
|
||||||
virtual void doUpdate(MM::Engine& engine) = 0;
|
virtual void doUpdate(MM::Engine& engine) = 0;
|
||||||
|
|
||||||
public: // the user facing interface
|
public: // the user facing interface
|
||||||
// similar to *ableService, can only be used for non-auto_enable-updates
|
|
||||||
virtual bool enable(const update_key_t key) = 0;
|
|
||||||
virtual bool disable(const update_key_t key) = 0;
|
|
||||||
|
|
||||||
// add extra dependencies into the tree, the user has the most knowlage about
|
|
||||||
// the order the services should execute in.
|
|
||||||
// A -> B (make A depend on B)
|
|
||||||
virtual bool depend(const update_key_t A, const update_key_t B) = 0;
|
|
||||||
|
|
||||||
// WIP:
|
// WIP:
|
||||||
|
|
||||||
// dont use, if you are not using it to modify the engine.
|
// dont use, if you are not using it to modify the engine.
|
||||||
@ -77,6 +116,10 @@ class UpdateStrategy {
|
|||||||
// note: the US might decide to limit the amount of executed asyncs per tick (eg. when single-threaded)
|
// note: the US might decide to limit the amount of executed asyncs per tick (eg. when single-threaded)
|
||||||
virtual void addAsync(std::function<void(Engine&)> function) = 0;
|
virtual void addAsync(std::function<void(Engine&)> function) = 0;
|
||||||
//virtual std::future addAsync(std::function<void(Engine&)> function) = 0;
|
//virtual std::future addAsync(std::function<void(Engine&)> function) = 0;
|
||||||
|
protected: // engine tools inspector
|
||||||
|
friend ::MM::Services::ImGuiEngineTools;
|
||||||
|
|
||||||
|
virtual void forEachTask(std::function<bool(TaskInfo&)> fn) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // MM::UpdateStrategies
|
} // MM::UpdateStrategies
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
add_executable(engine_test
|
add_executable(engine_test
|
||||||
update_strategy_test.cpp
|
update_strategy_test.cpp
|
||||||
default_us_test.cpp
|
#default_us_test.cpp
|
||||||
#dependency_check_us_test.cpp
|
|
||||||
|
|
||||||
# old:
|
# old:
|
||||||
#update_test.cpp
|
#update_test.cpp
|
||||||
|
@ -16,37 +16,25 @@ class MockUpdateStrategy : public MM::UpdateStrategies::UpdateStrategy {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "MockUpdateStrategy"; }
|
const char* name(void) override { return "MockUpdateStrategy"; }
|
||||||
|
|
||||||
MOCK_METHOD(
|
|
||||||
bool,
|
|
||||||
registerService,
|
|
||||||
(const entt::id_type s_id, std::vector<MM::UpdateStrategies::UpdateCreationInfo>&& info),
|
|
||||||
(override)
|
|
||||||
);
|
|
||||||
|
|
||||||
// protected:
|
// protected:
|
||||||
MOCK_METHOD(void, doUpdate, (MM::Engine& engine), (override));
|
MOCK_METHOD(void, doUpdate, (MM::Engine& engine), (override));
|
||||||
|
|
||||||
MOCK_METHOD(bool, enableService, (const entt::id_type s_id), (override));
|
MOCK_METHOD(bool, enableService, (const entt::id_type s_id, std::vector<MM::UpdateStrategies::TaskInfo>&& task_array), (override));
|
||||||
MOCK_METHOD(bool, disableService, (const entt::id_type s_id), (override));
|
MOCK_METHOD(bool, disableService, (const entt::id_type s_id), (override));
|
||||||
|
|
||||||
// public:
|
// public:
|
||||||
MOCK_METHOD(bool, enable, (const MM::UpdateStrategies::update_key_t key), (override));
|
|
||||||
MOCK_METHOD(bool, disable, (const MM::UpdateStrategies::update_key_t key), (override));
|
|
||||||
|
|
||||||
MOCK_METHOD(bool, depend, (const MM::UpdateStrategies::update_key_t A, const MM::UpdateStrategies::update_key_t B), (override));
|
|
||||||
|
|
||||||
MOCK_METHOD(void, addDeferred, (std::function<void(MM::Engine&)> function), (override));
|
MOCK_METHOD(void, addDeferred, (std::function<void(MM::Engine&)> function), (override));
|
||||||
MOCK_METHOD(void, addAsync, (std::function<void(MM::Engine&)> function), (override));
|
MOCK_METHOD(void, addAsync, (std::function<void(MM::Engine&)> function), (override));
|
||||||
|
|
||||||
|
MOCK_METHOD(void, forEachTask, (std::function<bool(MM::UpdateStrategies::TaskInfo&)> function), (override));
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockService : public MM::Services::Service {
|
class MockService : public MM::Services::Service {
|
||||||
public:
|
public:
|
||||||
const char* name(void) override { return "MockService"; }
|
const char* name(void) override { return "MockService"; }
|
||||||
|
|
||||||
MOCK_METHOD(bool, enable, (MM::Engine& engine), (override));
|
MOCK_METHOD(bool, enable, (MM::Engine& engine, std::vector<MM::UpdateStrategies::TaskInfo>& task_array), (override));
|
||||||
MOCK_METHOD(void, disable, (MM::Engine& engine), (override));
|
MOCK_METHOD(void, disable, (MM::Engine& engine), (override));
|
||||||
|
|
||||||
MOCK_METHOD(std::vector<MM::UpdateStrategies::UpdateCreationInfo>, registerUpdates, (), (override));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(engine_mock, update_strategy_run) {
|
TEST(engine_mock, update_strategy_run) {
|
||||||
@ -63,9 +51,7 @@ TEST(engine_mock, update_strategy_run) {
|
|||||||
TEST(engine_mock, service_update_strategy) {
|
TEST(engine_mock, service_update_strategy) {
|
||||||
auto mock = std::make_unique<MockUpdateStrategy>();
|
auto mock = std::make_unique<MockUpdateStrategy>();
|
||||||
|
|
||||||
EXPECT_CALL(*mock, registerService(_, _))
|
EXPECT_CALL(*mock, enableService(_, _))
|
||||||
.Times(1);
|
|
||||||
EXPECT_CALL(*mock, enableService(_))
|
|
||||||
.Times(1);
|
.Times(1);
|
||||||
EXPECT_CALL(*mock, disableService(_))
|
EXPECT_CALL(*mock, disableService(_))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
@ -73,12 +59,9 @@ TEST(engine_mock, service_update_strategy) {
|
|||||||
class TmpMockService : public MockService {
|
class TmpMockService : public MockService {
|
||||||
public:
|
public:
|
||||||
TmpMockService(void) {
|
TmpMockService(void) {
|
||||||
EXPECT_CALL(*this, registerUpdates())
|
EXPECT_CALL(*this, enable(_, _))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
|
ON_CALL(*this, enable(_, _))
|
||||||
EXPECT_CALL(*this, enable(_))
|
|
||||||
.Times(1);
|
|
||||||
ON_CALL(*this, enable(_))
|
|
||||||
.WillByDefault(Return(true));
|
.WillByDefault(Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(*this, disable(_))
|
EXPECT_CALL(*this, disable(_))
|
||||||
@ -99,9 +82,7 @@ TEST(engine_mock, service_update_strategy) {
|
|||||||
TEST(engine_mock, service_update_strategy_run_1) {
|
TEST(engine_mock, service_update_strategy_run_1) {
|
||||||
auto mock = std::make_unique<MockUpdateStrategy>();
|
auto mock = std::make_unique<MockUpdateStrategy>();
|
||||||
|
|
||||||
EXPECT_CALL(*mock, registerService(_, _))
|
EXPECT_CALL(*mock, enableService(_, _))
|
||||||
.Times(1);
|
|
||||||
EXPECT_CALL(*mock, enableService(_))
|
|
||||||
.Times(1);
|
.Times(1);
|
||||||
EXPECT_CALL(*mock, disableService(_))
|
EXPECT_CALL(*mock, disableService(_))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
@ -109,23 +90,20 @@ TEST(engine_mock, service_update_strategy_run_1) {
|
|||||||
class TmpMockService : public MockService {
|
class TmpMockService : public MockService {
|
||||||
public:
|
public:
|
||||||
explicit TmpMockService(void) {
|
explicit TmpMockService(void) {
|
||||||
EXPECT_CALL(*this, registerUpdates())
|
EXPECT_CALL(*this, enable)
|
||||||
.Times(1);
|
.Times(1);
|
||||||
ON_CALL(*this, registerUpdates())
|
ON_CALL(*this, enable)
|
||||||
.WillByDefault([]() -> std::vector<MM::UpdateStrategies::UpdateCreationInfo> {
|
.WillByDefault([](MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) -> bool {
|
||||||
return {
|
using MM::UpdateStrategies::TaskInfo;
|
||||||
{
|
|
||||||
"TmpMockService"_hs,
|
|
||||||
"TmpMockService",
|
|
||||||
[](MM::Engine&) {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_CALL(*this, enable(_))
|
task_array.push_back(
|
||||||
.Times(1);
|
TaskInfo{"TmpMockService"}
|
||||||
ON_CALL(*this, enable(_))
|
//.precede("PreviousTask")
|
||||||
.WillByDefault(Return(true));
|
.fn([](MM::Engine& engine) { (void)engine; })
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_CALL(*this, disable(_))
|
EXPECT_CALL(*this, disable(_))
|
||||||
.Times(1);
|
.Times(1);
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool FilesystemService::enable(Engine&) {
|
bool FilesystemService::enable(Engine&, std::vector<UpdateStrategies::TaskInfo>&) {
|
||||||
if (PHYSFS_isInit()) {
|
if (PHYSFS_isInit()) {
|
||||||
LOG_ERROR("physfs already initialized!!");
|
LOG_ERROR("physfs already initialized!!");
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
#include "mm/update_strategies/update_strategy.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -20,7 +22,7 @@ class FilesystemService : public Service {
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine&) override;
|
bool enable(Engine&, std::vector<UpdateStrategies::TaskInfo>&) override;
|
||||||
void disable(Engine&) override;
|
void disable(Engine&) override;
|
||||||
|
|
||||||
const char* name(void) override { return "Filesystem"; }
|
const char* name(void) override { return "Filesystem"; }
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#include "./engine_tools.hpp"
|
#include "./engine_tools.hpp"
|
||||||
#include "mm/update_strategies/update_strategy.hpp"
|
|
||||||
|
|
||||||
#include <entt/config/version.h>
|
#include <entt/config/version.h>
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
#include <entt/core/hashed_string.hpp>
|
|
||||||
|
|
||||||
#include <mm/update_strategies/default_strategy.hpp>
|
#include <mm/update_strategies/update_strategy.hpp>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
@ -17,10 +15,13 @@ namespace MM::Services {
|
|||||||
using UpdateStrategies::update_key_t;
|
using UpdateStrategies::update_key_t;
|
||||||
|
|
||||||
template<typename NColFn, typename LColFn, typename TTFn>
|
template<typename NColFn, typename LColFn, typename TTFn>
|
||||||
static void renderUpdateStratGraph(const std::unordered_map<update_key_t, std::set<update_key_t>>& g, std::set<update_key_t>& a, NColFn&& node_color_fn, LColFn&& line_color_fn, TTFn&& tooltip_fn) {
|
static void renderUpdateStratGraph(
|
||||||
//auto& g = us_default->getGraph(UpdateStrategies::update_phase_t::MAIN);
|
const std::unordered_map<update_key_t, std::set<update_key_t>>& g,
|
||||||
//auto& a = us_default->getActiveSet(UpdateStrategies::update_phase_t::MAIN);
|
std::set<update_key_t>& a,
|
||||||
|
NColFn&& node_color_fn,
|
||||||
|
LColFn&& line_color_fn,
|
||||||
|
TTFn&& tooltip_fn
|
||||||
|
) {
|
||||||
using UpdateStrategies::update_key_t;
|
using UpdateStrategies::update_key_t;
|
||||||
|
|
||||||
std::set<update_key_t> work_queue{a.begin(), a.end()};
|
std::set<update_key_t> work_queue{a.begin(), a.end()};
|
||||||
@ -156,7 +157,7 @@ static void renderUpdateStratGraph(const std::unordered_map<update_key_t, std::s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiEngineTools::enable(Engine& engine) {
|
bool ImGuiEngineTools::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
||||||
|
|
||||||
// use underscore hack to make it last
|
// use underscore hack to make it last
|
||||||
@ -179,6 +180,13 @@ bool ImGuiEngineTools::enable(Engine& engine) {
|
|||||||
ImGui::MenuItem("UpdateStrategy", NULL, &_show_update_stategy);
|
ImGui::MenuItem("UpdateStrategy", NULL, &_show_update_stategy);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiEngineTools::render"}
|
||||||
|
.fn([this](Engine& e){ renderImGui(e); })
|
||||||
|
.succeed("ImGuiMenuBar::render")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,22 +199,6 @@ void ImGuiEngineTools::disable(Engine& engine) {
|
|||||||
menu_bar.menu_tree["Engine"].erase("UpdateStrategy");
|
menu_bar.menu_tree["Engine"].erase("UpdateStrategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiEngineTools::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiEngineTools::render"_hs,
|
|
||||||
"ImGuiEngineTools::render",
|
|
||||||
[this](Engine& e){ renderImGui(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"ImGuiMenuBar::render"_hs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiEngineTools::renderImGui(Engine& engine) {
|
void ImGuiEngineTools::renderImGui(Engine& engine) {
|
||||||
if (_show_about) {
|
if (_show_about) {
|
||||||
renderAbout(engine);
|
renderAbout(engine);
|
||||||
@ -250,7 +242,7 @@ void ImGuiEngineTools::renderServices(Engine& engine) {
|
|||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%d", it.first);
|
ImGui::Text("%u", it.first);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", it.second->second->name());
|
ImGui::Text("%s", it.second->second->name());
|
||||||
@ -284,10 +276,99 @@ void ImGuiEngineTools::renderUpdateStrategy(Engine& engine) {
|
|||||||
auto us_name = us.name();
|
auto us_name = us.name();
|
||||||
|
|
||||||
ImGui::Text("UpdateStrategy: '%s'", us_name);
|
ImGui::Text("UpdateStrategy: '%s'", us_name);
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
auto* us_default = dynamic_cast<MM::UpdateStrategies::SingleThreadedDefault*>(&us);
|
// TODO: tabs? dropdown(combo)?
|
||||||
if (us_default) {
|
static const char* const phase_str[4] = {
|
||||||
|
"All",
|
||||||
|
"Pre",
|
||||||
|
"Main",
|
||||||
|
"Post",
|
||||||
|
};
|
||||||
|
static int curr_phase = 2;
|
||||||
|
|
||||||
|
ImGui::Combo("Phase", &curr_phase, phase_str, 4);
|
||||||
|
|
||||||
|
if (ImGui::BeginTabBar("tabs")) {
|
||||||
|
if (curr_phase != 0 && ImGui::BeginTabItem("Graph")) {
|
||||||
|
// BRUHHH this is needs to be cached
|
||||||
|
std::unordered_map<update_key_t, std::set<update_key_t>> graph;
|
||||||
|
std::unordered_map<update_key_t, UpdateStrategies::TaskInfo*> task_lut;
|
||||||
|
std::set<update_key_t> nodes;
|
||||||
|
|
||||||
|
// build lut
|
||||||
|
us.forEachTask([&graph, &nodes, &task_lut](UpdateStrategies::TaskInfo& task) -> bool {
|
||||||
|
if (task._phase != UpdateStrategies::update_phase_t(curr_phase-1)) {
|
||||||
|
return true; // skip, not our phase
|
||||||
|
}
|
||||||
|
|
||||||
|
graph[task._key] = task._dependencies;
|
||||||
|
task_lut[task._key] = &task;
|
||||||
|
nodes.emplace(task._key);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// also do dependents // ugh, 2*N
|
||||||
|
us.forEachTask([&graph](UpdateStrategies::TaskInfo& task) -> bool {
|
||||||
|
if (task._phase != UpdateStrategies::update_phase_t(curr_phase-1)) {
|
||||||
|
return true; // skip, not our phase
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto it : task._dependents) {
|
||||||
|
graph[it].emplace(task._key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: make sense of the colloring
|
||||||
|
renderUpdateStratGraph(graph, nodes,
|
||||||
|
[](const update_key_t key) -> ImVec4 {
|
||||||
|
return {0.9f, 1.f, 0.9f, 1.f};
|
||||||
|
},
|
||||||
|
[](const update_key_t from, const update_key_t to) -> ImVec4 {
|
||||||
|
return {0.9f, 1.f, 0.9f, 1.f};
|
||||||
|
},
|
||||||
|
[&task_lut](update_key_t key) {
|
||||||
|
ImGui::SetTooltip("%s\n[%u]", task_lut.at(key)->_name.c_str(), key);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginTabItem("List")) {
|
||||||
|
if (ImGui::BeginTable("table", curr_phase == 0 ? 3 : 2)) {
|
||||||
|
us.forEachTask([](UpdateStrategies::TaskInfo& task) -> bool {
|
||||||
|
if (
|
||||||
|
curr_phase == 0 ||
|
||||||
|
task._phase == UpdateStrategies::update_phase_t(curr_phase-1)
|
||||||
|
) {
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%u", task._key);
|
||||||
|
|
||||||
|
if (curr_phase == 0) {
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s", phase_str[task._phase + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s", task._name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
auto& g = us_default->getGraph(UpdateStrategies::update_phase_t::MAIN);
|
auto& g = us_default->getGraph(UpdateStrategies::update_phase_t::MAIN);
|
||||||
auto& a = us_default->getActiveSet(UpdateStrategies::update_phase_t::MAIN);
|
auto& a = us_default->getActiveSet(UpdateStrategies::update_phase_t::MAIN);
|
||||||
std::set<update_key_t> nodes;
|
std::set<update_key_t> nodes;
|
||||||
@ -305,7 +386,7 @@ void ImGuiEngineTools::renderUpdateStrategy(Engine& engine) {
|
|||||||
ImGui::Text("%u", it);
|
ImGui::Text("%u", it);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", us_default->_tasks[it].name.c_str());
|
ImGui::Text("%s", us_default->_tasks.at(it)._name.c_str());
|
||||||
}
|
}
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
@ -329,7 +410,7 @@ void ImGuiEngineTools::renderUpdateStrategy(Engine& engine) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[us_default](update_key_t key) {
|
[us_default](update_key_t key) {
|
||||||
ImGui::SetTooltip("'%s'\n[%u]", us_default->_tasks[key].name.c_str(), key);
|
ImGui::SetTooltip("'%s'\n[%u]", us_default->_tasks.at(key)._name.c_str(), key);
|
||||||
});
|
});
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
@ -337,6 +418,7 @@ void ImGuiEngineTools::renderUpdateStrategy(Engine& engine) {
|
|||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,9 @@ namespace MM::Services {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "ImGuiEngineTools"; }
|
const char* name(void) override { return "ImGuiEngineTools"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _show_about = false;
|
bool _show_about = false;
|
||||||
bool _show_services = false;
|
bool _show_services = false;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "./imgui_menu_bar.hpp"
|
#include "./imgui_menu_bar.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
#include <entt/core/hashed_string.hpp>
|
#include <entt/core/hashed_string.hpp>
|
||||||
@ -17,7 +18,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ImGuiMenuBar::enable(Engine& engine) {
|
bool ImGuiMenuBar::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
MM::Logger::initSectionLogger("ImGuiMenuBar");
|
MM::Logger::initSectionLogger("ImGuiMenuBar");
|
||||||
|
|
||||||
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
||||||
@ -32,6 +33,12 @@ namespace MM::Services {
|
|||||||
LOG_WARN("no SDLService, skipping toggle hotkey");
|
LOG_WARN("no SDLService, skipping toggle hotkey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiMenuBar::render"}
|
||||||
|
.fn([this](Engine& e){ renderImGui(e); })
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,17 +50,6 @@ namespace MM::Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiMenuBar::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiMenuBar::render"_hs,
|
|
||||||
"ImGuiMenuBar::render",
|
|
||||||
[this](Engine& e){ renderImGui(e); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiMenuBar::renderImGui(Engine& engine) {
|
void ImGuiMenuBar::renderImGui(Engine& engine) {
|
||||||
if (show_menu_bar && ImGui::BeginMainMenuBar()) {
|
if (show_menu_bar && ImGui::BeginMainMenuBar()) {
|
||||||
|
|
||||||
@ -80,7 +76,8 @@ namespace MM::Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ImGui::Text("| %.1fFPS", ImGui::GetIO().Framerate);
|
ImGui::Separator();
|
||||||
|
ImGui::Text("%.1fFPS", ImGui::GetIO().Framerate);
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,9 @@ namespace MM::Services {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "ImGuiMenuBar"; }
|
const char* name(void) override { return "ImGuiMenuBar"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool show_menu_bar = true;
|
bool show_menu_bar = true;
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "./imgui_s.hpp"
|
#include "./imgui_s.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
#include "mm/update_strategies/update_strategy.hpp"
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
#include <imgui/backends/imgui_impl_sdl.h>
|
#include <imgui/backends/imgui_impl_sdl.h>
|
||||||
@ -25,7 +27,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ImGuiService::enable(Engine& engine) {
|
bool ImGuiService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
|
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
@ -69,6 +71,14 @@ bool ImGuiService::enable(Engine& engine) {
|
|||||||
[this](const SDL_Event& e) { return handle_sdl_event(e); }
|
[this](const SDL_Event& e) { return handle_sdl_event(e); }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiService::new_frame"}
|
||||||
|
.phase(UpdateStrategies::update_phase_t::PRE)
|
||||||
|
.fn([this](Engine& e) { this->imgui_new_frame(e); })
|
||||||
|
.succeed("SDLService::events")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,20 +95,6 @@ void ImGuiService::disable(Engine& engine) {
|
|||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiService::new_frame"_hs,
|
|
||||||
"ImGuiService::new_frame",
|
|
||||||
[this](Engine& e) { this->imgui_new_frame(e); },
|
|
||||||
UpdateStrategies::update_phase_t::PRE,
|
|
||||||
true,
|
|
||||||
{"SDLService::events"_hs}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiService::imgui_new_frame(Engine& engine) {
|
void ImGuiService::imgui_new_frame(Engine& engine) {
|
||||||
ZoneScopedN("MM::Services::ImGuiService::imgui_new_frame");
|
ZoneScopedN("MM::Services::ImGuiService::imgui_new_frame");
|
||||||
|
|
||||||
|
@ -14,13 +14,11 @@ namespace MM::Services {
|
|||||||
// new frame needs to start AFTER the events have been processed (and obv bf rendt)
|
// new frame needs to start AFTER the events have been processed (and obv bf rendt)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
const char* name(void) override { return "ImGuiService"; }
|
const char* name(void) override { return "ImGuiService"; }
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void imgui_new_frame(Engine& engine);
|
void imgui_new_frame(Engine& engine);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
#include "./imgui_menu_bar.hpp"
|
#include "./imgui_menu_bar.hpp"
|
||||||
#include "mm/components/time_delta.hpp"
|
#include "mm/components/time_delta.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
@ -36,7 +37,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ImGuiSceneToolsService::enable(Engine& engine) {
|
bool ImGuiSceneToolsService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
if (!engine.tryService<MM::Services::SceneServiceInterface>()) {
|
if (!engine.tryService<MM::Services::SceneServiceInterface>()) {
|
||||||
LOGIGS("error: no SceneServiceInterface");
|
LOGIGS("error: no SceneServiceInterface");
|
||||||
return false;
|
return false;
|
||||||
@ -82,6 +83,13 @@ namespace MM::Services {
|
|||||||
ImGui::MenuItem("TimeDelta Context", NULL, &_show_time_delta_ctx, td_ptr);
|
ImGui::MenuItem("TimeDelta Context", NULL, &_show_time_delta_ctx, td_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiSceneToolsService::render"}
|
||||||
|
.fn([this](Engine& e){ renderImGui(e); })
|
||||||
|
.succeed("ImGuiMenuBar::render")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,22 +102,6 @@ namespace MM::Services {
|
|||||||
menu_bar.menu_tree["Scene"].erase("TimeCtx");
|
menu_bar.menu_tree["Scene"].erase("TimeCtx");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiSceneToolsService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiSceneToolsService::render"_hs,
|
|
||||||
"ImGuiSceneToolsService::render",
|
|
||||||
[this](Engine& e){ renderImGui(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"ImGuiMenuBar::render"_hs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiSceneToolsService::renderImGui(Engine& engine) {
|
void ImGuiSceneToolsService::renderImGui(Engine& engine) {
|
||||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
#define MM_IEEE_ENTITY_WIDGET ::MM::ImGuiWidgets::Entity // evil
|
#define MM_IEEE_ENTITY_WIDGET ::MM::ImGuiWidgets::Entity // evil
|
||||||
#define MM_IEEE_ASSERT(x)
|
#define MM_IEEE_ASSERT(x)
|
||||||
#include <mm/imgui/widgets/entity.hpp>
|
#include <mm/imgui/widgets/entity.hpp>
|
||||||
@ -11,13 +12,11 @@ namespace MM::Services {
|
|||||||
|
|
||||||
class ImGuiSceneToolsService : public Service {
|
class ImGuiSceneToolsService : public Service {
|
||||||
public:
|
public:
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
const char* name(void) override { return "ImGuiSceneToolsService"; }
|
const char* name(void) override { return "ImGuiSceneToolsService"; }
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _show_scene_metrics = false;
|
bool _show_scene_metrics = false;
|
||||||
bool _show_entity_editor = false;
|
bool _show_entity_editor = false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "./sound_tools.hpp"
|
#include "./sound_tools.hpp"
|
||||||
#include "mm/imgui/sound_info.hpp"
|
#include <mm/imgui/sound_info.hpp>
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
#include <entt/core/hashed_string.hpp>
|
#include <entt/core/hashed_string.hpp>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ImGuiSoundTools::enable(Engine& engine) {
|
bool ImGuiSoundTools::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
||||||
|
|
||||||
//menu_bar.menu_tree["Engine"]["Stop Engine"] = [](Engine& e) {
|
//menu_bar.menu_tree["Engine"]["Stop Engine"] = [](Engine& e) {
|
||||||
@ -35,6 +35,13 @@ namespace MM::Services {
|
|||||||
ImGui::MenuItem("Info", NULL, &_show_info);
|
ImGui::MenuItem("Info", NULL, &_show_info);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiSoundTools::render"}
|
||||||
|
.fn([this](Engine& e){ renderImGui(e); })
|
||||||
|
.succeed("ImGuiMenuBar::render")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,22 +52,6 @@ namespace MM::Services {
|
|||||||
menu_bar.menu_tree["Sound"].erase("Info");
|
menu_bar.menu_tree["Sound"].erase("Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiSoundTools::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiSoundTools::render"_hs,
|
|
||||||
"ImGuiSoundTools::render",
|
|
||||||
[this](Engine& e){ renderImGui(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"ImGuiMenuBar::render"_hs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiSoundTools::renderImGui(Engine& engine) {
|
void ImGuiSoundTools::renderImGui(Engine& engine) {
|
||||||
if (_show_info) {
|
if (_show_info) {
|
||||||
MM::ImGuiSoundInfo(engine, &_show_info);
|
MM::ImGuiSoundInfo(engine, &_show_info);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "./imgui_menu_bar.hpp"
|
#include "./imgui_menu_bar.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
@ -8,11 +9,9 @@ namespace MM::Services {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "ImGuiSoundTools"; }
|
const char* name(void) override { return "ImGuiSoundTools"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _show_info = false;
|
bool _show_info = false;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ TEST(imgui_scene_tools, it) {
|
|||||||
ASSERT_TRUE(engine.enableService<MM::Services::ImGuiEngineTools>());
|
ASSERT_TRUE(engine.enableService<MM::Services::ImGuiEngineTools>());
|
||||||
|
|
||||||
engine.addService<MM::Services::ImGuiSceneToolsService>();
|
engine.addService<MM::Services::ImGuiSceneToolsService>();
|
||||||
engine.getUpdateStrategy().depend("ImGuiSceneToolsService::render"_hs, "SimpleSceneService::scene_tick"_hs);
|
//engine.getUpdateStrategy().depend("ImGuiSceneToolsService::render"_hs, "SimpleSceneService::scene_tick"_hs);
|
||||||
|
|
||||||
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
auto& rs = engine.addService<MM::Services::OpenGLRenderer>();
|
||||||
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
ASSERT_TRUE(engine.enableService<MM::Services::OpenGLRenderer>());
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
@ -45,7 +46,7 @@ class ImGuiSpeechy : public MM::Services::Service {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestWindow"; }
|
const char* name(void) override { return "TestWindow"; }
|
||||||
|
|
||||||
bool enable(MM::Engine& engine) override {
|
bool enable(MM::Engine& engine, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) override {
|
||||||
auto& sound = engine.getService<MM::Services::SoundService>().engine;
|
auto& sound = engine.getService<MM::Services::SoundService>().engine;
|
||||||
|
|
||||||
speech.setText("Test text. 1. 2. 3.");
|
speech.setText("Test text. 1. 2. 3.");
|
||||||
@ -55,21 +56,16 @@ class ImGuiSpeechy : public MM::Services::Service {
|
|||||||
sound.setGlobalFilter(1, &echo);
|
sound.setGlobalFilter(1, &echo);
|
||||||
sound.setGlobalFilter(2, &freeverb);
|
sound.setGlobalFilter(2, &freeverb);
|
||||||
|
|
||||||
|
task_array.push_back(
|
||||||
|
MM::UpdateStrategies::TaskInfo{"testwindow"}
|
||||||
|
.fn([this](MM::Engine& engine) { renderImGui(engine); })
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
|
|
||||||
std::vector<MM::UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override {
|
|
||||||
return {{
|
|
||||||
"testwindow"_hs,
|
|
||||||
"testwindow",
|
|
||||||
[this](MM::Engine& engine) {
|
|
||||||
renderImGui(engine);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderImGui(MM::Engine& engine) {
|
void renderImGui(MM::Engine& engine) {
|
||||||
auto& sound = *engine.tryService<MM::Services::SoundService>();
|
auto& sound = *engine.tryService<MM::Services::SoundService>();
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
@ -32,16 +33,16 @@ class TemplateUpdateMainService : public MM::Services::Service {
|
|||||||
explicit TemplateUpdateMainService(std::function<void(MM::Engine&)> fn) : _fn(fn) {}
|
explicit TemplateUpdateMainService(std::function<void(MM::Engine&)> fn) : _fn(fn) {}
|
||||||
|
|
||||||
const char* name(void) override { return "TemplateUpdateMainService"; }
|
const char* name(void) override { return "TemplateUpdateMainService"; }
|
||||||
bool enable(MM::Engine&) override { return true; }
|
|
||||||
void disable(MM::Engine&) override {}
|
|
||||||
|
|
||||||
std::vector<MM::UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override {
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) override {
|
||||||
return {{
|
task_array.push_back(
|
||||||
"TemplateUpdateMainService::fn"_hs,
|
MM::UpdateStrategies::TaskInfo{"TemplateUpdateMainService::fn"}
|
||||||
"TemplateUpdateMainService::fn",
|
.fn(_fn)
|
||||||
_fn
|
);
|
||||||
}};
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disable(MM::Engine&) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(imgui_text_edit, it) {
|
TEST(imgui_text_edit, it) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "mm/imgui/widgets/scalar_range.hpp"
|
#include "mm/services/service.hpp"
|
||||||
#include "mm/scalar_range2.hpp"
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
@ -17,6 +16,7 @@
|
|||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
#include <mm/imgui/widgets/knob.hpp>
|
#include <mm/imgui/widgets/knob.hpp>
|
||||||
|
#include <mm/imgui/widgets/scalar_range.hpp>
|
||||||
|
|
||||||
const char* argv0;
|
const char* argv0;
|
||||||
|
|
||||||
@ -44,14 +44,11 @@ TEST(imgui_widgets, basic) {
|
|||||||
class TestWindow : public MM::Services::Service {
|
class TestWindow : public MM::Services::Service {
|
||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestWindow"; }
|
const char* name(void) override { return "TestWindow"; }
|
||||||
bool enable(MM::Engine&) override { return true; }
|
|
||||||
void disable(MM::Engine&) override {}
|
|
||||||
|
|
||||||
std::vector<MM::UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override {
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) override {
|
||||||
return {{
|
task_array.push_back(
|
||||||
"testwindow"_hs,
|
MM::UpdateStrategies::TaskInfo{"testwindow"}
|
||||||
"testwindow",
|
.fn([](MM::Engine&) {
|
||||||
[](MM::Engine&) {
|
|
||||||
if (ImGui::Begin("test window")) {
|
if (ImGui::Begin("test window")) {
|
||||||
|
|
||||||
static float knob_test = 0.f;
|
static float knob_test = 0.f;
|
||||||
@ -63,9 +60,12 @@ TEST(imgui_widgets, basic) {
|
|||||||
MM::ImGuiWidgets::DragScalarRange2("range", range);
|
MM::ImGuiWidgets::DragScalarRange2("range", range);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
})
|
||||||
}};
|
);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disable(MM::Engine&) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
engine.addService<TestWindow>();
|
engine.addService<TestWindow>();
|
||||||
|
@ -77,7 +77,7 @@ InputService::InputService(void) {
|
|||||||
InputService::~InputService(void) {
|
InputService::~InputService(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputService::enable(Engine& engine) {
|
bool InputService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
auto* sdl_ss = engine.tryService<SDLService>();
|
auto* sdl_ss = engine.tryService<SDLService>();
|
||||||
if (!sdl_ss) {
|
if (!sdl_ss) {
|
||||||
LOG_ERROR("InputService requires SDLService in engine!");
|
LOG_ERROR("InputService requires SDLService in engine!");
|
||||||
@ -90,6 +90,24 @@ bool InputService::enable(Engine& engine) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"InputService::update"}
|
||||||
|
.fn([this](MM::Engine&) {
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
if (!_player_active[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& p = _player[i];
|
||||||
|
if (p.is_controller) {
|
||||||
|
} else {
|
||||||
|
updateKPlayerDirs(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,28 +123,6 @@ void InputService::disable(Engine& engine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> InputService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"InputService::update"_hs,
|
|
||||||
"InputService::update",
|
|
||||||
[this](MM::Engine&) {
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
|
||||||
if (!_player_active[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto& p = _player[i];
|
|
||||||
if (p.is_controller) {
|
|
||||||
} else {
|
|
||||||
updateKPlayerDirs(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InputService::handleSDL_Event(const SDL_Event& e, MM::Engine& engine) {
|
bool InputService::handleSDL_Event(const SDL_Event& e, MM::Engine& engine) {
|
||||||
ZoneScopedN("MM::InputService::handleSDL_Event");
|
ZoneScopedN("MM::InputService::handleSDL_Event");
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SDL.h>
|
#include "mm/services/service.hpp"
|
||||||
|
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
#include <mm/services/sdl_service.hpp>
|
#include <mm/services/sdl_service.hpp>
|
||||||
@ -108,14 +107,11 @@ namespace MM::Services {
|
|||||||
SDLService::EventHandlerHandle _event_handle = nullptr;
|
SDLService::EventHandlerHandle _event_handle = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
const char* name(void) override { return "InputService"; }
|
const char* name(void) override { return "InputService"; }
|
||||||
|
|
||||||
// you will likely want to make the scene depend on this
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// returns true if event was relevant
|
// returns true if event was relevant
|
||||||
bool handleSDL_Event(const SDL_Event& e, MM::Engine& engine);
|
bool handleSDL_Event(const SDL_Event& e, MM::Engine& engine);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <mm/services/input_service.hpp>
|
#include <mm/services/input_service.hpp>
|
||||||
#include <mm/services/sdl_service.hpp>
|
#include <mm/services/sdl_service.hpp>
|
||||||
#include <mm/services/filesystem.hpp>
|
#include <mm/services/filesystem.hpp>
|
||||||
@ -11,7 +13,6 @@
|
|||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
|
|
||||||
class InputVisualizer : public MM::Services::Service {
|
class InputVisualizer : public MM::Services::Service {
|
||||||
private:
|
private:
|
||||||
MM::Input::PlayerID _player_id;
|
MM::Input::PlayerID _player_id;
|
||||||
@ -20,7 +21,7 @@ class InputVisualizer : public MM::Services::Service {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "InputVisualizer"; }
|
const char* name(void) override { return "InputVisualizer"; }
|
||||||
|
|
||||||
bool enable(MM::Engine& engine) override {
|
bool enable(MM::Engine& engine, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) override {
|
||||||
_player_id = UINT16_MAX;
|
_player_id = UINT16_MAX;
|
||||||
|
|
||||||
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
auto* sdl_ss = engine.tryService<MM::Services::SDLService>();
|
||||||
@ -40,27 +41,18 @@ class InputVisualizer : public MM::Services::Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task_array.push_back(
|
||||||
|
MM::UpdateStrategies::TaskInfo{"InputVisualizer::render"}
|
||||||
|
.fn([this](MM::Engine& e){ renderImGui(e); })
|
||||||
|
.succeed("InputService::update")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable(MM::Engine&) override {
|
void disable(MM::Engine&) override {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MM::UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"InputVisualizer::render"_hs,
|
|
||||||
"InputVisualizer::render",
|
|
||||||
[this](MM::Engine& e){ this->renderImGui(e); },
|
|
||||||
MM::UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{ "InputService::update"_hs }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void renderImGui(MM::Engine& engine) {
|
void renderImGui(MM::Engine& engine) {
|
||||||
ImGui::Begin("InputVisualizer", NULL, ImGuiWindowFlags_AlwaysAutoResize);
|
ImGui::Begin("InputVisualizer", NULL, ImGuiWindowFlags_AlwaysAutoResize);
|
||||||
|
@ -43,7 +43,7 @@ OpenGLRenderer::OpenGLRenderer(void) {
|
|||||||
OpenGLRenderer::~OpenGLRenderer(void) {
|
OpenGLRenderer::~OpenGLRenderer(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLRenderer::enable(Engine& engine) {
|
bool OpenGLRenderer::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
if (!engine.tryService<SDLService>()) {
|
if (!engine.tryService<SDLService>()) {
|
||||||
LOG_ERROR("OpenGLRenderer requires SDLService");
|
LOG_ERROR("OpenGLRenderer requires SDLService");
|
||||||
return false;
|
return false;
|
||||||
@ -126,6 +126,14 @@ bool OpenGLRenderer::enable(Engine& engine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"OpenGLRenderer::render"}
|
||||||
|
.phase(UpdateStrategies::update_phase_t::POST)
|
||||||
|
.fn([this](Engine& e){ this->render(e); })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,17 +146,6 @@ void OpenGLRenderer::disable(Engine&) {
|
|||||||
MM::ResourceManager<MM::OpenGL::Texture>::ref().clear();
|
MM::ResourceManager<MM::OpenGL::Texture>::ref().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> OpenGLRenderer::registerUpdates(void) {
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"OpenGLRenderer::render"_hs,
|
|
||||||
"OpenGLRenderer::render",
|
|
||||||
[this](Engine& e){ this->render(e); },
|
|
||||||
UpdateStrategies::update_phase_t::POST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLRenderer::render(Engine& engine) {
|
void OpenGLRenderer::render(Engine& engine) {
|
||||||
ZoneScopedN("MM::Services::OpenGLRenderer::render");
|
ZoneScopedN("MM::Services::OpenGLRenderer::render");
|
||||||
|
|
||||||
|
@ -31,14 +31,11 @@ namespace MM::Services {
|
|||||||
SDLService::EventHandlerHandle _sdl_event_handle = nullptr;
|
SDLService::EventHandlerHandle _sdl_event_handle = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
const char* name(void) override { return "OpenGLRendererService"; }
|
const char* name(void) override { return "OpenGLRendererService"; }
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render(Engine& engine);
|
void render(Engine& engine);
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ImGuiOpenGLRendererTools::enable(Engine& engine) {
|
bool ImGuiOpenGLRendererTools::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
auto& menu_bar = engine.getService<MM::Services::ImGuiMenuBar>();
|
||||||
|
|
||||||
menu_bar.menu_tree["OpenGL"]["RenderTasks"] = [this](Engine&) {
|
menu_bar.menu_tree["OpenGL"]["RenderTasks"] = [this](Engine&) {
|
||||||
@ -21,6 +21,13 @@ bool ImGuiOpenGLRendererTools::enable(Engine& engine) {
|
|||||||
ImGui::MenuItem("Texture Cache (legacy)", NULL, &_show_texture_cache_legacy);
|
ImGui::MenuItem("Texture Cache (legacy)", NULL, &_show_texture_cache_legacy);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ImGuiOpenGLRendererTools::render"}
|
||||||
|
.fn([this](Engine& e) { renderImGui(e); })
|
||||||
|
.succeed("ImGuiMenuBar::render")
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,22 +38,6 @@ void ImGuiOpenGLRendererTools::disable(Engine& engine) {
|
|||||||
menu_bar.menu_tree["OpenGL"].erase("TextureCacheLegacy");
|
menu_bar.menu_tree["OpenGL"].erase("TextureCacheLegacy");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiOpenGLRendererTools::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ImGuiOpenGLRendererTools::render"_hs,
|
|
||||||
"ImGuiOpenGLRendererTools::render",
|
|
||||||
[this](Engine& e) { renderImGui(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"ImGuiMenuBar::render"_hs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiOpenGLRendererTools::renderImGui(Engine& engine) {
|
void ImGuiOpenGLRendererTools::renderImGui(Engine& engine) {
|
||||||
if (_show_render_tasks) {
|
if (_show_render_tasks) {
|
||||||
renderRenderTasks(engine);
|
renderRenderTasks(engine);
|
||||||
|
@ -8,11 +8,9 @@ namespace MM::Services {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "ImGuiOpenGLRendererTools"; }
|
const char* name(void) override { return "ImGuiOpenGLRendererTools"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _show_render_tasks = false;
|
bool _show_render_tasks = false;
|
||||||
bool _show_texture_cache_legacy = false;
|
bool _show_texture_cache_legacy = false;
|
||||||
|
@ -30,17 +30,16 @@ TEST(imgui_render_task, demowindow) {
|
|||||||
class ImGuiDemoWindowService : public MM::Services::Service {
|
class ImGuiDemoWindowService : public MM::Services::Service {
|
||||||
public:
|
public:
|
||||||
const char* name(void) override { return "ImGuiDemoWindowService"; }
|
const char* name(void) override { return "ImGuiDemoWindowService"; }
|
||||||
bool enable(MM::Engine&) override { return true; }
|
|
||||||
void disable(MM::Engine&) override {}
|
|
||||||
|
|
||||||
std::vector<MM::UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override {
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>& task_array) override {
|
||||||
return {{
|
task_array.push_back(
|
||||||
"ImGuiDemoWindow"_hs,
|
MM::UpdateStrategies::TaskInfo{"ImGuiDemoWindow"}
|
||||||
"ImGuiDemoWindow",
|
.fn([](MM::Engine&) { ImGui::ShowDemoWindow(); })
|
||||||
[](MM::Engine&) { ImGui::ShowDemoWindow(); }
|
);
|
||||||
}};
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disable(MM::Engine&) override {}
|
||||||
};
|
};
|
||||||
engine.addService<ImGuiDemoWindowService>();
|
engine.addService<ImGuiDemoWindowService>();
|
||||||
ASSERT_TRUE(engine.enableService<ImGuiDemoWindowService>());
|
ASSERT_TRUE(engine.enableService<ImGuiDemoWindowService>());
|
||||||
|
@ -36,7 +36,25 @@ static std::ostream& operator<<(std::ostream& out, const std::vector<entt::organ
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool OrganizerSceneService::enable(Engine& engine) {
|
bool OrganizerSceneService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
|
// add tasks
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"OrganizerSceneService::scene_update"}
|
||||||
|
.fn([this](Engine& e) { sceneUpdate(e); })
|
||||||
|
);
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"OrganizerSceneService::scene_tick"}
|
||||||
|
.fn([this](Engine& e) { sceneFixedUpdate(e); })
|
||||||
|
|
||||||
|
// bc it renders imgui, but this is not "hard"
|
||||||
|
.succeed("OrganizerSceneService::scene_update")
|
||||||
|
);
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"OrganizerSceneService::scene_changer"}
|
||||||
|
.fn([this](Engine& e) { changeSceneFixedUpdate(e); })
|
||||||
|
.succeed("OrganizerSceneService::scene_tick")
|
||||||
|
);
|
||||||
|
|
||||||
// default scene
|
// default scene
|
||||||
if (!_scene) {
|
if (!_scene) {
|
||||||
_scene = std::make_unique<Scene>();
|
_scene = std::make_unique<Scene>();
|
||||||
@ -52,38 +70,6 @@ bool OrganizerSceneService::enable(Engine& engine) {
|
|||||||
void OrganizerSceneService::disable(Engine&) {
|
void OrganizerSceneService::disable(Engine&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> OrganizerSceneService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"OrganizerSceneService::scene_update"_hs,
|
|
||||||
"OrganizerSceneService::scene_update",
|
|
||||||
[this](Engine& e) { sceneUpdate(e); },
|
|
||||||
// depends on imgui
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OrganizerSceneService::scene_tick"_hs,
|
|
||||||
"OrganizerSceneService::scene_tick",
|
|
||||||
[this](Engine& e) { sceneFixedUpdate(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"OrganizerSceneService::scene_update"_hs, // bc it renders imgui, but this is not "hard"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"OrganizerSceneService::scene_changer"_hs,
|
|
||||||
"OrganizerSceneService::scene_changer",
|
|
||||||
[this](Engine& e) { changeSceneFixedUpdate(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"OrganizerSceneService::scene_tick"_hs,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void OrganizerSceneService::sceneFixedUpdate(Engine&) {
|
void OrganizerSceneService::sceneFixedUpdate(Engine&) {
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <mm/services/scene_service_interface.hpp>
|
#include <mm/services/scene_service_interface.hpp>
|
||||||
#include <entt/fwd.hpp>
|
#include <entt/fwd.hpp>
|
||||||
|
|
||||||
@ -28,11 +29,9 @@ namespace MM::Services {
|
|||||||
|
|
||||||
const char* name(void) override { return "OrganizerSceneService"; }
|
const char* name(void) override { return "OrganizerSceneService"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
public: // scene interface
|
public: // scene interface
|
||||||
Scene& getScene(void) override { return *_scene; }
|
Scene& getScene(void) override { return *_scene; }
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "./screen_director.hpp"
|
#include "./screen_director.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
#include "mm/update_strategies/update_strategy.hpp"
|
||||||
|
|
||||||
#include <entt/core/hashed_string.hpp>
|
#include <entt/core/hashed_string.hpp>
|
||||||
|
|
||||||
@ -8,7 +10,14 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool ScreenDirector::enable(MM::Engine& engine) {
|
bool ScreenDirector::enable(MM::Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
|
// add task
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"ScreenDirector::update"}
|
||||||
|
.fn([this](Engine& e) { update(e); })
|
||||||
|
.phase(UpdateStrategies::update_phase_t::POST)
|
||||||
|
);
|
||||||
|
|
||||||
// start initial screen
|
// start initial screen
|
||||||
if (!queued_screen_id.empty()) {
|
if (!queued_screen_id.empty()) {
|
||||||
auto next_screen_id = queued_screen_id;
|
auto next_screen_id = queued_screen_id;
|
||||||
@ -25,18 +34,6 @@ bool ScreenDirector::enable(MM::Engine& engine) {
|
|||||||
void ScreenDirector::disable(MM::Engine&) {
|
void ScreenDirector::disable(MM::Engine&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> ScreenDirector::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"ScreenDirector::update"_hs,
|
|
||||||
"ScreenDirector::update",
|
|
||||||
[this](Engine& engine) { update(engine); },
|
|
||||||
UpdateStrategies::update_phase_t::POST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenDirector::update(MM::Engine& engine) {
|
void ScreenDirector::update(MM::Engine& engine) {
|
||||||
if (curr_screen_id != queued_screen_id) {
|
if (curr_screen_id != queued_screen_id) {
|
||||||
engine.getUpdateStrategy().addDeferred([this](MM::Engine& e) {
|
engine.getUpdateStrategy().addDeferred([this](MM::Engine& e) {
|
||||||
|
@ -12,11 +12,9 @@ class ScreenDirector : public Service {
|
|||||||
const char* name(void) override { return "ScreenDirector"; }
|
const char* name(void) override { return "ScreenDirector"; }
|
||||||
|
|
||||||
// enable switches to queued_screen_index
|
// enable switches to queued_screen_index
|
||||||
bool enable(MM::Engine&) override;
|
bool enable(MM::Engine&, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(MM::Engine&) override;
|
void disable(MM::Engine&) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Screen {
|
struct Screen {
|
||||||
// lists of services relevant for this screen, disable and enable are called when its changed to
|
// lists of services relevant for this screen, disable and enable are called when its changed to
|
||||||
|
@ -7,7 +7,7 @@ class TestService1 : public MM::Services::Service {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestService1"; }
|
const char* name(void) override { return "TestService1"; }
|
||||||
|
|
||||||
bool enable(MM::Engine&) override { return true; }
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>&) override { return true; }
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ class TestService2 : public MM::Services::Service {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestService2"; }
|
const char* name(void) override { return "TestService2"; }
|
||||||
|
|
||||||
bool enable(MM::Engine&) override { return true; }
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>&) override { return true; }
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ class TestServiceInterface : public MM::Services::Service {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestServiceInterface"; }
|
const char* name(void) override { return "TestServiceInterface"; }
|
||||||
|
|
||||||
bool enable(MM::Engine&) override { return true; }
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>&) override { return true; }
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -34,7 +34,7 @@ class TestServiceInterfaceImpl1 : public TestServiceInterface {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestServiceInterfaceImpl1"; }
|
const char* name(void) override { return "TestServiceInterfaceImpl1"; }
|
||||||
|
|
||||||
bool enable(MM::Engine&) override { return true; }
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>&) override { return true; }
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -47,7 +47,7 @@ class TestServiceInterfaceImpl2 : public TestServiceInterface {
|
|||||||
public:
|
public:
|
||||||
const char* name(void) override { return "TestServiceInterfaceImpl2"; }
|
const char* name(void) override { return "TestServiceInterfaceImpl2"; }
|
||||||
|
|
||||||
bool enable(MM::Engine&) override { return true; }
|
bool enable(MM::Engine&, std::vector<MM::UpdateStrategies::TaskInfo>&) override { return true; }
|
||||||
void disable(MM::Engine&) override {}
|
void disable(MM::Engine&) override {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "./sdl_service.hpp"
|
#include "./sdl_service.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
#include "mm/update_strategies/update_strategy.hpp"
|
||||||
|
|
||||||
#include <entt/core/hashed_string.hpp>
|
#include <entt/core/hashed_string.hpp>
|
||||||
|
|
||||||
@ -70,19 +72,14 @@ SDLService::~SDLService(void) {
|
|||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> SDLService::registerUpdates(void) {
|
bool SDLService::enable(Engine&, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
using namespace entt::literals;
|
// add task
|
||||||
return {
|
task_array.push_back(
|
||||||
{
|
UpdateStrategies::TaskInfo{"SDLService::events"}
|
||||||
"SDLService::events"_hs,
|
.phase(UpdateStrategies::update_phase_t::PRE)
|
||||||
"SDLService::events",
|
.fn([this](Engine& e) { this->processEvents(e); })
|
||||||
[this](Engine& e) { this->processEvents(e); },
|
);
|
||||||
UpdateStrategies::update_phase_t::PRE
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SDLService::enable(Engine&) {
|
|
||||||
bool succ = true;
|
bool succ = true;
|
||||||
return succ;
|
return succ;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,7 @@ namespace MM::Services {
|
|||||||
~SDLService(void);
|
~SDLService(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
|
||||||
void disable(Engine& engine) override; // destroys windows and ass contexts
|
void disable(Engine& engine) override; // destroys windows and ass contexts
|
||||||
|
|
||||||
const char* name(void) override { return "SDLService"; }
|
const char* name(void) override { return "SDLService"; }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "./simple_scene.hpp"
|
#include "./simple_scene.hpp"
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
|
|
||||||
#include <mm/components/time_delta.hpp>
|
#include <mm/components/time_delta.hpp>
|
||||||
|
|
||||||
@ -12,7 +13,18 @@
|
|||||||
|
|
||||||
namespace MM::Services {
|
namespace MM::Services {
|
||||||
|
|
||||||
bool SimpleSceneService::enable(Engine& engine) {
|
bool SimpleSceneService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
|
// add tasks
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"SimpleSceneService::scene_tick"}
|
||||||
|
.fn([this](Engine& e) { sceneFixedUpdate(e); })
|
||||||
|
);
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"SimpleSceneService::scene_change"}
|
||||||
|
.succeed("SimpleSceneService::scene_tick")
|
||||||
|
.fn([this](Engine& e) { changeSceneFixedUpdate(e); })
|
||||||
|
);
|
||||||
|
|
||||||
// default scene
|
// default scene
|
||||||
if (!_scene) {
|
if (!_scene) {
|
||||||
_scene = std::make_unique<Scene>();
|
_scene = std::make_unique<Scene>();
|
||||||
@ -27,29 +39,6 @@ bool SimpleSceneService::enable(Engine& engine) {
|
|||||||
void SimpleSceneService::disable(Engine&) {
|
void SimpleSceneService::disable(Engine&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> SimpleSceneService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"SimpleSceneService::scene_tick"_hs,
|
|
||||||
"SimpleSceneService::scene_tick",
|
|
||||||
[this](Engine& e) { this->sceneFixedUpdate(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
{} // no dependencies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"SimpleSceneService::scene_change"_hs,
|
|
||||||
"SimpleSceneService::scene_change",
|
|
||||||
[this](Engine& e) { this->changeSceneFixedUpdate(e); },
|
|
||||||
UpdateStrategies::update_phase_t::MAIN,
|
|
||||||
true,
|
|
||||||
//{"SimpleSceneService::scene_update"_hs} // first update, than change????
|
|
||||||
{"SimpleSceneService::scene_tick"_hs}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void SimpleSceneService::sceneFixedUpdate(Engine&) {
|
void SimpleSceneService::sceneFixedUpdate(Engine&) {
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <mm/services/scene_service_interface.hpp>
|
#include <mm/services/scene_service_interface.hpp>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -26,11 +27,9 @@ namespace MM::Services {
|
|||||||
|
|
||||||
const char* name(void) override { return "SimpleSceneService"; }
|
const char* name(void) override { return "SimpleSceneService"; }
|
||||||
|
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sceneFixedUpdate(Engine& engine);
|
void sceneFixedUpdate(Engine& engine);
|
||||||
void changeSceneFixedUpdate(Engine& engine);
|
void changeSceneFixedUpdate(Engine& engine);
|
||||||
|
@ -20,7 +20,7 @@ SimpleSDLRendererService::SimpleSDLRendererService(void) {
|
|||||||
SimpleSDLRendererService::~SimpleSDLRendererService(void) {
|
SimpleSDLRendererService::~SimpleSDLRendererService(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SimpleSDLRendererService::enable(Engine& engine) {
|
bool SimpleSDLRendererService::enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) {
|
||||||
auto* sdl_ss = engine.tryService<SDLService>();
|
auto* sdl_ss = engine.tryService<SDLService>();
|
||||||
if (!sdl_ss) {
|
if (!sdl_ss) {
|
||||||
LOG_ERROR("SimpleSDLRendererService requires SDLService in engine!");
|
LOG_ERROR("SimpleSDLRendererService requires SDLService in engine!");
|
||||||
@ -46,6 +46,13 @@ bool SimpleSDLRendererService::enable(Engine& engine) {
|
|||||||
|
|
||||||
targets["display"].reset(renderer, 800, 600);
|
targets["display"].reset(renderer, 800, 600);
|
||||||
|
|
||||||
|
// add tasks
|
||||||
|
task_array.push_back(
|
||||||
|
UpdateStrategies::TaskInfo{"SimpleSDLRendererService::render"}
|
||||||
|
.phase(UpdateStrategies::update_phase_t::POST)
|
||||||
|
.fn([this](Engine& e){ this->render(e); })
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,18 +64,6 @@ void SimpleSDLRendererService::disable(Engine&) {
|
|||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> SimpleSDLRendererService::registerUpdates(void) {
|
|
||||||
using namespace entt::literals;
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
"SimpleSDLRendererService::render"_hs,
|
|
||||||
"SimpleSDLRendererService::render",
|
|
||||||
[this](Engine& e){ this->render(e); },
|
|
||||||
UpdateStrategies::update_phase_t::POST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void SimpleSDLRendererService::render(Engine& engine) {
|
void SimpleSDLRendererService::render(Engine& engine) {
|
||||||
targets["display"].clear(renderer, {40, 40, 40, 255});
|
targets["display"].clear(renderer, {40, 40, 40, 255});
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "mm/services/service.hpp"
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include <mm/engine.hpp>
|
#include <mm/engine.hpp>
|
||||||
@ -23,14 +24,11 @@ namespace MM::Services {
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine& engine) override;
|
bool enable(Engine& engine, std::vector<UpdateStrategies::TaskInfo>& task_array) override;
|
||||||
void disable(Engine& engine) override;
|
void disable(Engine& engine) override;
|
||||||
|
|
||||||
const char* name(void) override { return "SimpleSDLServiceSystem"; };
|
const char* name(void) override { return "SimpleSDLServiceSystem"; };
|
||||||
|
|
||||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render(Engine& engine);
|
void render(Engine& engine);
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ SoundService::SoundService(void) : engine() {
|
|||||||
SoundService::~SoundService(void) {
|
SoundService::~SoundService(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundService::enable(Engine&) {
|
bool SoundService::enable(Engine&, std::vector<UpdateStrategies::TaskInfo>&) {
|
||||||
unsigned int flags = SoLoud::Soloud::CLIP_ROUNDOFF;
|
unsigned int flags = SoLoud::Soloud::CLIP_ROUNDOFF;
|
||||||
auto r = engine.init(flags);
|
auto r = engine.init(flags);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
|
@ -11,7 +11,7 @@ namespace MM::Services {
|
|||||||
SoLoud::Soloud engine;
|
SoLoud::Soloud engine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool enable(Engine&) override;
|
bool enable(Engine&, std::vector<UpdateStrategies::TaskInfo>&) override;
|
||||||
void disable(Engine&) override;
|
void disable(Engine&) override;
|
||||||
|
|
||||||
const char* name(void) override { return "SoundService"; }
|
const char* name(void) override { return "SoundService"; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user