mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2024-12-04 19:23:28 +01:00
add organizer scene, and add scene tools time delta context editor
This commit is contained in:
parent
9bcaf87788
commit
39b0677c3a
@ -9,6 +9,7 @@ add_subdirectory(std_utils)
|
||||
add_subdirectory(screen_director)
|
||||
add_subdirectory(filesystem)
|
||||
add_subdirectory(simple_scene)
|
||||
add_subdirectory(organizer_scene)
|
||||
|
||||
if(NOT MM_HEADLESS)
|
||||
add_subdirectory(sdl_service)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <mm/engine.hpp>
|
||||
#include "./imgui_menu_bar.hpp"
|
||||
#include "mm/components/time_delta.hpp"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
@ -70,6 +71,17 @@ namespace MM::Services {
|
||||
ImGui::MenuItem("Camera3D Tool", NULL, &_show_camera_tool);
|
||||
};
|
||||
|
||||
menu_bar.menu_tree["Scene"]["TimeCtx"] = [this](Engine& e) {
|
||||
MM::Components::TimeDelta* td_ptr = nullptr;
|
||||
|
||||
if (auto* ssi_ptr = e.tryService<MM::Services::SceneServiceInterface>()) {
|
||||
auto& scene = ssi_ptr->getScene();
|
||||
td_ptr = scene.try_ctx<MM::Components::TimeDelta>();
|
||||
}
|
||||
|
||||
ImGui::MenuItem("TimeDelta Context", NULL, &_show_time_delta_ctx, td_ptr);
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -78,6 +90,8 @@ namespace MM::Services {
|
||||
|
||||
menu_bar.menu_tree["Scene"].erase("Metrics");
|
||||
menu_bar.menu_tree["Scene"].erase("EntityEditor");
|
||||
menu_bar.menu_tree["Scene"].erase("CameraTool");
|
||||
menu_bar.menu_tree["Scene"].erase("TimeCtx");
|
||||
}
|
||||
|
||||
std::vector<UpdateStrategies::UpdateCreationInfo> ImGuiSceneToolsService::registerUpdates(void) {
|
||||
@ -97,15 +111,6 @@ namespace MM::Services {
|
||||
}
|
||||
|
||||
void ImGuiSceneToolsService::renderImGui(Engine& engine) {
|
||||
//if (show_menu && ImGui::BeginMainMenuBar()) {
|
||||
|
||||
//if (ImGui::BeginMenu("Windows")) {
|
||||
//ImGui::MenuItem("Camera Tool", NULL, &_show_camera_tool);
|
||||
//ImGui::EndMenu();
|
||||
//}
|
||||
|
||||
//}
|
||||
|
||||
auto& scene = engine.tryService<MM::Services::SceneServiceInterface>()->getScene();
|
||||
|
||||
if (_show_scene_metrics) {
|
||||
@ -150,6 +155,16 @@ namespace MM::Services {
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (_show_time_delta_ctx) {
|
||||
if (ImGui::Begin("Scene TimeDelta Context", &_show_time_delta_ctx)) {
|
||||
auto* td_ptr = scene.try_ctx<MM::Components::TimeDelta>();
|
||||
ImGui::Value("tickDelta", td_ptr->tickDelta);
|
||||
ImGui::SliderFloat("deltaFactor", &td_ptr->deltaFactor, 0.f, 10.f, "%.5f", ImGuiSliderFlags_Logarithmic);
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
EntityEditor<Entity>& ImGuiSceneToolsService::getEntityEditor(void) {
|
||||
|
@ -23,6 +23,7 @@ namespace MM::Services {
|
||||
bool _show_entity_editor = false;
|
||||
bool _show_entity_list = true;
|
||||
bool _show_camera_tool = false;
|
||||
bool _show_time_delta_ctx = false;
|
||||
|
||||
EntityEditor<Entity> _entity_editor;
|
||||
// for list
|
||||
|
19
framework/organizer_scene/CMakeLists.txt
Normal file
19
framework/organizer_scene/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
project(organizer_scene CXX)
|
||||
|
||||
add_library(organizer_scene
|
||||
src/mm/services/organizer_scene.hpp
|
||||
src/mm/services/organizer_scene.cpp
|
||||
)
|
||||
|
||||
target_include_directories(organizer_scene PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
|
||||
target_link_libraries(organizer_scene
|
||||
engine
|
||||
common_components
|
||||
)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
#add_subdirectory(test)
|
||||
endif()
|
||||
|
174
framework/organizer_scene/src/mm/services/organizer_scene.cpp
Normal file
174
framework/organizer_scene/src/mm/services/organizer_scene.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
#include "./organizer_scene.hpp"
|
||||
|
||||
#include <mm/components/time_delta.hpp>
|
||||
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <entt/entity/organizer.hpp>
|
||||
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#include <spdlog/fmt/ostr.h>
|
||||
#define LOG_OSS(x) LOG("OrganizerSceneService", x)
|
||||
|
||||
namespace entt {
|
||||
|
||||
// graphviz dot export
|
||||
static std::ostream& operator<<(std::ostream& out, const std::vector<entt::organizer::vertex>& nodes) {
|
||||
out << "digraph EnTT_organizer {\nrankdir=RL;\n";
|
||||
|
||||
|
||||
for (size_t i = 0; i < nodes.size(); i++) {
|
||||
out << "n" << i << "[shape=" << (nodes[i].top_level() ? "doublecircle" : "circle") << " label=\"" << (nodes[i].name() == nullptr ? "NoName" : nodes[i].name()) << "\"];\n";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nodes.size(); i++) {
|
||||
for (const size_t child : nodes[i].children()) {
|
||||
out << "n" << child << " -> " << "n" << i << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
out << "}";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // entt
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
bool OrganizerSceneService::enable(Engine& engine) {
|
||||
// default scene
|
||||
if (!_scene) {
|
||||
_scene = std::make_unique<Scene>();
|
||||
_scene->set<MM::Engine*>(&engine);
|
||||
updateOrganizerVertices(*_scene);
|
||||
}
|
||||
|
||||
resetTime();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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&) {
|
||||
ZoneScoped;
|
||||
|
||||
auto newNow = clock::now();
|
||||
auto deltaTime = std::chrono::duration_cast<std::chrono::nanoseconds>(newNow - _last_time);
|
||||
_last_time = newNow;
|
||||
_accumulator += deltaTime.count();
|
||||
const double dt = f_delta * 1'000'000'000.0;
|
||||
|
||||
size_t continuous_counter = 0;
|
||||
|
||||
auto& time_ctx = _scene->ctx_or_set<MM::Components::TimeDelta>(f_delta, delta_factor);
|
||||
time_ctx.tickDelta = f_delta * delta_factor;
|
||||
time_ctx.deltaFactor = delta_factor;
|
||||
|
||||
// TODO: this while is just cancer
|
||||
while (_accumulator >= static_cast<decltype(_accumulator)>(dt)){
|
||||
_accumulator -= static_cast<decltype(_accumulator)>(dt);
|
||||
continuous_counter++;
|
||||
|
||||
for (auto&& v : _scene->ctx<std::vector<entt::organizer::vertex>>()) {
|
||||
v.callback()(v.data(), *_scene);
|
||||
}
|
||||
|
||||
TracyPlot("MM::Services::OrganizerSceneService::_scene.alive", (int64_t)_scene->alive());
|
||||
}
|
||||
|
||||
if (continuous_counter > 2) {
|
||||
LOG_OSS(fmt::format("had {} contiguous scene ticks!", continuous_counter));
|
||||
}
|
||||
}
|
||||
|
||||
void OrganizerSceneService::changeSceneFixedUpdate(Engine& engine) {
|
||||
if (_next_scene) {
|
||||
LOG_OSS("changing scene...");
|
||||
_scene = std::move(_next_scene);
|
||||
_scene->set<MM::Engine*>(&engine); // make engine accessible from scene
|
||||
updateOrganizerVertices(*_scene);
|
||||
}
|
||||
}
|
||||
|
||||
void OrganizerSceneService::sceneUpdate(Engine&) {
|
||||
ZoneScoped;
|
||||
|
||||
//if (ImGui::Begin("OrganizerScene")) {
|
||||
//ImGui::SliderFloat("time_factor", &delta_factor, 0.f, 10.f, "%.5f", ImGuiSliderFlags_Logarithmic);
|
||||
//}
|
||||
//ImGui::End();
|
||||
|
||||
//for (auto&& v : _scene->ctx<std::vector<entt::organizer::vertex>>()) {
|
||||
//v.callback()(v.data(), *_scene);
|
||||
//}
|
||||
|
||||
//TracyPlot("MM::Services::OrganizerSceneService::_scene.alive", (int64_t)_scene->alive());
|
||||
}
|
||||
|
||||
void OrganizerSceneService::changeScene(std::unique_ptr<Scene>&& new_scene) {
|
||||
if (_next_scene) {
|
||||
LOG_OSS("warn: already next scene enqueued! overwriting...");
|
||||
}
|
||||
|
||||
_next_scene = std::move(new_scene);
|
||||
}
|
||||
|
||||
void OrganizerSceneService::changeSceneNow(std::unique_ptr<Scene>&& new_scene) {
|
||||
_scene = std::move(new_scene);
|
||||
//_scene->set<MM::Engine*>(&engine); // make engine accessible from scene
|
||||
updateOrganizerVertices(*_scene);
|
||||
}
|
||||
|
||||
void OrganizerSceneService::updateOrganizerVertices(Scene& scene) {
|
||||
scene.ctx_or_set<std::vector<entt::organizer::vertex>>() =
|
||||
scene.ctx_or_set<entt::organizer>().graph();
|
||||
|
||||
if (!scene.try_ctx<MM::Components::TimeDelta>()) {
|
||||
scene.set<MM::Components::TimeDelta>();
|
||||
}
|
||||
|
||||
SPDLOG_DEBUG("graph:\n{}", scene.ctx<std::vector<entt::organizer::vertex>>());
|
||||
}
|
||||
|
||||
void OrganizerSceneService::resetTime(void) {
|
||||
_last_time = clock::now();
|
||||
_accumulator = 0;
|
||||
}
|
||||
|
||||
} // MM::Services
|
||||
|
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/services/scene_service_interface.hpp>
|
||||
#include <entt/fwd.hpp>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace MM::Services {
|
||||
|
||||
// provides an ~implementation for SceneServiceInterface
|
||||
// !! IMPORTANT: relies on entt::organizer. Use it to add systems!
|
||||
class OrganizerSceneService : public SceneServiceInterface {
|
||||
private:
|
||||
std::unique_ptr<Scene> _scene;
|
||||
std::unique_ptr<Scene> _next_scene; // enqueued next scene
|
||||
|
||||
using clock = std::chrono::high_resolution_clock;
|
||||
long long int _accumulator = 0;
|
||||
std::chrono::time_point<clock> _last_time;
|
||||
|
||||
public:
|
||||
const float f_delta;
|
||||
|
||||
float delta_factor = 1.f;
|
||||
|
||||
public: // service
|
||||
explicit OrganizerSceneService(const float update_delta = 1.f/60.f) : f_delta(update_delta) {}
|
||||
|
||||
const char* name(void) override { return "OrganizerSceneService"; }
|
||||
|
||||
bool enable(Engine& engine) override;
|
||||
void disable(Engine& engine) override;
|
||||
|
||||
std::vector<UpdateStrategies::UpdateCreationInfo> registerUpdates(void) override;
|
||||
|
||||
public: // scene interface
|
||||
Scene& getScene(void) override { return *_scene; }
|
||||
|
||||
void changeScene(std::unique_ptr<Scene>&& new_scene) override;
|
||||
|
||||
// be carefull of that one
|
||||
void changeSceneNow(std::unique_ptr<Scene>&& new_scene) override;
|
||||
|
||||
public:
|
||||
void sceneFixedUpdate(Engine& engine);
|
||||
void changeSceneFixedUpdate(Engine& engine);
|
||||
|
||||
void sceneUpdate(Engine& engine);
|
||||
void updateOrganizerVertices(Scene& scene);
|
||||
|
||||
void resetTime(void);
|
||||
};
|
||||
|
||||
} // MM::Services
|
||||
|
Loading…
Reference in New Issue
Block a user