introduce active and passive events

This commit is contained in:
2025-04-23 13:51:09 -05:00
parent a3fb96abb7
commit b4ac013f18
17 changed files with 197 additions and 42 deletions

View File

@@ -17,10 +17,22 @@ namespace Archimedes {
} }
instance = this; instance = this;
roInsert = runOrder.begin(); roInsert = runOrder.begin();
registerEvent(DoLoadModuleEvent());
registerEvent(DoUnloadModuleEvent());
registerEvent(LoadModuleEvent());
registerEvent(UnloadModuleEvent());
} }
virtual ~App() { virtual ~App() {
unregisterEvent(DoLoadModuleEvent());
unregisterEvent(DoUnloadModuleEvent());
unregisterEvent(LoadModuleEvent());
unregisterEvent(UnloadModuleEvent());
for(std::string s : runOrder) { for(std::string s : runOrder) {
void* handle = modules[s]->getHandle(); void* handle = modules[s]->getHandle();
delete modules[s]; delete modules[s];
@@ -40,17 +52,6 @@ namespace Archimedes {
virtual void run() = 0; 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<std::string, Module*> m) { toOpen.push_back(m); }
void end() { done = true; } void end() { done = true; }
@@ -94,8 +95,23 @@ namespace Archimedes {
std::list<std::string> toClose; std::list<std::string> toClose;
std::list<std::variant<std::string, Module*>> toOpen; std::list<std::variant<std::string, Module*>> 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<std::string, Module*> m) { toOpen.push_back(m); }
virtual bool onEvent(const Event&) = 0;
void handleEvents() { void handleEvents() {
static bool handled; static bool handled;
while(!events.empty()) { while(!events.empty()) {
handled = false; handled = false;
@@ -113,7 +129,13 @@ namespace Archimedes {
} }
if(!handled) { 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); runOrder.insert(roInsert, *m);
emitEvent(new LoadModuleEvent(*m));
return m; return m;
} }
virtual void unload(std::string name) { virtual void unload(std::string name) {
std::cout << "Attempting to unload module: " << name << std::endl;
if(modules.find(name) == modules.end()) if(modules.find(name) == modules.end())
return; return;
@@ -246,7 +267,7 @@ namespace Archimedes {
} }
} }
std::cout << "Successfully unloaded module: " << name << std::endl; emitEvent(new UnloadModuleEvent(name));
} }
virtual void printHelp() = 0; virtual void printHelp() = 0;

View File

@@ -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<std::string, Module*> n) : module(n) {}
~DoLoadModuleEvent() {}
operator std::string() const override { return "DoLoadModuleEvent"; }
std::variant<std::string, Module*> 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

View File

@@ -16,4 +16,6 @@ namespace Archimedes {
}; };
} }
#include "BasicEvents.h"
#endif #endif

View File

@@ -47,12 +47,12 @@ void MainGUI::run() {
ImGui::InputText("module: ", &s); ImGui::InputText("module: ", &s);
if(ImGui::Button("load")) if(ImGui::Button("load"))
app->startModule(s); app->emitEvent(new Archimedes::DoLoadModuleEvent(s));
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("unload")) 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::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End(); ImGui::End();

View File

