Added widget drawer for module settings

This commit is contained in:
Antoine Pilote
2025-04-02 13:19:30 -04:00
parent 3037813cf4
commit 0f7a9ebfba
5 changed files with 164 additions and 53 deletions

View File

@@ -7,6 +7,7 @@
#include "../../Commands/Commands/Commands.h"
#include <Nuake/Audio/AudioManager.h>
#include <Nuake/Modules/ModuleDB.h>
#include "Nuake/UI/WidgetDrawer.h"
ProjectSettingsCategoryWindowGeneral::ProjectSettingsCategoryWindowGeneral(Ref<Nuake::Project> project) :
m_Project(project)
@@ -212,6 +213,7 @@ ProjectSettingsModuleWindow::ProjectSettingsModuleWindow(const std::string& inMo
void ProjectSettingsModuleWindow::Draw()
{
auto meta = entt::resolve(entt::hashed_string(Name.c_str()));
auto instance = ModuleDB::Get().GetBaseImpl(Name).instance;
for (auto [id, data] : meta.data())
{
auto propDisplayName = data.prop(HashedName::DisplayName);
@@ -220,59 +222,12 @@ void ProjectSettingsModuleWindow::Draw()
auto propVal = propDisplayName.value();
const char* settingName = *propVal.try_cast<const char*>();
auto& drawer = WidgetDrawer::Get();
drawer.DrawWidget(data, instance);
ImGui::Text(settingName);
}
}
for (auto [id, func] : meta.func())
{
auto propDisplayName = func.prop(HashedName::DisplayName);
if (propDisplayName)
{
auto propVal = propDisplayName.value();
const char* settingName = *propVal.try_cast<const char*>();
ImGui::Text(settingName);
}
// Setting
//std::string funcName = "UnknownFunc";
//if (propDisplayName)
//{
// funcName = std::string(*propDisplayName.value().try_cast<const char*>());
//}
//
//std::string msg = std::string(returnType) + " " + std::string(funcName) + "(";
//std::vector<std::string_view> args;
//
//if (func.arity() > 0)
//{
// auto propArgsName = func.prop(HashedName::ArgsName);
// if (propArgsName)
// {
// std::vector<std::string> argsName = *propArgsName.value().try_cast<std::vector<std::string>>();
// for (int i = 0; i < func.arity(); i++)
// {
// const std::string argType = std::string(func.arg(i).info().name());
// args.push_back(argType);
//
// msg += argType + " " + argsName[i];
//
// if (i < func.arity() - 1)
// {
// msg += ", ";
// }
// }
// }
//}
//
//
//msg += ")";
//
//Logger::Log(msg, "", VERBOSE);
}
}
void ProjectSettingsCategoryAudio::Draw()

View File

@@ -62,7 +62,7 @@ void ExampleModuleLog(const std::string& hi)
Nuake::Logger::Log(hi, "ExampleModule", Nuake::VERBOSE);
}
float mySetting = 1.0f;
float mySetting = 8.0f;
NUAKEMODULE(ExampleModule)
void ExampleModule_Startup()
@@ -76,7 +76,7 @@ void ExampleModule_Startup()
module.Description = "This is an example module";
module.RegisterSetting<&mySetting>("Hello World!");
module.RegisterSetting<&mySetting>("mySetting");
// This is to expose functions to the rest of the engine
module.BindFunction<ExampleFunction>("ExampleFunction");

View File

