mirror of https://github.com/Xaymar/obs-StreamFX
code: Add a proper dynamic loader for components
This loader model should have wider compatibility, as it relies on defined C++ behavior instead of undefined preprocessor behavior. We may even be able to implement a simple dependency system that automatically sorts components into the correct order.
This commit is contained in:
parent
65c45c4461
commit
49f763aa44
|
@ -76,6 +76,8 @@
|
|||
|
||||
#include "warning-disable.hpp"
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include "warning-enable.hpp"
|
||||
|
||||
|
@ -83,11 +85,60 @@ static std::shared_ptr<streamfx::util::threadpool::threadpool> _threadpool;
|
|||
static std::shared_ptr<streamfx::gfx::opengl> _streamfx_gfx_opengl;
|
||||
static std::shared_ptr<streamfx::obs::source_tracker> _source_tracker;
|
||||
|
||||
namespace streamfx {
|
||||
typedef std::list<loader_function_t> loader_list_t;
|
||||
typedef std::map<loader_priority_t, loader_list_t> loader_map_t;
|
||||
|
||||
loader_map_t& get_initializers()
|
||||
{
|
||||
static loader_map_t initializers;
|
||||
return initializers;
|
||||
}
|
||||
|
||||
loader_map_t& get_finalizers()
|
||||
{
|
||||
static loader_map_t finalizers;
|
||||
return finalizers;
|
||||
}
|
||||
|
||||
loader::loader(loader_function_t initializer, loader_function_t finalizer, loader_priority_t priority)
|
||||
{
|
||||
auto init_kv = get_initializers().find(priority);
|
||||
if (init_kv != get_initializers().end()) {
|
||||
init_kv->second.push_back(initializer);
|
||||
} else {
|
||||
get_initializers().emplace(priority, loader_list_t{initializer});
|
||||
}
|
||||
|
||||
// Invert the order for finalizers.
|
||||
auto ipriority = priority ^ static_cast<loader_priority_t>(0xFFFFFFFFFFFFFFFF);
|
||||
auto fina_kv = get_finalizers().find(ipriority);
|
||||
if (fina_kv != get_finalizers().end()) {
|
||||
fina_kv->second.push_back(finalizer);
|
||||
} else {
|
||||
get_finalizers().emplace(ipriority, loader_list_t{finalizer});
|
||||
}
|
||||
}
|
||||
} // namespace streamfx
|
||||
|
||||
MODULE_EXPORT bool obs_module_load(void)
|
||||
{
|
||||
try {
|
||||
DLOG_INFO("Loading Version %s", STREAMFX_VERSION_STRING);
|
||||
|
||||
// Run all initializers.
|
||||
for (auto kv : streamfx::get_initializers()) {
|
||||
for (auto init : kv.second) {
|
||||
try {
|
||||
init();
|
||||
} catch (const std::exception& ex) {
|
||||
DLOG_ERROR("Initializer threw exception: %s", ex.what());
|
||||
} catch (...) {
|
||||
DLOG_ERROR("Initializer threw unknown exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize global configuration.
|
||||
streamfx::configuration::initialize();
|
||||
|
||||
|
@ -290,6 +341,19 @@ MODULE_EXPORT void obs_module_unload(void)
|
|||
// Finalize Thread Pool
|
||||
_threadpool.reset();
|
||||
|
||||
// Run all finalizers.
|
||||
for (auto kv : streamfx::get_finalizers()) {
|
||||
for (auto init : kv.second) {
|
||||
try {
|
||||
init();
|
||||
} catch (const std::exception& ex) {
|
||||
DLOG_ERROR("Finalizer threw exception: %s", ex.what());
|
||||
} catch (...) {
|
||||
DLOG_ERROR("Finalizer threw unknown exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLOG_INFO("Unloaded Version %s", STREAMFX_VERSION_STRING);
|
||||
} catch (std::exception const& ex) {
|
||||
DLOG_ERROR("Unexpected exception in function '%s': %s", __FUNCTION_NAME__, ex.what());
|
||||
|
|
|
@ -5,7 +5,36 @@
|
|||
#pragma once
|
||||
#include "common.hpp"
|
||||
|
||||
#include "warning-disable.hpp"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include "warning-enable.hpp"
|
||||
|
||||
namespace streamfx {
|
||||
/** Simple but efficient loader structure for ordered initia-/finalize.
|
||||
*
|
||||
*/
|
||||
typedef int32_t loader_priority_t;
|
||||
typedef std::function<void()> loader_function_t;
|
||||
enum loader_priority : loader_priority_t {
|
||||
HIGHEST = INT32_MIN,
|
||||
HIGHER = INT32_MIN / 4 * 3,
|
||||
HIGH = INT32_MIN / 4 * 2,
|
||||
ABOVE = INT32_MIN / 4,
|
||||
NORMAL = 0,
|
||||
BELOW = INT32_MAX / 4,
|
||||
LOW = INT32_MAX / 4 * 2,
|
||||
LOWER = INT32_MAX / 4 * 3,
|
||||
LOWEST = INT32_MAX,
|
||||
};
|
||||
|
||||
struct loader {
|
||||
loader(loader_function_t initializer, loader_function_t finalizer, loader_priority_t priority);
|
||||
|
||||
// Usage:
|
||||
// auto loader = streamfx::loader([]() { ... }, []() { ... }, 0);
|
||||
};
|
||||
|
||||
// Threadpool
|
||||
std::shared_ptr<streamfx::util::threadpool::threadpool> threadpool();
|
||||
|
||||
|
|
Loading…
Reference in New Issue