Refactor this (tekno gods dont sue please)

This commit is contained in:
2022-04-22 15:35:14 +02:00
parent 4e1dfcfc3c
commit b48ab294b8
46 changed files with 341 additions and 201 deletions

View File

@ -0,0 +1,21 @@
#pragma once
class component_interface {
public:
virtual ~component_interface() {}
virtual void post_start() {}
virtual void post_load() {}
virtual void pre_destroy() {}
virtual void post_unpack() {}
virtual void* load_import([[maybe_unused]] const std::string& library,
[[maybe_unused]] const std::string& function) {
return nullptr;
}
virtual bool is_supported() { return true; }
};

View File

@ -0,0 +1,111 @@
#include <std_include.hpp>
#include "component_loader.hpp"
void component_loader::register_component(
std::unique_ptr<component_interface>&& component_) {
get_components().push_back(std::move(component_));
}
bool component_loader::post_start() {
static auto handled = false;
if (handled)
return true;
handled = true;
try {
for (const auto& component_ : get_components()) {
component_->post_start();
}
} catch (premature_shutdown_trigger&) {
return false;
}
return true;
}
bool component_loader::post_load() {
static auto handled = false;
if (handled)
return true;
handled = true;
clean();
try {
for (const auto& component_ : get_components()) {
component_->post_load();
}
} catch (premature_shutdown_trigger&) {
return false;
}
return true;
}
void component_loader::post_unpack() {
static auto handled = false;
if (handled)
return;
handled = true;
for (const auto& component_ : get_components()) {
component_->post_unpack();
}
}
void component_loader::pre_destroy() {
static auto handled = false;
if (handled)
return;
handled = true;
for (const auto& component_ : get_components()) {
component_->pre_destroy();
}
}
void component_loader::clean() {
auto& components = get_components();
for (auto i = components.begin(); i != components.end();) {
if (!(*i)->is_supported()) {
(*i)->pre_destroy();
i = components.erase(i);
} else {
++i;
}
}
}
void* component_loader::load_import(const std::string& library,
const std::string& function) {
void* function_ptr = nullptr;
for (const auto& component_ : get_components()) {
auto* const component_function_ptr =
component_->load_import(library, function);
if (component_function_ptr) {
function_ptr = component_function_ptr;
}
}
return function_ptr;
}
void component_loader::trigger_premature_shutdown() {
throw premature_shutdown_trigger();
}
std::vector<std::unique_ptr<component_interface>>&
component_loader::get_components() {
using component_vector = std::vector<std::unique_ptr<component_interface>>;
using component_vector_container =
std::unique_ptr<component_vector, std::function<void(component_vector*)>>;
static component_vector_container components(
new component_vector, [](component_vector* component_vector) {
pre_destroy();
delete component_vector;
});
return *components;
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "component_interface.hpp"
class component_loader final {
public:
class premature_shutdown_trigger final : public std::exception {
[[nodiscard]] const char* what() const noexcept override {
return "Premature shutdown requested";
}
};
template <typename T> class installer final {
static_assert(std::is_base_of<component_interface, T>::value,
"component has invalid base class");
public:
installer() { register_component(std::make_unique<T>()); }
};
template <typename T> static T* get() {
for (const auto& component_ : get_components()) {
if (typeid(*component_.get()) == typeid(T)) {
return reinterpret_cast<T*>(component_.get());
}
}
return nullptr;
}
static void
register_component(std::unique_ptr<component_interface>&& component);
static bool post_start();
static bool post_load();
static void post_unpack();
static void pre_destroy();
static void clean();
static void* load_import(const std::string& library,
const std::string& function);
static void trigger_premature_shutdown();
private:
static std::vector<std::unique_ptr<component_interface>>& get_components();
};
#define REGISTER_COMPONENT(name) \
namespace { \
static component_loader::installer<name> __component; \
}