Skeleton.h
// Skeleton.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2020
@import "cxRpc.h"
@import "Ceda/cxObject/Object.h"
#include "Ceda/cxUtils/Archive.h"
namespace ceda
{
class Skeleton;
///////////////////////////////////////////////////////////////////////////////////////////////////
// ISkeletonFactory
struct ISkeletonFactory
{
virtual Skeleton* CreateSkeleton() = 0;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Skeleton factory registry
// The SkeletonFactoryRegistry is a transient registry indexed by fully qualified name of the
// interface.
// This allows the system to automatically generate a suitable skeleton object for a given interface
// The following three functions can be called by different threads - they are fully threadsafe.
// Returns false if skeleton factory has already been registered
@api bool RegisterSkeleton(ConstStringZ qualifiedInterfaceName, ISkeletonFactory* factory);
@api void UnregisterSkeleton(ConstStringZ qualifiedInterfaceName);
// Create a skeleton for the given interface for which a skeleton factory has previously been
// registered.
// This must be deleted using C++ delete keyword
// Returns nullptr if no skeleton factory for the given interface has been registered.
@api Skeleton* CreateSkeleton(ConstStringZ qualifiedInterfaceName);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Skeleton
typedef void (*SkeletonThunkFn)(void* self);
/*
template<typename T>
struct SkeletonThunkFnTable3
{
static void sThunk0(void* self) { ((T*)self)->Thunk0(); }
static void sThunk1(void* self) { ((T*)self)->Thunk1(); }
static void sThunk2(void* self) { ((T*)self)->Thunk2(); }
static const SkeletonThunkFn* Table()
{
static const SkeletonThunkFn t[] =
{
&sThunk0,
&sThunk1,
&sThunk2,
};
return t;
}
};
*/
class Skeleton
{
cxNotCloneable(Skeleton)
public:
explicit Skeleton(const SkeletonThunkFn* skeletonThunkFnTable, ssize_t numMethods) :
m_ar(nullptr),
m_skeletonThunkFnTable(skeletonThunkFnTable),
numMethods(numMethods)
{
}
// Returns read-archive for reading the in-parameters
inline InputArchive& Pop() { return m_ar; }
// Test whether the given index is valid
inline bool ValidIndex(ssize_t index) const { return 0 <= index && index < numMethods; }
// The ultimate receiver of the messages. It is assumed this can be reinterpret cast to the
// interface associated with this Skeleton.
AnyInterface m_delegate;
InputArchive m_ar;
const SkeletonThunkFn* m_skeletonThunkFnTable;
ssize_t numMethods;
};
} // namespace ceda