@@ -185,7 +185,9 @@ namespace Nuake
template<typename T>
T& RegisterModule()
{
Modules[typeid(T).name()] = (ModuleInstance*)(new T());
T* newInstance = new T();
newInstance->instance = entt::resolve<T>().construct();
Modules[typeid(T).name()] = (ModuleInstance*)newInstance;
return *(T*)std::any_cast<ModuleInstance*>(Modules[typeid(T).name()]);
}
@@ -202,6 +204,18 @@ namespace Nuake
return *(T*)std::any_cast<ModuleInstance*>(Modules[typeName]);
}
ModuleInstance& GetBaseImpl(const std::string& moduleName)
{
for (auto& [name, _] : Modules)
{
if (name == moduleName)
{
return *std::any_cast<ModuleInstance*>(Modules[name]);
}
}
assert(false && "Module not found.");
}
entt::meta_type GetModuleMeta(const std::string& moduleName)
{

View File

@@ -5,10 +5,64 @@
#include "AudioModule/AudioModule.h"
#include "ExampleModule/ExampleModule.h"
#include "Nuake/UI/WidgetDrawer.h"
#include "Nuake/Core/Object/Object.h"
#include "Nuake/Core/Logger.h"
void DrawFloatWidget(entt::meta_data& type, entt::meta_any& instance)
{
using namespace Nuake;
float stepSize = 1.f;
if (auto prop = type.prop(HashedFieldPropName::FloatStep))
stepSize = *prop.value().try_cast<float>();
float min = 0.f;
if (auto prop = type.prop(HashedFieldPropName::FloatMin))
min = *prop.value().try_cast<float>();
float max = 0.f;
if (auto prop = type.prop(HashedFieldPropName::FloatMax))
max = *prop.value().try_cast<float>();
auto propDisplayName = type.prop(HashedName::DisplayName);
const char* displayName = *propDisplayName.value().try_cast<const char*>();
if (displayName != nullptr)
{
ImGui::Text(displayName);
ImGui::TableNextColumn();
auto fieldVal = type.get(instance);
float* floatPtr = fieldVal.try_cast<float>();
if (floatPtr != nullptr)
{
float floatProxy = *floatPtr;
const std::string controlId = std::string("##") + displayName;
if (ImGui::DragFloat(controlId.c_str(), &floatProxy, stepSize, min, max))
{
type.set(instance, floatProxy);
}
}
else
{
ImGui::Text("ERR");
}
}
}
void DrawBoolWidget(entt::meta_type& type, entt::meta_any& instance)
{
}
void Nuake::Modules::StartupModules()
{
auto& drawer = WidgetDrawer::Get();
drawer.RegisterTypeDrawer<float, &WidgetDrawer::DrawFloat>(&drawer);
//drawer.RegisterTypeDrawer<bool, DrawBoolWidget>(&DrawBoolWidget);
Logger::Log("Starting AssimpModule", "modules");
AssimpModule_Startup();
Logger::Log("Starting AudioModule", "modules");

View File

@@ -0,0 +1,88 @@
#pragma once
#include "Nuake/Core/Object/Object.h"
#include <entt/entt.hpp>
#include <imgui/imgui.h>
#include <functional>
#include <unordered_map>
namespace Nuake
{
using DrawWidgetTypeFn = std::function<void(entt::meta_data& fieldMeta, entt::meta_any& instance)>;
class WidgetDrawer
{
public:
WidgetDrawer() = default;
~WidgetDrawer() = default;
static WidgetDrawer& Get()
{
static WidgetDrawer instance;
return instance;
}
void DrawFloat(entt::meta_data& type, entt::meta_any& instance)
{
float stepSize = 1.f;
if (auto prop = type.prop(HashedFieldPropName::FloatStep))
stepSize = *prop.value().try_cast<float>();
float min = 0.f;
if (auto prop = type.prop(HashedFieldPropName::FloatMin))
min = *prop.value().try_cast<float>();
float max = 0.f;
if (auto prop = type.prop(HashedFieldPropName::FloatMax))
max = *prop.value().try_cast<float>();
auto propDisplayName = type.prop(HashedName::DisplayName);
const char* displayName = *propDisplayName.value().try_cast<const char*>();
if (displayName != nullptr)
{
ImGui::Text(displayName);
ImGui::TableNextColumn();
auto fieldVal = type.get(instance);
float* floatPtr = fieldVal.try_cast<float>();
if (floatPtr != nullptr)
{
float floatProxy = *floatPtr;
const std::string controlId = std::string("##") + displayName;
if (ImGui::DragFloat(controlId.c_str(), &floatProxy, stepSize, min, max))
{
type.set(instance, floatProxy);
}
}
else
{
ImGui::Text("ERR");
}
}
}
void DrawWidget(entt::meta_data& dataType, entt::meta_any& instance)
{
entt::id_type dataId = dataType.type().id();
if (WidgetTypeDrawers.contains(dataId))
{
auto& drawerFn = WidgetTypeDrawers[dataId];
drawerFn(dataType, instance);
}
else
{
ImGui::Text("ERR");
}
}
template<class T, auto Func, class O>
void RegisterTypeDrawer(O* o)
{
WidgetTypeDrawers[entt::type_id<T>().hash()] = std::bind(Func, o, std::placeholders::_1, std::placeholders::_2);
}
private:
std::unordered_map<entt::id_type, DrawWidgetTypeFn> WidgetTypeDrawers;
};
}