25#include <rex/version.h>
32constexpr const char* FunctionSignature() {
33#if defined(__clang__) || defined(__GNUC__)
34 return __PRETTY_FUNCTION__;
41constexpr std::string_view ExtractTypeName() {
42 std::string_view signature = FunctionSignature<T>();
43#if defined(__clang__) || defined(__GNUC__)
44 constexpr std::string_view kMarker =
"T = ";
45 const size_t begin = signature.find(kMarker) + kMarker.size();
46 const size_t end = signature.find_first_of(
";]", begin);
48 constexpr std::string_view kMarker =
"FunctionSignature<";
49 const size_t begin = signature.find(kMarker) + kMarker.size();
50 const size_t end = signature.rfind(
">(");
52 std::string_view name = signature.substr(begin, end - begin);
53 for (std::string_view prefix :
54 {std::string_view(
"class "), std::string_view(
"struct "), std::string_view(
"enum ")}) {
55 if (name.starts_with(prefix)) {
56 name.remove_prefix(prefix.size());
63inline constexpr auto kTypeNameChars = [] {
64 constexpr std::string_view kName = ExtractTypeName<T>();
65 std::array<char, kName.size() + 1> chars{};
66 for (
size_t i = 0; i < kName.size(); ++i) {
74inline constexpr const char* kTypeName = kTypeNameChars<T>.data();
97#define REX_DETAIL_ID(x) x
114#define REX_DECLARE_INTERFACE(Name, version) \
115 class REX_DETAIL_ID(Name) : public ::rex::IInterface { \
117 static constexpr ::rex::InterfaceType kInterface{::rex::detail::kTypeName<Name>, version};
125#define REX_DECLARE_PRIVATE_INTERFACE(Name, version) \
126 class REX_DETAIL_ID(Name) : public ::rex::IInterface { \
128 static constexpr ::rex::InterfaceType kInterface{::rex::detail::kTypeName<Name>, version, true};
147 virtual std::vector<IInterface*>
FindAll(std::string_view name, u32 version) = 0;
155 template <
typename T>
157 return static_cast<T*
>(
Find(T::kInterface.name, T::kInterface.version));
166 template <
typename T>
168 std::vector<T*> found;
170 found.push_back(
static_cast<T*
>(iface));
178 virtual std::string_view GetName() const = 0;
185 virtual std::span<const
InterfaceType> GetRequiredInterfaces()
const {
return {}; }
192 virtual std::span<const InterfaceType> GetServedInterfaces()
const {
return {}; }
204 virtual void Disconnect() = 0;
222 virtual IInterface* QueryInterface(std::string_view name, u32 version) {
236template <
typename... Interfaces,
typename Module>
239 ((!found && name == Interfaces::kInterface.name && version == Interfaces::kInterface.version
240 ? (found =
static_cast<Interfaces*
>(&module))
252REX_API IInterfaceFactory* GetAppInterfaceFactory();
265 template <
typename T>
268 return factory ? factory->
Get<T>() :
nullptr;
272#define REX_INTERFACE(T) ::rex::AppInterfaces::Get<T>()
301template <
typename... Interfaces>
302struct ServedTypeList {
303 static constexpr InterfaceType kList[] = {Interfaces::kInterface...};
307inline std::vector<InterfaceType> ListServedInterfaces(
const IModule& module) {
308 std::vector<InterfaceType> types{IModule::kInterface};
309 for (
const InterfaceType& type : module.GetServedInterfaces()) {
310 if (std::string_view(type.name) != IModule::kInterface.name) {
311 types.push_back(type);
317template <
typename Module>
318IInterface* CreateModuleInterface(Module& module, std::string_view name, u32 version) {
319 if (name == IModule::kInterface.name && version == IModule::kInterface.version) {
320 return static_cast<IModule*
>(&module);
322 return module.QueryInterface(name, version);
326 const std::vector<InterfaceType> types = ListServedInterfaces(module);
327 const u32 count =
static_cast<u32
>(types.size());
328 for (u32 i = 0; i < count && i < capacity; ++i) {
351#define REX_MODULE_SERVES(...) \
352 ::std::span<const ::rex::InterfaceType> GetServedInterfaces() const override { \
353 return ::rex::detail::ServedTypeList<__VA_ARGS__>::kList; \
366#define REX_DECLARE_MODULE(ModuleClass) \
368 using ReXModuleType = ModuleClass; \
369 ReXModuleType& ReXModuleInstance() { \
370 static ModuleClass instance; \
374 extern "C" REX_DETAIL_EXPORT const char* ReXBuildIdentity() { \
375 return REXGLUE_BUILD_IDENTITY; \
377 extern "C" REX_DETAIL_EXPORT ::rex::IInterface* ReXCreateInterface(const char* name, \
378 ::rex::u32 version) { \
379 return ::rex::detail::CreateModuleInterface<ModuleClass>(ReXModuleInstance(), name, version); \
381 extern "C" REX_DETAIL_EXPORT ::rex::u32 ReXEnumerateInterfaces(::rex::InterfaceType* out, \
382 ::rex::u32 capacity) { \
383 return ::rex::detail::EnumerateModuleInterfaces(ReXModuleInstance(), out, capacity); \
static T * Get()
Definition module.h:266
std::vector< T * > FindAll()
Definition module.h:167
virtual IInterface * Find(std::string_view name, u32 version)=0
virtual std::vector< IInterface * > FindAll(std::string_view name, u32 version)=0
T * Get()
Definition module.h:156
#define REX_DECLARE_INTERFACE(Name, version)
Definition module.h:114
constexpr const char * kEnumerateInterfacesSymbol
Definition module.h:278
constexpr const char * kCreateInterfaceSymbol
Definition module.h:275
IInterface * FindModuleInterface(Module &module, std::string_view name, u32 version)
Definition module.h:237
IInterface *(*)(const char *name, u32 version) CreateInterfaceFn
Definition module.h:288
std::expected< T, Error > Result
Definition result.h:98
u32(*)(InterfaceType *out, u32 capacity) EnumerateInterfacesFn
Definition module.h:291
Result< void > Init(const Config &config)
constexpr const char * kBuildIdentitySymbol
Definition module.h:285
const char * name
Definition module.h:80
bool is_private
Definition module.h:82
Integer types, byte order wrappers and size literals.
Move only function, const propagating pointer and scope guard.