diff --git a/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.cpp b/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.cpp index 6ee1d7bd..cc7909c8 100644 --- a/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.cpp +++ b/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.cpp @@ -6,6 +6,7 @@ #include "../EditorInterface.h" #include "../../Commands/Commands/Commands.h" #include +#include ProjectSettingsCategoryWindowGeneral::ProjectSettingsCategoryWindowGeneral(Ref project) : m_Project(project) @@ -56,6 +57,11 @@ void ProjectSettingsWindow::Init(Ref project) m_CategoryWindows.push_back(CreateRef(project)); m_CategoryWindows.push_back(CreateRef(project)); m_CategoryWindows.push_back(CreateRef(project)); + + for (auto& m : ModuleDB::Get().GetModules()) + { + m_CategoryWindows.push_back(CreateRef(m)); + } } void ProjectSettingsWindow::Draw() @@ -197,6 +203,78 @@ ProjectSettingsCategoryAudio::ProjectSettingsCategoryAudio(Ref p Name = "Audio"; } +ProjectSettingsModuleWindow::ProjectSettingsModuleWindow(const std::string& inModuleName) : + moduleName(inModuleName) +{ + Name = moduleName; +} + +void ProjectSettingsModuleWindow::Draw() +{ + auto meta = entt::resolve(entt::hashed_string(Name.c_str())); + for (auto [id, data] : meta.data()) + { + auto propDisplayName = data.prop(HashedName::DisplayName); + if (propDisplayName) + { + auto propVal = propDisplayName.value(); + const char* settingName = *propVal.try_cast(); + + 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(); + + ImGui::Text(settingName); + } + + + // Setting + //std::string funcName = "UnknownFunc"; + //if (propDisplayName) + //{ + // funcName = std::string(*propDisplayName.value().try_cast()); + //} + // + //std::string msg = std::string(returnType) + " " + std::string(funcName) + "("; + //std::vector args; + // + //if (func.arity() > 0) + //{ + // auto propArgsName = func.prop(HashedName::ArgsName); + // if (propArgsName) + // { + // std::vector argsName = *propArgsName.value().try_cast>(); + // 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() { float oldVolume = Engine::GetProject()->Settings.GlobalVolume; diff --git a/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.h b/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.h index c45d106f..5a6f2e66 100644 --- a/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.h +++ b/Editor/Source/Editor/Windows/ProjectSettings/ProjectSettingsWindow.h @@ -70,6 +70,17 @@ public: void Draw() override; }; +class ProjectSettingsModuleWindow : public ProjectSettingsCategoryWindow +{ +private: + std::string moduleName; + +public: + ProjectSettingsModuleWindow(const std::string& inModuleName); + + void Draw() override; +}; + class ProjectSettingsWindow { private: diff --git a/Nuake/Source/Nuake/Core/Object/Object.h b/Nuake/Source/Nuake/Core/Object/Object.h index 8944cf40..5037a2b3 100644 --- a/Nuake/Source/Nuake/Core/Object/Object.h +++ b/Nuake/Source/Nuake/Core/Object/Object.h @@ -24,6 +24,7 @@ namespace Nuake NK_HASHED_STATIC_STR(AddToEntity) NK_HASHED_STATIC_STR(RemoveFromEntity) NK_HASHED_STATIC_STR(ActionName) + NK_HASHED_STATIC_STR(ModuleSettingName) }; struct HashedFieldPropName diff --git a/Nuake/Source/Nuake/Modules/AudioModule/AudioModule.cpp b/Nuake/Source/Nuake/Modules/AudioModule/AudioModule.cpp index 7cb8dee1..2afe3445 100644 --- a/Nuake/Source/Nuake/Modules/AudioModule/AudioModule.cpp +++ b/Nuake/Source/Nuake/Modules/AudioModule/AudioModule.cpp @@ -15,20 +15,38 @@ void StopAudio() } +float Volume = 1.0f; +void SetVolume(float volume) +{ + Volume = volume; +} + +bool Muted = false; +void SetMuted(bool muted) +{ + Muted = muted; +} + NUAKEMODULE(AudioModule) void AudioModule_Startup() { using namespace Nuake; auto& module = ModuleDB::Get().RegisterModule(); + module.Name = "AudioModule"; module.Description = "Core audio module."; + module.RegisterSetting<&Volume>("Volume"); + module.RegisterSetting<&Muted>("Muted"); + module.BindFunction("PlayAudio", "id", "volume"); module.BindFunction("StopAudio"); Logger::Log("AudioModule exposed API:", "Module", VERBOSE); auto reflection = module.Resolve(); + auto metaTypeid = entt::hashed_string(module.Name.c_str()); + auto s = reflection.func(metaTypeid); for (auto [id, func] : reflection.func()) { const std::string_view returnType = func.ret().info().name(); diff --git a/Nuake/Source/Nuake/Modules/ExampleModule/ExampleModule.cpp b/Nuake/Source/Nuake/Modules/ExampleModule/ExampleModule.cpp index 39b7a570..5aad6999 100644 --- a/Nuake/Source/Nuake/Modules/ExampleModule/ExampleModule.cpp +++ b/Nuake/Source/Nuake/Modules/ExampleModule/ExampleModule.cpp @@ -62,6 +62,8 @@ void ExampleModuleLog(const std::string& hi) Nuake::Logger::Log(hi, "ExampleModule", Nuake::VERBOSE); } +float mySetting = 1.0f; + NUAKEMODULE(ExampleModule) void ExampleModule_Startup() { @@ -74,6 +76,8 @@ void ExampleModule_Startup() module.Description = "This is an example module"; + module.RegisterSetting<&mySetting>("Hello World!"); + // This is to expose functions to the rest of the engine module.BindFunction("ExampleFunction"); module.BindFunction("ExampleModuleLog", "hi"); diff --git a/Nuake/Source/Nuake/Modules/ModuleDB.h b/Nuake/Source/Nuake/Modules/ModuleDB.h index ba2a11e2..8fa2c966 100644 --- a/Nuake/Source/Nuake/Modules/ModuleDB.h +++ b/Nuake/Source/Nuake/Modules/ModuleDB.h @@ -8,6 +8,22 @@ #include +#include "Nuake/Core/Logger.h" +class ModuleInstance +{ +public: + entt::meta_any instance; + std::string Name; + + entt::meta_type Resolve() + { + Nuake::Logger::Log("Resolved!" + Name, "ModuleReflection", Nuake::LOG_TYPE::VERBOSE); \ + return entt::resolve(entt::hashed_string(Name.c_str())); + } + + +}; + class Class { protected: @@ -82,16 +98,16 @@ public: \ #define NUAKEMODULE(moduleName) \ using TypeNameMap = std::map; \ \ -struct moduleName \ +class moduleName : public ModuleInstance \ { \ - entt::meta_any instance; \ - const std::string Name = #moduleName; \ +public: \ std::string Description = "No Description"; \ entt::meta_factory ModuleFactory = entt::meta(); \ TypeNameMap TypeNames; \ \ std::map> FuncArgNames; \ \ + inline static auto ClassFactory = entt::meta(); \ template \ inline moduleName& BindFunction(const std::string& name, Args... argNames) \ { \ @@ -101,11 +117,14 @@ struct moduleName \ ModuleFactory.func(typeId); \ return *this; \ } \ - \ - auto Resolve() \ + template \ + static auto RegisterSetting(const char* settingName) \ { \ - return entt::resolve(); \ - } \ + return ClassFactory \ + .data(entt::hashed_string(settingName)) \ + .prop(Nuake::HashedName::DisplayName, settingName); \ + } \ + \ \ template \ auto Invoke(const std::string& funcName, Args... args) \ @@ -166,8 +185,8 @@ namespace Nuake template T& RegisterModule() { - Modules[typeid(T).name()] = T(); - return std::any_cast(Modules[typeid(T).name()]); + Modules[typeid(T).name()] = (ModuleInstance*)(new T()); + return *(T*)std::any_cast(Modules[typeid(T).name()]); } template @@ -180,7 +199,40 @@ namespace Nuake return; } - return std::any_cast(Modules[typeName]); + return *(T*)std::any_cast(Modules[typeName]); + } + + + entt::meta_type GetModuleMeta(const std::string& moduleName) + { + for (auto& [name, _] : Modules) + { + if (name == moduleName) + { + return std::any_cast(Modules[name])->Resolve(); + } + } + //auto foundIt = std::find_if(Modules.begin(), Modules.end(), moduleName); + //if (foundIt != Modules.end()) + //{ + // return std::any_cast(foundIt->second)->Resolve(); + //} + + assert(false && "Module not found"); + return entt::meta_type(); + } + + std::vector GetModules() + { + std::vector moduleNames; + moduleNames.reserve(Modules.size()); + + for(auto& [moduleName, _] : Modules) + { + moduleNames.push_back(moduleName); + } + + return moduleNames; } private: diff --git a/Nuake/Source/Nuake/Modules/Modules.h b/Nuake/Source/Nuake/Modules/Modules.h index 8886bd7a..20ed9e09 100644 --- a/Nuake/Source/Nuake/Modules/Modules.h +++ b/Nuake/Source/Nuake/Modules/Modules.h @@ -1,9 +1,15 @@ #pragma once +#include +#include + namespace Nuake { class Modules { + private: + std::map modules; + public: static void StartupModules(); static void ShutdownModules();