improve plugin facing api with c++ helpers
This commit is contained in:
parent
87b3d15a2b
commit
9c54a50810
@ -21,29 +21,7 @@ void g_provideInstance__internal(const char* id, const char* version, const char
|
||||
|
||||
} // extern C
|
||||
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
class g_type_version {
|
||||
typedef char yes[1];
|
||||
typedef char no [2];
|
||||
|
||||
template<typename C> static yes& test_version(decltype(&C::version));
|
||||
template<typename C> static no& test_version(...);
|
||||
|
||||
static bool const has_version = sizeof(test_version<T>(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<typename T>
|
||||
|
@ -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 <string>
|
||||
|
||||
// templated helper, use or make sure vtable is right
|
||||
|
||||
// versioned means explicitly provided
|
||||
|
||||
// ---------- provide ----------
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
static void plug_provideInstance(const SolanaAPI* solana_api, const char* id, const char* plugin_name, T* instance) {
|
||||
plug_provideInstance<T>(solana_api, id, internal::g_type_version<T>::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<typename T>
|
||||
static T* plug_resolveInstanceOptional(const SolanaAPI* solana_api, const char* id, const char* version) {
|
||||
return static_cast<T*>(solana_api->resolveInstance(id, version));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T* plug_resolveInstanceOptional(const SolanaAPI* solana_api, const char* id) {
|
||||
return plug_resolveInstanceOptional<T>(solana_api, id, internal::g_type_version<T>::version);
|
||||
}
|
||||
|
||||
// ---------- resolve require ----------
|
||||
// throws if id+version is not found
|
||||
|
||||
struct ResolveException {
|
||||
std::string what;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static T* plug_resolveInstance(const SolanaAPI* solana_api, const char* id, const char* version) {
|
||||
T* res = plug_resolveInstanceOptional<T>(solana_api, id, version);
|
||||
if (res == nullptr) {
|
||||
throw ResolveException{"missing " + std::string{id} + " " + version};
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<typename T>
|
||||
static T* plug_resolveInstance(const SolanaAPI* solana_api, const char* id) {
|
||||
return plug_resolveInstance<T>(solana_api, id, internal::g_type_version<T>::version);
|
||||
}
|
||||
|
||||
#define PLUG_RESOLVE_INSTANCE_VERSIONED(x, ver) plug_resolveInstance<x>(solana_api, #x, ver)
|
||||
#define PLUG_RESOLVE_INSTANCE(x) plug_resolveInstance<x>(solana_api, #x)
|
||||
|
||||
// optional variants dont error
|
||||
#define PLUG_RESOLVE_INSTANCE_VERSIONED_OPT(x, ver) plug_resolveInstanceOptional<x>(solana_api, #x, ver)
|
||||
#define PLUG_RESOLVE_INSTANCE_OPT(x) plug_resolveInstanceOptional<x>(solana_api, #x)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SOLANA_PLUGIN__H
|
||||
|
25
solanaceae/plugin/version_helper.inl
Normal file
25
solanaceae/plugin/version_helper.inl
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
namespace internal {
|
||||
template<typename T>
|
||||
class g_type_version {
|
||||
typedef char yes[1];
|
||||
typedef char no [2];
|
||||
|
||||
template<typename C> static yes& test_version(decltype(&C::version));
|
||||
template<typename C> static no& test_version(...);
|
||||
|
||||
static bool const has_version = sizeof(test_version<T>(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
|
||||
|
Loading…
Reference in New Issue
Block a user