#include #include "component_loader.hpp" #include namespace component_loader { namespace { std::vector>& get_components() { using component_vector = std::vector>; using component_vector_container = std::unique_ptr> ; static component_vector_container components(new component_vector, [](const component_vector* component_vector) { pre_destroy(); delete component_vector; }); return *components; } std::vector& get_registration_functors() { static std::vector functors; return functors; } void activate_component(std::unique_ptr component) { auto& components = get_components(); components.push_back(std::move(component)); std::ranges::stable_sort(components, [](const std::unique_ptr& a, const std::unique_ptr& b) { return a->priority() > b->priority(); }); } } void register_component(registration_functor functor) { if (!get_components().empty()) { throw std::runtime_error("Registration is too late"); } get_registration_functors().push_back(std::move(functor)); } bool activate() { static auto res = [] { try { for (auto& functor : get_registration_functors()) { activate_component(functor()); } } catch (premature_shutdown_trigger&) { return false; } catch (const std::exception& e) { MessageBoxA(nullptr, e.what(), "Error", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); return false; } return true; }(); return res; } bool post_load() { static auto res = [] { try { for (const auto& component : get_components()) { component->post_load(); } } catch (premature_shutdown_trigger&) { return false; } catch (const std::exception& e) { MessageBoxA(nullptr, e.what(), "Error", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); return false; } return true; }(); return res; } void post_unpack() { static auto res = [] { try { for (const auto& component : get_components()) { component->post_unpack(); } } catch (const std::exception& e) { MessageBoxA(nullptr, e.what(), "Error", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); return false; } return true; }(); if (!res) { TerminateProcess(GetCurrentProcess(), 1); } } void pre_destroy() { static auto res = [] { try { for (const auto& component : get_components()) { component->pre_destroy(); } } catch (const std::exception& e) { MessageBoxA(nullptr, e.what(), "Error", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); return false; } return true; }(); if (!res) { TerminateProcess(GetCurrentProcess(), 1); } } void trigger_premature_shutdown() { throw premature_shutdown_trigger(); } }