From 0d61a369fc36051ff128dc6d11a98a81d3733836 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sat, 29 Mar 2025 15:02:27 -0500 Subject: [PATCH] make apps customizable --- example_apps/MinimalApp/MinimalApp.cpp | 136 ++----------------------- example_apps/MinimalApp/MinimalApp.h | 35 ++----- flake.nix | 3 +- include/Archimedes.h | 2 +- include/utils/App/App.cpp | 62 +---------- include/utils/App/App.h | 16 +-- include/utils/GuiModule/GuiModule.h | 4 +- include/utils/Module/Module.h | 14 ++- modules/Print/src/Print.cpp | 8 +- modules/Print/src/Print.h | 8 +- src/main.cpp | 2 +- 11 files changed, 49 insertions(+), 241 deletions(-) diff --git a/example_apps/MinimalApp/MinimalApp.cpp b/example_apps/MinimalApp/MinimalApp.cpp index d2173fb..5f581cc 100644 --- a/example_apps/MinimalApp/MinimalApp.cpp +++ b/example_apps/MinimalApp/MinimalApp.cpp @@ -1,148 +1,24 @@ -#include "App.h" - -Archimedes::App* Archimedes::App::instance = nullptr; +#include "MinimalApp.h" namespace Archimedes { - App::App(const int& argc, char* argv[]) { - - if(instance != nullptr) { - std::cout << "App already exists\nThere can only be one!\n"; - std::abort(); - } - - std::cout << "Initializing...\n"; - - instance = this; - - handleArgs(argc, argv); + MinimalApp::MinimalApp() : App() { } - App::~App() { - - std::cout << "\nExiting...\n"; - for(auto it = modules.begin(); it != modules.end(); it++) { - void* handle = (*it)->getHandle(); - delete *it; - dlclose(handle); - it = modules.erase(it); - } - } - - - bool App::load(std::string lib, std::list blacklist = {}) { - - - std::cout << "print twice!\n"; - void* h = dlopen(lib.c_str(), RTLD_NOW); - - if(!h) { - std::cout << "could not open lib at: \"" << lib.c_str() << "\"\nError: " << dlerror() << std::endl; - return false; - } - - Module::create_t* create = (Module::create_t*) dlsym(h, "create"); - char* err = dlerror(); - if(err) { - std::cout << "error finding create function in file: " << lib << std::endl; - std::cout << "dlerror(): " << err << std::endl; - } - - Module* m = create(h, App::Get()); - - for(auto it = blacklist.begin(); it != blacklist.end(); it++) { - if(*it == m->getName()) { - std::cout << "Module \"" << *it << "\" is already loaded!\n"; - delete m; - dlclose(h); - return false; - } - } - - blacklist.push_back(m->getName()); - - bool skip = false; - for(auto it = m->deps.begin(); it != m->deps.end(); it++) { - for(std::string s : blacklist) { - if(it->first == s) - skip = true; - } - if(skip) { - skip = false; - continue; - } else { - load(it->second, blacklist); - } - } - - - modules.push_back(m); - m->setSelf(--modules.end()); - modules.end()++; - - return true; - } - - void App::unload(std::list::iterator it) { - - Module* m = *it; - void* h = m->getHandle(); - - modules.erase(m->self); - delete m; - - dlclose(h); + MinimalApp::~MinimalApp() { } - void App::stopModule(std::list::iterator it) { - toClose.push_back(*it); - } - - void App::startModule(std::string lib) { - toOpen.push_back(lib); - } - - void App::handleArgs(const int& argc, char* argv[]) { - - int i = 1; - - if(argc == 1) { - printHelp(); - end(); - } - - while(i < argc) { - if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { - printHelp(); - end(); - } else { - break; - } - i++; - } - - while(i < argc) { - std::cout << "Attempting to load: " << argv[i] << std::endl; - load(argv[i]); - - i++; - } - } - - void App::printHelp() { - std::cout << "archimedes [ -h | --help ] /path/to/some/library.so\n"; - } - - - void App::run() { + void MinimalApp::run() { std::cout << "\nTesting...\n"; for(auto* m : modules) m->onLoad(); + for(auto* s : Archimedes::Module::GetModules()) + std::cout << "Module: " << (s ? *s : "nullptr") << std::endl; // Main loop while (!done && !modules.empty()) { diff --git a/example_apps/MinimalApp/MinimalApp.h b/example_apps/MinimalApp/MinimalApp.h index c3a82df..18fd1eb 100644 --- a/example_apps/MinimalApp/MinimalApp.h +++ b/example_apps/MinimalApp/MinimalApp.h @@ -1,41 +1,23 @@ -#ifndef APP_H -#define APP_H +#ifndef MINIMALAPP_H +#define MINIMALAPP_H #include "pch.hpp" +#include "utils/App/App.h" #include "utils/Module/Module.h" namespace Archimedes { - class App { + class MinimalApp : public App { private: - static App* instance; - bool done = false; + void handleArgs(const int&, char*[]) {}; - std::list modules; - std::list toClose; - std::list toOpen; - - bool load(std::string, std::list); - void unload(std::list::iterator); - - void handleArgs(const int&, char*[]); - - void printHelp(); - - std::list getBlacklist() { - std::list l; - for(Module* m : modules) - l.push_back(m->getName()); - return l; - } + void printHelp() {}; public: - App(const int&, char*[]); - ~App(); - - static App& Get() { return *instance; } + MinimalApp(); + ~MinimalApp(); void run(); @@ -43,7 +25,6 @@ namespace Archimedes { void startModule(std::string); - void end() { done = true; } }; } diff --git a/flake.nix b/flake.nix index 5ddf4f1..ee5a199 100755 --- a/flake.nix +++ b/flake.nix @@ -84,7 +84,8 @@ buildPhase = '' clang++ \ - modules/Print/src/*.cpp src/App.cpp \ + modules/Print/src/*.cpp \ + utils/App/App.cpp \ -fpic -shared \ -I src -I include \ -Wall \ diff --git a/include/Archimedes.h b/include/Archimedes.h index 01d260c..8560f5a 100644 --- a/include/Archimedes.h +++ b/include/Archimedes.h @@ -3,6 +3,6 @@ #include "utils/Module/Module.h" #include "utils/GuiModule/GuiModule.h" -#include "App.h" +#include "utils/App/App.h" #endif diff --git a/include/utils/App/App.cpp b/include/utils/App/App.cpp index d2173fb..ac4eaa8 100644 --- a/include/utils/App/App.cpp +++ b/include/utils/App/App.cpp @@ -5,7 +5,7 @@ Archimedes::App* Archimedes::App::instance = nullptr; namespace Archimedes { - App::App(const int& argc, char* argv[]) { + App::App() { if(instance != nullptr) { std::cout << "App already exists\nThere can only be one!\n"; @@ -16,8 +16,6 @@ namespace Archimedes { instance = this; - handleArgs(argc, argv); - } App::~App() { @@ -34,7 +32,6 @@ namespace Archimedes { bool App::load(std::string lib, std::list blacklist = {}) { - std::cout << "print twice!\n"; void* h = dlopen(lib.c_str(), RTLD_NOW); @@ -105,61 +102,4 @@ namespace Archimedes { toOpen.push_back(lib); } - void App::handleArgs(const int& argc, char* argv[]) { - - int i = 1; - - if(argc == 1) { - printHelp(); - end(); - } - - while(i < argc) { - if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { - printHelp(); - end(); - } else { - break; - } - i++; - } - - while(i < argc) { - std::cout << "Attempting to load: " << argv[i] << std::endl; - load(argv[i]); - - i++; - } - } - - void App::printHelp() { - std::cout << "archimedes [ -h | --help ] /path/to/some/library.so\n"; - } - - - void App::run() { - std::cout << "\nTesting...\n"; - - for(auto* m : modules) - m->onLoad(); - - // Main loop - while (!done && !modules.empty()) { - - for(auto* m : modules) { - m->run(); - } - - for(auto it = toClose.begin(); it != toClose.end(); it++) { - unload(it); - } - toClose.clear(); - - for(std::string s : toOpen) { - load(s, getBlacklist()); - } - toOpen.clear(); - } - - } } diff --git a/include/utils/App/App.h b/include/utils/App/App.h index ec75117..0bc7762 100644 --- a/include/utils/App/App.h +++ b/include/utils/App/App.h @@ -20,9 +20,9 @@ namespace Archimedes { virtual bool load(std::string, std::list); virtual void unload(std::list::iterator); - virtual void handleArgs(const int&, char*[]); + virtual void handleArgs(const int&, char*[]) = 0; - virtual void printHelp(); + virtual void printHelp() = 0; std::list getBlacklist() { std::list l; @@ -32,16 +32,16 @@ namespace Archimedes { } public: - App(const int&, char*[]); - ~App(); + App(); + virtual ~App(); - static App& Get() { return *instance; } + static App* Get() { return instance; } - void run(); + virtual void run() = 0; - void stopModule(std::list::iterator); + virtual void stopModule(std::list::iterator); - void startModule(std::string); + virtual void startModule(std::string); void end() { done = true; } }; diff --git a/include/utils/GuiModule/GuiModule.h b/include/utils/GuiModule/GuiModule.h index f6b9fc5..f90a12f 100644 --- a/include/utils/GuiModule/GuiModule.h +++ b/include/utils/GuiModule/GuiModule.h @@ -9,9 +9,9 @@ namespace Archimedes { class GuiModule : public Module { public: - typedef GuiModule* create_t(void*, App&); + typedef GuiModule* create_t(void*, App*); - GuiModule(void* h, App& a) : Module(h, a) {} + GuiModule(void* h, App* a) : Module(h, a) {} virtual ~GuiModule() { if(window) delete window; } virtual void onLoad() = 0; virtual void run() = 0; diff --git a/include/utils/Module/Module.h b/include/utils/Module/Module.h index dd69e93..078850e 100644 --- a/include/utils/Module/Module.h +++ b/include/utils/Module/Module.h @@ -11,11 +11,17 @@ namespace Archimedes { friend class App; + static std::list modules; + public: - typedef Module* create_t(void*, App&); + typedef Module* create_t(void*, App*); + + static std::list& GetModules() { return modules; } + + Module(void* h, App* a) : handle(h), app(a) { modules.push_back(&name); } + + virtual ~Module() { modules.remove_if([this](std::string* s) -> bool { return s ? *s == name : false; }); } - Module(void* h, App& a) : handle(h), app(a) {}; - virtual ~Module() {} virtual void run() = 0; virtual void onLoad() = 0; @@ -29,7 +35,7 @@ namespace Archimedes { void* handle; std::list::iterator self; - App& app; + App* app; std::unordered_map deps; }; diff --git a/modules/Print/src/Print.cpp b/modules/Print/src/Print.cpp index de33fea..f3a474d 100644 --- a/modules/Print/src/Print.cpp +++ b/modules/Print/src/Print.cpp @@ -1,6 +1,6 @@ #include "Print.h" -Print::Print(void* h, App& a) : Module(h, a) { +Print::Print(void* h, Archimedes::App* a) : Archimedes::Module(h, a) { name = "Print"; } @@ -10,5 +10,9 @@ Print::~Print() { void Print::run() { std::cout << "Print lib loaded and run!\n"; - app.stopModule(self); + + for(auto m : Archimedes::Module::GetModules()) + std::cout << m << std::endl; + + app->stopModule(self); } diff --git a/modules/Print/src/Print.h b/modules/Print/src/Print.h index 8ce423a..973402e 100644 --- a/modules/Print/src/Print.h +++ b/modules/Print/src/Print.h @@ -1,9 +1,9 @@ -#include "../../../include/Archimedes.h" +#include "Archimedes.h" -class Print : public Module { +class Print : public Archimedes::Module { public: - Print(void*, App&); + Print(void*, Archimedes::App*); ~Print(); void run(); void onLoad() {} @@ -11,7 +11,7 @@ class Print : public Module { }; extern "C" { - Module* create(void* handle, App& app) { + Archimedes::Module* create(void* handle, Archimedes::App* app) { return new Print(handle, app); } } diff --git a/src/main.cpp b/src/main.cpp index 3e65ab5..bed3777 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ #include "pch.hpp" -#include "App.h" +#include "utils/App/App.h" int main(int argc, char* argv[]) { Archimedes::App app(argc, argv);