Stub.h
// Stub.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 Stub;
///////////////////////////////////////////////////////////////////////////////////////////////////
// IStubFactory
struct IStubFactory
{
virtual Stub* CreateStub() = 0;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Stub factory registry
// The StubFactoryRegistry is a transient registry indexed by fully qualified name of the
// interface.
// This allows the system to automatically generate a suitable stub object for a given interface
// The following three functions can be called by different threads - they are fully threadsafe.
// Returns false if stub factory has already been registered
@api bool RegisterStub(ConstStringZ qualifiedInterfaceName, IStubFactory* factory);
@api void UnregisterStub(ConstStringZ qualifiedInterfaceName);
// Create a stub for the given interface for which a stub factory has previously been
// registered.
// Returns nullptr if no stub factory for the given interface has been registered.
@api Stub* CreateStub(ConstStringZ qualifiedInterfaceName);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Stub
/*
Base class for a stub. More specifically, for a stub for a single implemented interface on a
single object.
*/
class @api Stub : public BaseMixin<Stub,EmptyBase>
{
cxNotCloneable(Stub)
public:
Stub(AnyInterface stub, ssize_t numMethods) :
m_ar(nullptr),
m_stub(stub),
numMethods(numMethods)
{
// We assume there are no more than 256 methods, allowing the method index to be
// serialised with a single octet.
// todo: Xcpp should allow for an alternative Stub to be used which uses two octets for the
// index when the number of methods exceeds 256
cxAssert(numMethods <= 256);
}
inline Archive& StubBegin(ssize_t index) const
{
cxAssert(0 <= index && index <= numMethods);
*m_ar << (octet_t) index;
return *m_ar; // Return the archive used to push the arguments
}
public:
Archive* m_ar;
AnyInterface m_stub; // It is assumed this can be reinterpret cast to the interface provided by the stub
ssize_t numMethods;
};
} // namespace ceda