#include "App.h" Archimedes::App* Archimedes::App::instance = nullptr; namespace Archimedes { App::App() { if(instance != nullptr) { std::cout << "App already exists\nThere can only be one!\n"; std::abort(); } instance = this; } App::~App() { for(auto it = modules.begin(); it != modules.end(); it++) { void* handle = (*it)->getHandle(); delete *it; if(handle) dlclose(handle); it = modules.erase(it); } } Module* App::dynamicLoad(std::string lib) { 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 nullptr; } 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; return nullptr; } return create(h, Get()); } std::list::iterator App::load(Module* m, std::list blacklist = {}) { if(!m) { return modules.end(); } void* h = m->getHandle(); for(auto it = blacklist.begin(); it != blacklist.end(); it++) { if(*it == m->getName()) { std::cout << "Module \"" << *it << "\" is already loaded!\n"; delete m; if(h) dlclose(h); return modules.end(); } } 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 { if(std::holds_alternative(it->second)) m->depsInstances[it->first] = load(std::get(it->second), blacklist); else m->depsInstances[it->first] = load(std::get(it->second), blacklist); } } modules.push_back(m); m->setSelf(--modules.end()); modules.end()++; /* m->setSelf(modules.end()); modules.push_back(m); */ return m->self; } std::list::iterator App::load(std::string modulePath, std::list blacklist = {}) { Module* m = dynamicLoad(modulePath); return load(m, blacklist); } void App::unload(std::list::iterator it) { Module* m = *it; void* h = m->getHandle(); modules.erase(m->self); delete m; if(h) dlclose(h); } void App::stopModule(std::list::iterator it) { toClose.push_back(*it); } void App::startModule(std::string lib) { toOpen.push_back(lib); } }