diff --git a/include/utils/App/App.h b/include/utils/App/App.h index 7479762..28b8be8 100644 --- a/include/utils/App/App.h +++ b/include/utils/App/App.h @@ -17,10 +17,22 @@ namespace Archimedes { } instance = this; roInsert = runOrder.begin(); + + registerEvent(DoLoadModuleEvent()); + registerEvent(DoUnloadModuleEvent()); + + registerEvent(LoadModuleEvent()); + registerEvent(UnloadModuleEvent()); } virtual ~App() { + unregisterEvent(DoLoadModuleEvent()); + unregisterEvent(DoUnloadModuleEvent()); + + unregisterEvent(LoadModuleEvent()); + unregisterEvent(UnloadModuleEvent()); + for(std::string s : runOrder) { void* handle = modules[s]->getHandle(); delete modules[s]; @@ -40,17 +52,6 @@ namespace Archimedes { virtual void run() = 0; - virtual void stopModule(std::string lib) { - //unload modules that depend on the one we are unloading - for(std::string s : runOrder) { - if(modules[s]->deps.find(lib) != modules[s]->deps.end()) { - stopModule(s); - } - } - toClose.push_back(lib); - } - - virtual void startModule(std::variant m) { toOpen.push_back(m); } void end() { done = true; } @@ -94,8 +95,23 @@ namespace Archimedes { std::list toClose; std::list> toOpen; + virtual void stopModule(std::string lib) { + //unload modules that depend on the one we are unloading + for(std::string s : runOrder) { + if(modules[s]->deps.find(lib) != modules[s]->deps.end()) { + stopModule(s); + } + } + toClose.push_back(lib); + } + + virtual void startModule(std::variant m) { toOpen.push_back(m); } + + virtual bool onEvent(const Event&) = 0; + void handleEvents() { static bool handled; + while(!events.empty()) { handled = false; @@ -113,7 +129,13 @@ namespace Archimedes { } if(!handled) { - std::cout << "Error: Unhandled Event: " << (std::string) *events.front() << std::endl; + if(this->onEvent(*events.front())) { + Event* e = events.front(); + events.pop_front(); + delete e; + } else { + std::cout << "Error: Unhandled Event: " << (std::string) *events.front() << std::endl; + } } } } @@ -212,13 +234,12 @@ namespace Archimedes { runOrder.insert(roInsert, *m); + emitEvent(new LoadModuleEvent(*m)); return m; } virtual void unload(std::string name) { - std::cout << "Attempting to unload module: " << name << std::endl; - if(modules.find(name) == modules.end()) return; @@ -246,7 +267,7 @@ namespace Archimedes { } } - std::cout << "Successfully unloaded module: " << name << std::endl; + emitEvent(new UnloadModuleEvent(name)); } virtual void printHelp() = 0; diff --git a/include/utils/Events/BasicEvents.h b/include/utils/Events/BasicEvents.h new file mode 100644 index 0000000..441f881 --- /dev/null +++ b/include/utils/Events/BasicEvents.h @@ -0,0 +1,74 @@ +#ifndef BASICEVENTS_H +#define BASICEVENTS_H + +#include "Event.h" + +namespace Archimedes { + + class Module; + + class LoadModuleEvent : public Event { + + public: + + LoadModuleEvent() {} + + LoadModuleEvent(std::string n) : module(n) {} + + ~LoadModuleEvent() {} + + operator std::string() const override { return "LoadModuleEvent"; } + + std::string module; + + }; + + class DoLoadModuleEvent : public Event { + + public: + + DoLoadModuleEvent() {} + + DoLoadModuleEvent(std::variant n) : module(n) {} + + ~DoLoadModuleEvent() {} + + operator std::string() const override { return "DoLoadModuleEvent"; } + + std::variant module; + + }; + + class UnloadModuleEvent : public Event { + + public: + + UnloadModuleEvent() {} + + UnloadModuleEvent(std::string n) : module(n) {} + + ~UnloadModuleEvent() {} + + operator std::string() const override { return "UnloadModuleEvent"; } + + std::string module; + }; + + class DoUnloadModuleEvent : public Event { + + public: + + DoUnloadModuleEvent() {} + + DoUnloadModuleEvent(std::string n) : module(n) {} + + ~DoUnloadModuleEvent() {} + + operator std::string() const override { return "DoUnloadModuleEvent"; } + + std::string module; + + }; +} + +#endif diff --git a/include/utils/Events/Event.h b/include/utils/Events/Event.h index e1a0bc1..b98b414 100644 --- a/include/utils/Events/Event.h +++ b/include/utils/Events/Event.h @@ -16,4 +16,6 @@ namespace Archimedes { }; } +#include "BasicEvents.h" + #endif diff --git a/modules/MainGUI/src/MainGUI.cpp b/modules/MainGUI/src/MainGUI.cpp index c15b535..9422344 100644 --- a/modules/MainGUI/src/MainGUI.cpp +++ b/modules/MainGUI/src/MainGUI.cpp @@ -47,12 +47,12 @@ void MainGUI::run() { ImGui::InputText("module: ", &s); if(ImGui::Button("load")) - app->startModule(s); + app->emitEvent(new Archimedes::DoLoadModuleEvent(s)); ImGui::SameLine(); if(ImGui::Button("unload")) - app->stopModule(s); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(s)); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); ImGui::End(); diff --git a/modules/Ollama/src/Ollama.cpp b/modules/Ollama/src/Ollama.cpp index df6f35a..944647c 100644 --- a/modules/Ollama/src/Ollama.cpp +++ b/modules/Ollama/src/Ollama.cpp @@ -114,7 +114,7 @@ void Ollama::run() { if(code != CURLE_OK) { std::cerr << "curl_easy_perform() failed!: " << curl_easy_strerror(code) << std::endl; - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); return; } else { jsonObj = nlohmann::json::parse(response); diff --git a/modules/Terminal/src/Terminal.cpp b/modules/Terminal/src/Terminal.cpp index 665ba52..785f8d7 100644 --- a/modules/Terminal/src/Terminal.cpp +++ b/modules/Terminal/src/Terminal.cpp @@ -17,7 +17,11 @@ Terminal::Terminal(Archimedes::App* a, void* h) : Archimedes::Module(a, h) { } Terminal::~Terminal() { - if(app) {} + if(app) { + ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } + + im->releaseContext(ImGui::GetCurrentContext()); + } } void Terminal::onLoad() { @@ -29,7 +33,7 @@ void Terminal::onLoad() { std::abort(); } - ImGui::SetCurrentContext(im->getContext()); + ImGui::SetCurrentContext(im->aquireContext()); child_pid = forkpty(&master, nullptr, nullptr, nullptr); @@ -67,7 +71,7 @@ void Terminal::run() { rc = read(master, opArr, 150); if(rc < 0) { //error on read - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); } else { if(input == "clear") output = ""; output += opArr; diff --git a/modules/WindowModule/src/WindowModule.cpp b/modules/WindowModule/src/WindowModule.cpp index d33d224..d28d7da 100644 --- a/modules/WindowModule/src/WindowModule.cpp +++ b/modules/WindowModule/src/WindowModule.cpp @@ -55,7 +55,7 @@ bool WindowModule::onEvent(const Archimedes::Event& e) { window->getSize(renderer->w, renderer->h); return true; } else if(type == app->getEventType(Archimedes::WindowCloseEvent())) { - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); return true; } else if(type == app->getEventType(Archimedes::WindowKeyPressedEvent())) { diff --git a/modules/examples/ChatClient/src/ChatClient.cpp b/modules/examples/ChatClient/src/ChatClient.cpp index 967ba2b..2dfd6af 100644 --- a/modules/examples/ChatClient/src/ChatClient.cpp +++ b/modules/examples/ChatClient/src/ChatClient.cpp @@ -14,8 +14,25 @@ ChatClient::ChatClient(Archimedes::App* a, void* h) : Module(a, h) { deps[*im] = im; } +ChatClient::~ChatClient() { + if(app) { + + ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } + + im->releaseContext(ImGui::GetCurrentContext()); + } +} + void ChatClient::onLoad() { + ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } + + if(!im) { + std::cout << "No ImguiModule for TestImgui!\n"; + std::abort(); + } + + ImGui::SetCurrentContext(im->aquireContext()); } @@ -58,7 +75,7 @@ void ChatClient::run() { ImGui::End(); } else { - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); } } diff --git a/modules/examples/ChatClient/src/ChatClient.h b/modules/examples/ChatClient/src/ChatClient.h index 2e2255e..d15c6ef 100644 --- a/modules/examples/ChatClient/src/ChatClient.h +++ b/modules/examples/ChatClient/src/ChatClient.h @@ -12,9 +12,7 @@ class ChatClient : public Archimedes::Module { ChatClient() { name = "ChatClient"; } - ~ChatClient() { - if(app) {} - } + ~ChatClient(); void onLoad(); diff --git a/modules/examples/DependsOnPrint/src/DependsOnPrint.cpp b/modules/examples/DependsOnPrint/src/DependsOnPrint.cpp index cc65757..22d1f9d 100644 --- a/modules/examples/DependsOnPrint/src/DependsOnPrint.cpp +++ b/modules/examples/DependsOnPrint/src/DependsOnPrint.cpp @@ -12,5 +12,5 @@ DependsOnPrint::~DependsOnPrint() { void DependsOnPrint::run() { std::cout << "DependsOnPrint lib loaded and run!\n"; - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); } diff --git a/modules/examples/DependsOnPrintStatic/src/DependsOnPrintStatic.cpp b/modules/examples/DependsOnPrintStatic/src/DependsOnPrintStatic.cpp index 90405ee..dba7376 100644 --- a/modules/examples/DependsOnPrintStatic/src/DependsOnPrintStatic.cpp +++ b/modules/examples/DependsOnPrintStatic/src/DependsOnPrintStatic.cpp @@ -15,5 +15,5 @@ DependsOnPrintStatic::~DependsOnPrintStatic() { void DependsOnPrintStatic::run() { std::cout << "DependsOnPrintStatic lib loaded and run!\n"; - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); } diff --git a/modules/examples/TestImgui/src/TestImgui.cpp b/modules/examples/TestImgui/src/TestImgui.cpp index 7c01bed..1039ac9 100644 --- a/modules/examples/TestImgui/src/TestImgui.cpp +++ b/modules/examples/TestImgui/src/TestImgui.cpp @@ -10,19 +10,21 @@ TestImgui::TestImgui(Archimedes::App* a, void* h) : Archimedes::Module(a, h) { } TestImgui::~TestImgui() { - + + ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } + im->releaseContext(ImGui::GetCurrentContext()); } void TestImgui::onLoad() { - ImguiModule* im = (ImguiModule*) moduleInstances["ImguiModule"]; + ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } if(!im) { std::cout << "No ImguiModule for TestImgui!\n"; std::abort(); } - ImGui::SetCurrentContext(im->getContext()); + ImGui::SetCurrentContext(im->aquireContext()); } @@ -30,7 +32,7 @@ void TestImgui::run() { if(demo) ImGui::ShowDemoWindow(&this->demo); else - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); { ImGuiIO& io = ImGui::GetIO(); diff --git a/modules/examples/TestMenu/src/TestMenu.cpp b/modules/examples/TestMenu/src/TestMenu.cpp index 06bc21f..d393cf4 100644 --- a/modules/examples/TestMenu/src/TestMenu.cpp +++ b/modules/examples/TestMenu/src/TestMenu.cpp @@ -26,7 +26,7 @@ void TestMenu::run() { num--; break; case 3: - app->stopModule(name); + app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); break; case 4: app->end(); diff --git a/src/example_apps/ImguiEmbed/ImguiEmbed.h b/src/example_apps/ImguiEmbed/ImguiEmbed.h index 815515f..64e938b 100644 --- a/src/example_apps/ImguiEmbed/ImguiEmbed.h +++ b/src/example_apps/ImguiEmbed/ImguiEmbed.h @@ -7,8 +7,10 @@ class ImguiEmbed : public Archimedes::App { private: - void printHelp() {}; + void printHelp() override {}; + bool onEvent(const Archimedes::Event&) override; + public: ImguiEmbed() { Archimedes::Module* m = (Archimedes::Module*) new TestImgui(Get(), nullptr); @@ -17,9 +19,9 @@ class ImguiEmbed : public Archimedes::App { }; ~ImguiEmbed() {}; - void handleArgs(const int& argc, char* argv[]) {}; + void handleArgs(const int& argc, char* argv[]) override {}; - void run(); + void run() override; }; diff --git a/src/example_apps/MinimalApp/MinimalApp.cpp b/src/example_apps/MinimalApp/MinimalApp.cpp index c2edd18..36dde6f 100644 --- a/src/example_apps/MinimalApp/MinimalApp.cpp +++ b/src/example_apps/MinimalApp/MinimalApp.cpp @@ -36,3 +36,34 @@ void MinimalApp::run() { } } + +bool MinimalApp::onEvent(const Archimedes::Event& event) { + + unsigned int type = getEventType(event); + + if(type == getEventType(Archimedes::DoLoadModuleEvent())) { + + Archimedes::DoLoadModuleEvent& e = (Archimedes::DoLoadModuleEvent&) event; + + startModule(e.module); + + return true; + + } else if(type == getEventType(Archimedes::DoUnloadModuleEvent())) { + + Archimedes::DoUnloadModuleEvent& e = (Archimedes::DoUnloadModuleEvent&) event; + + stopModule(e.module); + + return true; + + } else if(type == getEventType(Archimedes::LoadModuleEvent())) { + + return true; + } else if(type == getEventType(Archimedes::UnloadModuleEvent())) { + + return true; + } + + return false; +} diff --git a/src/example_apps/MinimalApp/MinimalApp.h b/src/example_apps/MinimalApp/MinimalApp.h index 68036e5..c767933 100644 --- a/src/example_apps/MinimalApp/MinimalApp.h +++ b/src/example_apps/MinimalApp/MinimalApp.h @@ -5,13 +5,15 @@ class MinimalApp : public Archimedes::App { private: - void printHelp() {}; + void printHelp() override {}; + + bool onEvent(const Archimedes::Event&) override; public: MinimalApp() {}; ~MinimalApp() {}; - void handleArgs(const int& argc, char* argv[]) { + void handleArgs(const int& argc, char* argv[]) override { if(argc > 1) { for(int i = 1; i < argc; i++) { load(dynamicLoad(argv[i])); @@ -22,7 +24,7 @@ class MinimalApp : public Archimedes::App { } }; - void run(); + void run() override; }; diff --git a/src/example_apps/TerminalEmbed/TerminalEmbed.h b/src/example_apps/TerminalEmbed/TerminalEmbed.h index 294397e..6998c3a 100644 --- a/src/example_apps/TerminalEmbed/TerminalEmbed.h +++ b/src/example_apps/TerminalEmbed/TerminalEmbed.h @@ -7,7 +7,9 @@ class TerminalEmbed : public Archimedes::App { private: - void printHelp() {}; + void printHelp() override {}; + + bool onEvent(const Archimedes::Event&) override; public: TerminalEmbed() { @@ -17,9 +19,9 @@ class TerminalEmbed : public Archimedes::App { }; ~TerminalEmbed() {}; - void handleArgs(const int& argc, char* argv[]) {}; + void handleArgs(const int& argc, char* argv[]) override {}; - void run(); + void run() override; };