@@ -114,7 +114,7 @@ void Ollama::run() {
if(code != CURLE_OK) { if(code != CURLE_OK) {
std::cerr << "curl_easy_perform() failed!: " << curl_easy_strerror(code) << std::endl; std::cerr << "curl_easy_perform() failed!: " << curl_easy_strerror(code) << std::endl;
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
return; return;
} else { } else {
jsonObj = nlohmann::json::parse(response); jsonObj = nlohmann::json::parse(response);

View File

@@ -17,7 +17,11 @@ Terminal::Terminal(Archimedes::App* a, void* h) : Archimedes::Module(a, h) {
} }
Terminal::~Terminal() { Terminal::~Terminal() {
if(app) {} if(app) {
ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
im->releaseContext(ImGui::GetCurrentContext());
}
} }
void Terminal::onLoad() { void Terminal::onLoad() {
@@ -29,7 +33,7 @@ void Terminal::onLoad() {
std::abort(); std::abort();
} }
ImGui::SetCurrentContext(im->getContext()); ImGui::SetCurrentContext(im->aquireContext());
child_pid = forkpty(&master, nullptr, nullptr, nullptr); child_pid = forkpty(&master, nullptr, nullptr, nullptr);
@@ -67,7 +71,7 @@ void Terminal::run() {
rc = read(master, opArr, 150); rc = read(master, opArr, 150);
if(rc < 0) { if(rc < 0) {
//error on read //error on read
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
} else { } else {
if(input == "clear") output = ""; if(input == "clear") output = "";
output += opArr; output += opArr;

View File

@@ -55,7 +55,7 @@ bool WindowModule::onEvent(const Archimedes::Event& e) {
window->getSize(renderer->w, renderer->h); window->getSize(renderer->w, renderer->h);
return true; return true;
} else if(type == app->getEventType(Archimedes::WindowCloseEvent())) { } else if(type == app->getEventType(Archimedes::WindowCloseEvent())) {
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
return true; return true;
} else if(type == app->getEventType(Archimedes::WindowKeyPressedEvent())) { } else if(type == app->getEventType(Archimedes::WindowKeyPressedEvent())) {

View File

@@ -14,8 +14,25 @@ ChatClient::ChatClient(Archimedes::App* a, void* h) : Module(a, h) {
deps[*im] = im; deps[*im] = im;
} }
ChatClient::~ChatClient() {
if(app) {
ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
im->releaseContext(ImGui::GetCurrentContext());
}
}
void ChatClient::onLoad() { 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(); ImGui::End();
} else { } else {
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
} }
} }

View File

@@ -12,9 +12,7 @@ class ChatClient : public Archimedes::Module {
ChatClient() { name = "ChatClient"; } ChatClient() { name = "ChatClient"; }
~ChatClient() { ~ChatClient();
if(app) {}
}
void onLoad(); void onLoad();

View File

@@ -12,5 +12,5 @@ DependsOnPrint::~DependsOnPrint() {
void DependsOnPrint::run() { void DependsOnPrint::run() {
std::cout << "DependsOnPrint lib loaded and run!\n"; std::cout << "DependsOnPrint lib loaded and run!\n";
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
} }

View File

@@ -15,5 +15,5 @@ DependsOnPrintStatic::~DependsOnPrintStatic() {
void DependsOnPrintStatic::run() { void DependsOnPrintStatic::run() {
std::cout << "DependsOnPrintStatic lib loaded and run!\n"; std::cout << "DependsOnPrintStatic lib loaded and run!\n";
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
} }

View File

@@ -10,19 +10,21 @@ TestImgui::TestImgui(Archimedes::App* a, void* h) : Archimedes::Module(a, h) {
} }
TestImgui::~TestImgui() { TestImgui::~TestImgui() {
ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
im->releaseContext(ImGui::GetCurrentContext());
} }
void TestImgui::onLoad() { void TestImgui::onLoad() {
ImguiModule* im = (ImguiModule*) moduleInstances["ImguiModule"]; ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; }
if(!im) { if(!im) {
std::cout << "No ImguiModule for TestImgui!\n"; std::cout << "No ImguiModule for TestImgui!\n";
std::abort(); std::abort();
} }
ImGui::SetCurrentContext(im->getContext()); ImGui::SetCurrentContext(im->aquireContext());
} }
@@ -30,7 +32,7 @@ void TestImgui::run() {
if(demo) if(demo)
ImGui::ShowDemoWindow(&this->demo); ImGui::ShowDemoWindow(&this->demo);
else else
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();

View File

@@ -26,7 +26,7 @@ void TestMenu::run() {
num--; num--;
break; break;
case 3: case 3:
app->stopModule(name); app->emitEvent(new Archimedes::DoUnloadModuleEvent(name));
break; break;
case 4: case 4:
app->end(); app->end();

View File

@@ -7,8 +7,10 @@ class ImguiEmbed : public Archimedes::App {
private: private:
void printHelp() {}; void printHelp() override {};
bool onEvent(const Archimedes::Event&) override;
public: public:
ImguiEmbed() { ImguiEmbed() {
Archimedes::Module* m = (Archimedes::Module*) new TestImgui(Get(), nullptr); Archimedes::Module* m = (Archimedes::Module*) new TestImgui(Get(), nullptr);
@@ -17,9 +19,9 @@ class ImguiEmbed : public Archimedes::App {
}; };
~ImguiEmbed() {}; ~ImguiEmbed() {};
void handleArgs(const int& argc, char* argv[]) {}; void handleArgs(const int& argc, char* argv[]) override {};
void run(); void run() override;
}; };

View File

@@ -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;
}

View File

@@ -5,13 +5,15 @@ class MinimalApp : public Archimedes::App {
private: private:
void printHelp() {}; void printHelp() override {};
bool onEvent(const Archimedes::Event&) override;
public: public:
MinimalApp() {}; MinimalApp() {};
~MinimalApp() {}; ~MinimalApp() {};
void handleArgs(const int& argc, char* argv[]) { void handleArgs(const int& argc, char* argv[]) override {
if(argc > 1) { if(argc > 1) {
for(int i = 1; i < argc; i++) { for(int i = 1; i < argc; i++) {
load(dynamicLoad(argv[i])); load(dynamicLoad(argv[i]));
@@ -22,7 +24,7 @@ class MinimalApp : public Archimedes::App {
} }
}; };
void run(); void run() override;
}; };

View File

@@ -7,7 +7,9 @@ class TerminalEmbed : public Archimedes::App {
private: private:
void printHelp() {}; void printHelp() override {};
bool onEvent(const Archimedes::Event&) override;
public: public:
TerminalEmbed() { TerminalEmbed() {
@@ -17,9 +19,9 @@ class TerminalEmbed : public Archimedes::App {
}; };
~TerminalEmbed() {}; ~TerminalEmbed() {};
void handleArgs(const int& argc, char* argv[]) {}; void handleArgs(const int& argc, char* argv[]) override {};
void run(); void run() override;
}; };