Added Script Core

This commit is contained in:
OusmBlueNinja 2025-05-08 00:28:23 -05:00
parent 0e7913d3de
commit 3ab114208b
12 changed files with 1838 additions and 1606 deletions

View File

@ -21,7 +21,7 @@ DockId=0x00000018,0
[Window][Scene Tree] [Window][Scene Tree]
Pos=0,19 Pos=0,19
Size=335,579 Size=335,461
Collapsed=0 Collapsed=0
DockId=0x0000001B,0 DockId=0x0000001B,0
@ -43,7 +43,7 @@ DockId=0x00000019,0
[Window][Console] [Window][Console]
Pos=337,680 Pos=337,680
Size=1238,497 Size=1238,273
Collapsed=0 Collapsed=0
DockId=0x00000013,0 DockId=0x00000013,0
@ -54,8 +54,8 @@ Collapsed=0
DockId=0x00000017,1 DockId=0x00000017,1
[Window][Profiler] [Window][Profiler]
Pos=482,955 Pos=337,955
Size=1068,222 Size=1238,222
Collapsed=0 Collapsed=0
DockId=0x00000014,0 DockId=0x00000014,0
@ -90,8 +90,8 @@ Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
[Window][Confirm Deletion] [Window][Confirm Deletion]
Pos=787,416 Pos=764,456
Size=325,75 Size=325,96
Collapsed=0 Collapsed=0
[Window][Audio VU] [Window][Audio VU]

View File

