mirror of
https://github.com/diamante0018/MW3ServerFreezer.git
synced 2025-07-01 00:31:48 +00:00
Refactor this (tekno gods dont sue please)
This commit is contained in:
21
src/client/loader/component_interface.hpp
Normal file
21
src/client/loader/component_interface.hpp
Normal 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; }
|
||||
};
|
111
src/client/loader/component_loader.cpp
Normal file
111
src/client/loader/component_loader.cpp
Normal 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;
|
||||
}
|
51
src/client/loader/component_loader.hpp
Normal file
51
src/client/loader/component_loader.hpp
Normal 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; \
|
||||
}
|
Reference in New Issue
Block a user