t7x/src/client/loader/component_loader.cpp

166 lines
3.3 KiB
C++
Raw Normal View History

2022-05-21 06:04:08 -04:00
#include <std_include.hpp>
#include "component_loader.hpp"
2022-05-27 13:08:39 -04:00
#include <utils/nt.hpp>
2022-11-11 11:00:34 -05:00
namespace component_loader
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
namespace
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
std::vector<std::unique_ptr<component_interface>>& get_components()
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
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,
[](const component_vector* component_vector)
{
pre_destroy();
delete component_vector;
});
return *components;
}
2022-11-11 11:00:34 -05:00
std::vector<registration_functor>& get_registration_functors()
{
2022-11-11 11:00:34 -05:00
static std::vector<registration_functor> functors;
return functors;
}
2022-11-11 11:00:34 -05:00
void activate_component(std::unique_ptr<component_interface> component)
{
2022-11-11 11:00:34 -05:00
auto& components = get_components();
components.push_back(std::move(component));
std::ranges::stable_sort(components, [](const std::unique_ptr<component_interface>& a,
const std::unique_ptr<component_interface>& b)
{
return a->priority() > b->priority();
});
}
2022-11-11 11:00:34 -05:00
}
2022-11-11 11:00:34 -05:00
void register_component(registration_functor functor)
{
if (!get_components().empty())
{
throw std::runtime_error("Registration is too late");
}
2022-11-11 11:00:34 -05:00
get_registration_functors().push_back(std::move(functor));
}
2022-11-11 11:00:34 -05:00
bool activate()
{
2022-11-11 11:00:34 -05:00
static auto res = []
{
2022-11-11 11:00:34 -05:00
try
{
2022-11-11 11:00:34 -05:00
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;
2022-05-29 10:46:49 -04:00
}
2022-05-21 06:04:08 -04:00
2022-11-11 11:00:34 -05:00
return true;
}();
2022-05-29 10:46:49 -04:00
2022-11-11 11:00:34 -05:00
return res;
}
2022-05-21 06:04:08 -04:00
2022-11-11 11:00:34 -05:00
bool post_load()
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
static auto res = []
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
try
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
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;
2022-05-29 10:46:49 -04:00
}
2022-11-11 11:00:34 -05:00
return true;
}();
2022-05-29 10:46:49 -04:00
2022-11-11 11:00:34 -05:00
return res;
2022-05-21 06:04:08 -04:00
}
2022-11-11 11:00:34 -05:00
void post_unpack()
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
static auto res = []
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
try
2022-05-29 10:46:49 -04:00
{
2022-11-11 11:00:34 -05:00
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;
2022-05-29 10:46:49 -04:00
}
2022-11-11 11:00:34 -05:00
return true;
}();
2022-05-21 06:04:08 -04:00
2022-11-11 11:00:34 -05:00
if (!res)
{
TerminateProcess(GetCurrentProcess(), 1);
}
2022-05-21 06:04:08 -04:00
}
2022-11-11 11:00:34 -05:00
void pre_destroy()
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
static auto res = []
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
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)
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
TerminateProcess(GetCurrentProcess(), 1);
2022-05-21 06:04:08 -04:00
}
}
2022-11-11 11:00:34 -05:00
void trigger_premature_shutdown()
2022-05-21 06:04:08 -04:00
{
2022-11-11 11:00:34 -05:00
throw premature_shutdown_trigger();
}
2022-05-21 06:04:08 -04:00
}