@ -1 +1,5 @@
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\core\scripts\ScriptCore.cpp -o src\build\core\scripts\ScriptCore.o
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\Engine.cpp -o src\build\Engine.o [COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -Isrc/vendor/xxhash -Isrc/vendor/miniaudio -Isrc/vendor/imguizmo -IC:/msys64/mingw64/include -Isrc\vendor\imgui -IC:\msys64\mingw64\lib\libyaml-cpp.a -MMD -MP -c src\src\Engine.cpp -o src\build\Engine.o
[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\AudioPlayerComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\functions\Prefab.o src\build\core\functions\ScenePacker.o src\build\core\scripts\LuaGlobalBridge.o src\build\core\scripts\ScriptCore.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Popup.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\AudioInfo.o src\build\editor\windows\Inspector.o src\build\editor\windows\LuaGlobals.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o src\build\miniaudio.o src\build\ImGuizmo.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto -ldbghelp -lz
[ERROR] Runtime crash
Command 'src\build\app.exe' returned non-zero exit status 3221225477.

View File

@ -47,10 +47,13 @@ function OnUpdate(dt)
if Engine.KeyDown(Keycode.Equal) or Engine.KeyDown(Keycode.KPAdd) then if Engine.KeyDown(Keycode.Equal) or Engine.KeyDown(Keycode.KPAdd) then
Speed = Speed + 100 * dt Speed = Speed + 100 * dt
Engine.LogInfo(string.format("Speed increased to %.1f", Speed)) Engine.LogInfo(string.format("Speed increased to %.1f", Speed))
Engine.SetGlobal("speed", Speed)
elseif Engine.KeyDown(Keycode.Minus) or Engine.KeyDown(Keycode.KPSubtract) then elseif Engine.KeyDown(Keycode.Minus) or Engine.KeyDown(Keycode.KPSubtract) then
Speed = Speed - 100 * dt Speed = Speed - 100 * dt
if Speed < 0 then Speed = 0 end if Speed < 0 then Speed = 0 end
Engine.LogInfo(string.format("Speed decreased to %.1f", Speed)) Engine.LogInfo(string.format("Speed decreased to %.1f", Speed))
Engine.SetGlobal("speed", Speed)
end end
-- update light positions -- update light positions

View File

@ -0,0 +1,38 @@
-- Called once on load
function OnInit()
player = Engine.GetObjectByTag("PlayerRoot")
if not player then
Engine.LogError("PlayerRoot not found!")
return
end
if Engine.GetGlobal("player_health") == nil then
Engine.SetGlobal("player_health", 100)
end
end
-- Called every frame
function OnUpdate(dt)
if not player then return end
local speed = 200
local move = { x = 0, y = 0 }
if Engine.KeyDown(Keycode.W) then move.y = move.y - 1 end
if Engine.KeyDown(Keycode.S) then move.y = move.y + 1 end
if Engine.KeyDown(Keycode.A) then move.x = move.x - 1 end
if Engine.KeyDown(Keycode.D) then move.x = move.x + 1 end
local pos = player:GetPosition()
pos.x = pos.x + move.x * speed * dt
pos.y = pos.y + move.y * speed * dt
player:SetPosition(pos)
-- Simulate damage each second
local hp = Engine.GetGlobal("player_health") or 100
hp = hp - dt * 5
Engine.SetGlobal("player_health", hp)
-- Debug print
Engine.LogDebug(string.format("HP: %.1f", hp))
end

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include "../core/types/vec3.h" #include "../core/types/vec3.h"
#include "../core/scripts/LuaGlobalBridge.h" #include "../core/scripts/LuaGlobalBridge.h"
#include "../core/scripts/ScriptCore.h"
static int Lua_SetGlobal(lua_State *L) static int Lua_SetGlobal(lua_State *L)
{ {
@ -116,7 +117,10 @@ ScriptComponent::ScriptComponent(Object *owner) : Component(owner), L(nullptr) {
ScriptComponent::~ScriptComponent() ScriptComponent::~ScriptComponent()
{ {
if (L) if (L)
{
ScriptCore::UnregisterState(L);
lua_close(L); lua_close(L);
}
} }
void ScriptComponent::SetScriptPath(const std::string &path) void ScriptComponent::SetScriptPath(const std::string &path)
@ -1012,13 +1016,18 @@ void ScriptComponent::ReloadScript()
if (scriptPath.empty()) if (scriptPath.empty())
return; return;
if (L) if (L)
{
ScriptCore::UnregisterState(L);
lua_close(L); lua_close(L);
}
L = luaL_newstate(); L = luaL_newstate();
*(ScriptComponent **)lua_getextraspace(L) = this; *(ScriptComponent **)lua_getextraspace(L) = this;
luaL_openlibs(L); luaL_openlibs(L);
lua_sethook(L, Hook, LUA_MASKCALL | LUA_MASKRET, 0); lua_sethook(L, Hook, LUA_MASKCALL | LUA_MASKRET, 0);
ScriptCore::RegisterState(L, scriptPath, GetFilenameNoExtension(scriptPath));
RegisterObjectType(L); RegisterObjectType(L);
RegisterVector2Type(L); RegisterVector2Type(L);
RegisterVector3Type(L); RegisterVector3Type(L);
@ -1036,20 +1045,6 @@ void ScriptComponent::ReloadScript()
RecoverableError("Failed to load Lua script: " + scriptPath, Create::Exceptions::ComponentLoad).Handle(); RecoverableError("Failed to load Lua script: " + scriptPath, Create::Exceptions::ComponentLoad).Handle();
return; return;
} }
if (luaDebugEnabled)
Logger::LogVerbose("[Lua][call] OnInit()");
lua_getglobal(L, "OnInit");
if (lua_isfunction(L, -1))
{
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
{
Logger::LogError("[Lua] %s", lua_tostring(L, -1));
RecoverableError("OnInit failed: " + scriptPath, Create::Exceptions::ComponentLoad).Handle();
}
}
else
lua_pop(L, 1);
} }
void ScriptComponent::OnUpdate(float dt) void ScriptComponent::OnUpdate(float dt)

View File

@ -13,6 +13,7 @@
#include "core/utils/FileDialog.h" #include "core/utils/FileDialog.h"
#include "core/utils/Logging.h" #include "core/utils/Logging.h"
#include "core/utils/Input.h" #include "core/utils/Input.h"
#include "core/scripts/ScriptCore.h"
#include "core/audio/AudioEngine.h" #include "core/audio/AudioEngine.h"
@ -437,7 +438,9 @@ void DrawGizmoForObject(const std::shared_ptr<Object> &obj,
const glm::mat4 &view, const glm::mat4 &view,
const glm::mat4 &projection) const glm::mat4 &projection)
{ {
if (!obj) ImGuizmo::BeginFrame();
if (!obj || playing)
return; return;
// Model matrix at z = 1 to avoid clipping // Model matrix at z = 1 to avoid clipping
@ -446,16 +449,19 @@ void DrawGizmoForObject(const std::shared_ptr<Object> &obj,
ImGuizmo::SetOrthographic(true); ImGuizmo::SetOrthographic(true);
ImGuizmo::SetDrawlist(); ImGuizmo::SetDrawlist();
ImVec2 winPos = ImGui::GetWindowPos(); ImVec2 windowPos = ImGui::GetWindowPos();
ImVec2 winSize = ImGui::GetWindowSize(); ImVec2 windowSize = ImGui::GetWindowSize();
ImGuizmo::SetRect(winPos.x, winPos.y, winSize.x, winSize.y); ImGuizmo::SetRect(windowPos.x, windowPos.y, windowSize.x, windowSize.y);
static ImGuizmo::OPERATION op = ImGuizmo::TRANSLATE; static ImGuizmo::OPERATION op = ImGuizmo::TRANSLATE;
if (ImGui::IsKeyPressed(ImGuiKey_T)) if (ImGui::IsWindowFocused() && ImGui::IsWindowHovered())
op = ImGuizmo::TRANSLATE; {
if (ImGui::IsKeyPressed(ImGuiKey_R)) if (ImGui::IsKeyPressed(ImGuiKey_T))
op = ImGuizmo::ROTATE; op = ImGuizmo::TRANSLATE;
if (ImGui::IsKeyPressed(ImGuiKey_R))
op = ImGuizmo::ROTATE;
}
glm::mat4 manipulated = model; glm::mat4 manipulated = model;
ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection),
@ -463,14 +469,12 @@ void DrawGizmoForObject(const std::shared_ptr<Object> &obj,
if (ImGuizmo::IsUsing()) if (ImGuizmo::IsUsing())
{ {
Logger::LogInfo("adasd"); auto pos = core::types::Vec3(manipulated[3]);
glm::vec3 t, r, s;
ImGuizmo::DecomposeMatrixToComponents(glm::value_ptr(manipulated), float angleRadians = atan2(manipulated[1][0], manipulated[0][0]); // M10, M00
glm::value_ptr(t),
glm::value_ptr(r), obj->SetLocalPosition({pos.x, pos.y});
glm::value_ptr(s)); obj->SetLocalRotation(glm::degrees(angleRadians)); // Z
obj->SetLocalPosition({t.x, t.y});
obj->SetLocalRotation(r.z);
} }
} }
@ -578,7 +582,6 @@ void Engine::Init()
// These values were AI Generated. // These values were AI Generated.
m_toDraw.reserve(2048); // ~2K sprites per frame (including UI, particles, objects) m_toDraw.reserve(2048); // ~2K sprites per frame (including UI, particles, objects)
m_scriptUpdates.reserve(256); // ~256 active script components per frame
m_collectStack.reserve(2048); // Used for internal temp memory, 512 is safe unless deep recursion m_collectStack.reserve(2048); // Used for internal temp memory, 512 is safe unless deep recursion
m_physicsUpdates.reserve(512); // 256-512 physics bodies/entities with Box2D m_physicsUpdates.reserve(512); // 256-512 physics bodies/entities with Box2D
m_particleUpdates.reserve(24); // ~1K particle systems active is fair in effects-heavy scenes m_particleUpdates.reserve(24); // ~1K particle systems active is fair in effects-heavy scenes
@ -600,7 +603,6 @@ void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom
m_activeCamera = nullptr; m_activeCamera = nullptr;
m_toDraw.clear(); m_toDraw.clear();
m_scriptUpdates.clear();
m_animationsUpdates.clear(); m_animationsUpdates.clear();
m_collectStack.clear(); m_collectStack.clear();
m_physicsUpdates.clear(); m_physicsUpdates.clear();
@ -645,8 +647,6 @@ void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom
if (playing) if (playing)
{ {
if (auto script = obj->GetComponent<ScriptComponent>())
m_scriptUpdates.push_back(script.get());
if (auto physics = obj->GetComponent<PhysicsComponent>()) if (auto physics = obj->GetComponent<PhysicsComponent>())
m_physicsUpdates.push_back(physics.get()); m_physicsUpdates.push_back(physics.get());
@ -827,8 +827,7 @@ void Engine::Run()
ImGui::Begin("Scene Tree"); ImGui::Begin("Scene Tree");
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && if (ImGui::IsKeyPressed(ImGuiKey_Delete) && selected)
ImGui::IsKeyPressed(ImGuiKey_Delete) && selected)
{ {
ImGui::OpenPopup("Confirm Deletion"); ImGui::OpenPopup("Confirm Deletion");
} }
@ -836,6 +835,9 @@ void Engine::Run()
if (ImGui::BeginPopupModal("Confirm Deletion", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) if (ImGui::BeginPopupModal("Confirm Deletion", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::Text("Are you sure you want to delete this object?"); ImGui::Text("Are you sure you want to delete this object?");
ImGui::Spacing();
ImGui::Text("%s", selected->GetName().c_str());
ImGui::Separator(); ImGui::Separator();
if (ImGui::Button("Delete")) if (ImGui::Button("Delete"))
@ -903,6 +905,7 @@ void Engine::Run()
editorCameraSavedZoom = cameraZoom; editorCameraSavedZoom = cameraZoom;
editorCameraWasSaved = true; editorCameraWasSaved = true;
LuaGlobalBridge::Clear(); LuaGlobalBridge::Clear();
ScriptCore::CallAllInits();
} }
else if (!playing && lastPlaying && editorCameraWasSaved) else if (!playing && lastPlaying && editorCameraWasSaved)
{ {
@ -964,7 +967,6 @@ void Engine::Run()
m_toDraw.reserve(m_Reserved_draws); m_toDraw.reserve(m_Reserved_draws);
m_Reserved_draws = 0; m_Reserved_draws = 0;
m_toDraw.clear(); m_toDraw.clear();
m_scriptUpdates.clear();
m_particleUpdates.clear(); m_particleUpdates.clear();
profiler.EndEngineSection(); profiler.EndEngineSection();
@ -998,13 +1000,12 @@ void Engine::Run()
profiler.BeginSection("Updates"); profiler.BeginSection("Updates");
profiler.BeginSection("Scripts"); profiler.BeginSection("Scripts");
for (auto *script : m_scriptUpdates)
if (playing)
{ {
profiler.BeginSection("Object: " + script->GetOwner()->GetName()); ScriptCore::CallAllUpdates(deltaTime);
script->OnUpdate(deltaTime);
m_OnUpdateCalls++;
profiler.EndSection();
} }
profiler.EndSection(); profiler.EndSection();
profiler.BeginSection("Particles"); profiler.BeginSection("Particles");
@ -1358,6 +1359,11 @@ void Engine::Run()
for (auto &obj : pendingDeletion) for (auto &obj : pendingDeletion)
{ {
if (selected == obj)
{
selected = nullptr;
}
Logger::LogVerbose("Deleting Object From Que: '%s', [%d, %s]", obj->GetName().c_str(), obj->uid.id, obj->uid.uuid.c_str()); Logger::LogVerbose("Deleting Object From Que: '%s', [%d, %s]", obj->GetName().c_str(), obj->uid.id, obj->uid.uuid.c_str());
if (obj->GetParent()) if (obj->GetParent())
obj->GetParent()->RemoveChild(obj.get()); obj->GetParent()->RemoveChild(obj.get());

View File

@ -39,7 +39,6 @@ private:
int m_Reserved_draws; int m_Reserved_draws;
std::vector<Object *> m_toDraw; std::vector<Object *> m_toDraw;
std::vector<ScriptComponent *> m_scriptUpdates;
std::vector<AnimationComponent *> m_animationsUpdates; std::vector<AnimationComponent *> m_animationsUpdates;
int m_OnUpdateCalls; int m_OnUpdateCalls;

View File

@ -0,0 +1,89 @@
#include "ScriptCore.h"
#include "../../core/utils/Logging.h"
#include "../../core/utils/ExceptionHandler.h"
#include "../../core/utils/Profiler.h"
void ScriptCore::Init()
{
s_LuaStates.clear();
}
void ScriptCore::RegisterState(lua_State* L, const std::string& scriptPath, const std::string& name)
{
s_LuaStates.push_back({ L, scriptPath, name });
}
void ScriptCore::UnregisterState(lua_State* L)
{
auto it = std::remove_if(s_LuaStates.begin(), s_LuaStates.end(),
[L](const LuaScript& script) {
return script.L == L;
});
if (it != s_LuaStates.end())
{
Logger::LogVerbose("[ScriptCore] Unregistered Lua state");
s_LuaStates.erase(it, s_LuaStates.end());
}
else
{
Logger::LogWarning("[ScriptCore] Tried to unregister unknown Lua state");
}
}
void ScriptCore::CallAllInits()
{
for (auto& script : s_LuaStates)
{
PROFILE_DEEP_SCOPE("ScriptCore::OnInit");
if (!script.L)
continue;
lua_getglobal(script.L, "OnInit");
if (lua_isfunction(script.L, -1))
{
if (lua_pcall(script.L, 0, 0, 0) != LUA_OK)
{
Logger::LogError("[Lua] %s", lua_tostring(script.L, -1));
RecoverableError("OnInit failed in: " + script.scriptPath, Create::Exceptions::ComponentLoad).Handle();
lua_pop(script.L, 1);
}
}
else
{
lua_pop(script.L, 1);
}
}
}
void ScriptCore::CallAllUpdates(float dt)
{
PROFILE_DEEP_SCOPE("ScriptCore::OnUpdate");
for (auto& script : s_LuaStates)
{
PROFILE_SCOPE("Script: " + script.name);
if (!script.L)
continue;
lua_getglobal(script.L, "OnUpdate");
if (lua_isfunction(script.L, -1))
{
lua_pushnumber(script.L, dt);
if (lua_pcall(script.L, 1, 0, 0) != LUA_OK)
{
Logger::LogError("[Lua] %s", lua_tostring(script.L, -1));
RecoverableError("OnUpdate failed in: " + script.scriptPath, Create::Exceptions::ComponentLoad).Handle();
lua_pop(script.L, 1);
}
}
else
{
lua_pop(script.L, 1);
}
}
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <vector>
#include <string>
#include <lua.hpp>
class ScriptCore
{
public:
static void Init();
static void RegisterState(lua_State* L, const std::string& scriptPath, const std::string& name);
static void UnregisterState(lua_State* L);
static void CallAllInits();
static void CallAllUpdates(float dt);
private:
struct LuaScript
{
lua_State* L;
std::string scriptPath;
std::string name;
};
static inline std::vector<LuaScript> s_LuaStates;
};

View File

@ -12,7 +12,7 @@
//! Macro Fuckery my Gz //! Macro Fuckery my Gz
EngineConfig g_engineConfig{ EngineConfig g_engineConfig{
.version = "0.8.3", .version = "0.8.4",
.gl_version = "430", .gl_version = "430",
.gl_maxLight = 512, .gl_maxLight = 512,
.settings = UserSettings{} .settings = UserSettings{}

View File

@ -19,35 +19,50 @@ void DrawImGuiWindow()
} }
else else
{ {
ImGui::Text("Active Globals:"); ImGui::Text("Active Globals");
ImGui::Separator(); ImGui::Separator();
ImGui::Columns(2, nullptr, false); // 3 columns: Key | Type | Value
ImGui::SetColumnWidth(0, 160); ImGui::Columns(3, nullptr, false);
ImGui::SetColumnWidth(0, 180);
ImGui::SetColumnWidth(1, 80);
ImGui::TextColored(ImVec4(1, 1, 0.4f, 1), "Key"); ImGui::TextColored(ImVec4(1, 1, 0.4f, 1), "Key");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::TextColored(ImVec4(0.7f, 1, 0.7f, 1), "Type");
ImGui::NextColumn();
ImGui::TextColored(ImVec4(1, 1, 0.4f, 1), "Value"); ImGui::TextColored(ImVec4(1, 1, 0.4f, 1), "Value");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Separator(); ImGui::Separator();
for (const auto& [key, value] : allGlobals) for (const auto& [key, value] : allGlobals)
{ {
std::string typeStr;
std::string valueStr; std::string valueStr;
std::visit([&](auto&& val) { std::visit([&](auto&& val) {
using T = std::decay_t<decltype(val)>; using T = std::decay_t<decltype(val)>;
if constexpr (std::is_same_v<T, double>) if constexpr (std::is_same_v<T, double>) {
typeStr = "number";
valueStr = std::to_string(val); valueStr = std::to_string(val);
else if constexpr (std::is_same_v<T, bool>) }
else if constexpr (std::is_same_v<T, bool>) {
typeStr = "bool";
valueStr = val ? "true" : "false"; valueStr = val ? "true" : "false";
else if constexpr (std::is_same_v<T, std::string>) }
else if constexpr (std::is_same_v<T, std::string>) {
typeStr = "string";
valueStr = val; valueStr = val;
}
}, value); }, value);
ImGui::TextUnformatted(key.c_str()); ImGui::TextUnformatted(key.c_str());
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::TextUnformatted(valueStr.c_str());
ImGui::TextColored(ImVec4(0.7f, 0.9f, 1.0f, 1.0f), typeStr.c_str());
ImGui::NextColumn();
ImGui::TextWrapped("%s", valueStr.c_str());
ImGui::NextColumn(); ImGui::NextColumn();
} }