From 9c54a508105d8bd69239f746f262f178edf8bc89 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Thu, 18 Jan 2024 18:23:24 +0100 Subject: [PATCH] improve plugin facing api with c++ helpers --- solanaceae/plugin/plugin_manager.hpp | 24 +---------- solanaceae/plugin/solana_plugin_v1.h | 64 ++++++++++++++++++++++++++++ solanaceae/plugin/version_helper.inl | 25 +++++++++++ 3 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 solanaceae/plugin/version_helper.inl diff --git a/solanaceae/plugin/plugin_manager.hpp b/solanaceae/plugin/plugin_manager.hpp index be1b280..1637fce 100644 --- a/solanaceae/plugin/plugin_manager.hpp +++ b/solanaceae/plugin/plugin_manager.hpp @@ -21,29 +21,7 @@ void g_provideInstance__internal(const char* id, const char* version, const char } // extern C -namespace internal { - template - class g_type_version { - typedef char yes[1]; - typedef char no [2]; - - template static yes& test_version(decltype(&C::version)); - template static no& test_version(...); - - static bool const has_version = sizeof(test_version(nullptr)) == sizeof(yes); - static constexpr const char* get_version(void) { - if constexpr (has_version) { - return T::version; - } else { - return "UNK"; // default version - } - } - - public: - static constexpr const char* version = get_version(); - }; -} // internal - +#include "./version_helper.inl" // templated helper, use or make sure vtable is right template diff --git a/solanaceae/plugin/solana_plugin_v1.h b/solanaceae/plugin/solana_plugin_v1.h index 86680b1..698f0c2 100644 --- a/solanaceae/plugin/solana_plugin_v1.h +++ b/solanaceae/plugin/solana_plugin_v1.h @@ -51,6 +51,7 @@ SOLANA_PLUGIN_EXPORT void solana_plugin_stop(void); // ---------- called periodically ---------- // rendering needs to be called in a different interval AND needs to be garantied from mainthread // the functions return the minimum time in seconds until the update should be called next +// the interval is not garantied. in fact, clients can call them with a much longer interval // for compute tasks SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float delta); @@ -59,6 +60,69 @@ SOLANA_PLUGIN_EXPORT float solana_plugin_render(float delta); #ifdef __cplusplus } + +// in c++ we can provide generic helpers +#include "./version_helper.inl" + +#include + +// templated helper, use or make sure vtable is right + +// versioned means explicitly provided + +// ---------- provide ---------- +template +static void plug_provideInstance(const SolanaAPI* solana_api, const char* id, const char* version, const char* plugin_name, T* instance) { + solana_api->provideInstance(id, version, plugin_name, instance); +} + +template +static void plug_provideInstance(const SolanaAPI* solana_api, const char* id, const char* plugin_name, T* instance) { + plug_provideInstance(solana_api, id, internal::g_type_version::version, plugin_name, instance); +} + +#define PLUG_PROVIDE_INSTANCE_VERSIONED(x, ver, p, i) plug_provideInstance(solana_api, #x, ver, p, i) +#define PLUG_PROVIDE_INSTANCE(x, p, i) plug_provideInstance(solana_api, #x, p, i) + +// ---------- resolve optional ---------- + +template +static T* plug_resolveInstanceOptional(const SolanaAPI* solana_api, const char* id, const char* version) { + return static_cast(solana_api->resolveInstance(id, version)); +} + +template +static T* plug_resolveInstanceOptional(const SolanaAPI* solana_api, const char* id) { + return plug_resolveInstanceOptional(solana_api, id, internal::g_type_version::version); +} + +// ---------- resolve require ---------- +// throws if id+version is not found + +struct ResolveException { + std::string what; +}; + +template +static T* plug_resolveInstance(const SolanaAPI* solana_api, const char* id, const char* version) { + T* res = plug_resolveInstanceOptional(solana_api, id, version); + if (res == nullptr) { + throw ResolveException{"missing " + std::string{id} + " " + version}; + } + return res; +} +template +static T* plug_resolveInstance(const SolanaAPI* solana_api, const char* id) { + return plug_resolveInstance(solana_api, id, internal::g_type_version::version); +} + +#define PLUG_RESOLVE_INSTANCE_VERSIONED(x, ver) plug_resolveInstance(solana_api, #x, ver) +#define PLUG_RESOLVE_INSTANCE(x) plug_resolveInstance(solana_api, #x) + +// optional variants dont error +#define PLUG_RESOLVE_INSTANCE_VERSIONED_OPT(x, ver) plug_resolveInstanceOptional(solana_api, #x, ver) +#define PLUG_RESOLVE_INSTANCE_OPT(x) plug_resolveInstanceOptional(solana_api, #x) + #endif #endif // SOLANA_PLUGIN__H diff --git a/solanaceae/plugin/version_helper.inl b/solanaceae/plugin/version_helper.inl new file mode 100644 index 0000000..6876ed5 --- /dev/null +++ b/solanaceae/plugin/version_helper.inl @@ -0,0 +1,25 @@ +#pragma once + +namespace internal { + template + class g_type_version { + typedef char yes[1]; + typedef char no [2]; + + template static yes& test_version(decltype(&C::version)); + template static no& test_version(...); + + static bool const has_version = sizeof(test_version(nullptr)) == sizeof(yes); + static constexpr const char* get_version(void) { + if constexpr (has_version) { + return T::version; + } else { + return "UNK"; // default version + } + } + + public: + static constexpr const char* version = get_version(); + }; +} // internal +