omni/core/ITypeFactory.h
File members: omni/core/ITypeFactory.h
// Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "../../carb/Defines.h"
#include "IObject.h"
#include "ModuleExports.h"
#include "Omni.h"
#include "Result.h"
#include <cstdint>
#include <vector>
namespace omni
{
namespace core
{
OMNI_DECLARE_INTERFACE(ITypeFactory);
using InterfaceImplementationCreateFn = IObject*();
struct OMNI_ATTR("no_py") InterfaceImplementation
{
const char* name;
InterfaceImplementationCreateFn* createFn;
uint32_t version;
const char** interfacesImplemented;
uint32_t interfacesImplementedCount;
};
using TypeFactoryLoadFlags OMNI_ATTR("flag, prefix=fTypeFactoryFlag") = uint32_t;
constexpr TypeFactoryLoadFlags fTypeFactoryFlagNone = 0x0;
class ITypeFactory_abi : public omni::core::Inherits<omni::core::IObject, OMNI_TYPE_ID("omni.core.ITypeFactory")>
{
protected:
virtual IObject* OMNI_ATTR("no_py")
createType_abi(TypeId id, OMNI_ATTR("c_str") const char* moduleName, uint32_t implVersion) noexcept = 0;
virtual Result registerInterfaceImplementationsFromModule_abi(OMNI_ATTR("c_str, not_null") const char* moduleName,
TypeFactoryLoadFlags flags) noexcept = 0;
virtual Result unregisterInterfaceImplementationsFromModule_abi(OMNI_ATTR("c_str, not_null")
const char* moduleName) noexcept = 0;
virtual OMNI_ATTR("no_py") void registerInterfaceImplementations_abi(
OMNI_ATTR("in, count=implementationsCount, not_null") const InterfaceImplementation* implementations,
uint32_t implementationsCount,
TypeFactoryLoadFlags flags) noexcept = 0;
virtual const char* getTypeIdName_abi(TypeId id) noexcept = 0;
virtual void setInterfaceDefaults_abi(TypeId interfaceId,
TypeId implId,
OMNI_ATTR("c_str") const char* moduleName,
uint32_t implVersion) noexcept = 0;
virtual OMNI_ATTR("no_py") Result
getInterfaceDefaults_abi(TypeId interfaceId,
OMNI_ATTR("out") TypeId* outImplId, // nullptr accepted
OMNI_ATTR("out" /*count=*inOutModuleNameCount*/) char* outModuleName, // nullptr
// accepted
OMNI_ATTR("in, out, not_null") uint32_t* inOutModuleNameCount, // must not be null
OMNI_ATTR("out") uint32_t* outImplVersion) noexcept = 0; // nullptr accepted
};
constexpr uint16_t kTypeFactoryArgsVersion = 1;
class TypeFactoryArgs
{
public:
uint16_t version;
uint16_t byteCount;
uint8_t padding[4];
omni::log::ILog* log;
omni::structuredlog::IStructuredLog* structuredLog;
void* reserved[13];
TypeFactoryArgs()
{
std::memset(this, 0, sizeof(*this));
version = kTypeFactoryArgsVersion;
byteCount = sizeof(*this);
}
TypeFactoryArgs(omni::log::ILog* log_, omni::structuredlog::IStructuredLog* strucLog_) : TypeFactoryArgs()
{
log = log_;
structuredLog = strucLog_;
}
};
CARB_ASSERT_INTEROP_SAFE(TypeFactoryArgs);
static_assert((8 + 15 * sizeof(void*)) == sizeof(TypeFactoryArgs), "TypeFactoryArgs has an unexpected size");
} // namespace core
} // namespace omni
#include "ITypeFactory.gen.h"
#ifdef OMNI_COMPILE_AS_DYNAMIC_LIBRARY
OMNI_API omni::core::ITypeFactory* omniGetTypeFactoryWithoutAcquire();
#else
inline omni::core::ITypeFactory* omniGetTypeFactoryWithoutAcquire()
{
return static_cast<omni::core::ITypeFactory*>(omniGetBuiltInWithoutAcquire(OmniBuiltIn::eITypeFactory));
}
#endif
OMNI_API omni::core::ITypeFactory* omniCreateTypeFactory(const omni::core::TypeFactoryArgs* args = nullptr);
// clang-format off
OMNI_DEFINE_INTERFACE_API(omni::core::ITypeFactory)
{
public:
template <typename T>
inline ObjectPtr<T> createType(const char* moduleName = nullptr, uint32_t version = 0) noexcept
{
return createType<T>(T::kTypeId, moduleName, version);
}
template <typename T = IObject>
inline ObjectPtr<T> createType(TypeId id, const char* moduleName = nullptr, uint32_t version = 0) noexcept
{
auto ptr = steal(createType_abi(id, moduleName, version));
return ptr.template as<T>();
}
};
// clang-format on
namespace omni
{
namespace core
{
template <typename T>
inline ObjectPtr<T> createType(const char* moduleName = nullptr, uint32_t version = 0) throw()
{
return omniGetTypeFactoryWithoutAcquire()->createType<T>(moduleName, version);
}
template <typename T = IObject>
inline ObjectPtr<T> createType(TypeId id, const char* moduleName = nullptr, uint32_t version = 0) CARB_NOEXCEPT
{
return omniGetTypeFactoryWithoutAcquire()->createType<T>(id, moduleName, version);
}
inline Result registerInterfaceImplementationsFromModule(const char* moduleName, // e.g. omni.scripting-python.dll
TypeFactoryLoadFlags flags = 0) CARB_NOEXCEPT
{
return omniGetTypeFactoryWithoutAcquire()->registerInterfaceImplementationsFromModule(moduleName, flags);
}
inline void registerInterfaceImplementations(const InterfaceImplementation* implementations,
uint32_t implementationsCount,
TypeFactoryLoadFlags flags = 0) CARB_NOEXCEPT
{
return omniGetTypeFactoryWithoutAcquire()->registerInterfaceImplementations(
implementations, implementationsCount, flags);
}
inline const char* getTypeIdName(TypeId id) CARB_NOEXCEPT
{
return omniGetTypeFactoryWithoutAcquire()->getTypeIdName(id);
}
template <typename T>
inline void setInterfaceDefaults(TypeId implId, const char* moduleName, uint32_t implVersion)
{
omniGetTypeFactoryWithoutAcquire()->setInterfaceDefaults(T::kTypeId, implId, moduleName, implVersion);
}
template <typename T>
inline Result getInterfaceDefaults(TypeId* implId, std::string* moduleName, uint32_t* implVersion)
{
if (!moduleName)
{
uint32_t moduleNameCount = 0;
Result result = omniGetTypeFactoryWithoutAcquire()->getInterfaceDefaults(
T::kTypeId, implId, nullptr, &moduleNameCount, implVersion);
return result;
}
else
{
// loop here in case the module name size changes between checking for the size and actually get the string.
std::vector<char> buffer;
for (unsigned i = 0; i < 4; ++i)
{
uint32_t moduleNameCount = uint32_t(buffer.size());
Result result = omniGetTypeFactoryWithoutAcquire()->getInterfaceDefaults(
T::kTypeId, implId, buffer.data(), &moduleNameCount, implVersion);
if (kResultInsufficientBuffer != result)
{
*moduleName = buffer.data();
return result;
}
else
{
buffer.resize(moduleNameCount);
}
}
return kResultTryAgain;
}
}
inline Result unregisterInterfaceImplementationsFromModule(const char* moduleName) CARB_NOEXCEPT
{
return omniGetTypeFactoryWithoutAcquire()->unregisterInterfaceImplementationsFromModule(moduleName);
}
} // namespace core
} // namespace omni