174 lines
5.1 KiB
C++
174 lines
5.1 KiB
C++
#pragma once
|
|
|
|
#include "dtcore/inc/dtdefinitions.h"
|
|
#include "dtcore/inc/dtstream.h"
|
|
#include "dtcore/inc/dttypeinfo.h"
|
|
#include "dtcore/inc/dtmemory.h"
|
|
#include "dtcore/inc/dtfunctor.h"
|
|
|
|
namespace dt
|
|
{
|
|
|
|
class Message : public Serializable
|
|
{
|
|
DT_DECLARE_ROOT_TYPE(Message);
|
|
public:
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class ConnectionDescriptor;
|
|
class MessageFactoryImpl;
|
|
|
|
class MessageCallbackAdapterBase
|
|
{
|
|
public:
|
|
virtual ~MessageCallbackAdapterBase() {}
|
|
virtual void Thunk(const ConnectionDescriptor& descriptor, const String& route, Message* msg) = 0;
|
|
};
|
|
|
|
template <class T> class MessageCallbackAdapter : public MessageCallbackAdapterBase
|
|
{
|
|
public:
|
|
MessageCallbackAdapter() {}
|
|
MessageCallbackAdapter(const Functor2<const ConnectionDescriptor&, T*>& callback)
|
|
: m_Callback(callback)
|
|
{
|
|
|
|
}
|
|
|
|
virtual void Thunk(const ConnectionDescriptor& descriptor, const String& route, Message* msg) override
|
|
{
|
|
DT_UNUSED(route);
|
|
if (m_Callback)
|
|
{
|
|
T* casted = DynamicCast<T>(msg);
|
|
DT_ASSERT(casted);
|
|
m_Callback(descriptor, casted);
|
|
}
|
|
}
|
|
private:
|
|
Functor2<const ConnectionDescriptor&, T*> m_Callback;
|
|
};
|
|
|
|
template <class T> class MessageCallbackAdapterWithRoute : public MessageCallbackAdapterBase
|
|
{
|
|
public:
|
|
MessageCallbackAdapterWithRoute() {}
|
|
MessageCallbackAdapterWithRoute(const Functor3<const ConnectionDescriptor&, const String&, T*>& callback)
|
|
: m_Callback(callback)
|
|
{
|
|
|
|
}
|
|
|
|
virtual void Thunk(const ConnectionDescriptor& descriptor, const String& route, Message* msg) override
|
|
{
|
|
if (m_Callback)
|
|
{
|
|
T* casted = DynamicCast<T>(msg);
|
|
DT_ASSERT(casted);
|
|
m_Callback(descriptor, route, casted);
|
|
}
|
|
}
|
|
private:
|
|
Functor3<const ConnectionDescriptor&, const String&, T*> m_Callback;
|
|
};
|
|
|
|
class MessageFactory
|
|
{
|
|
public:
|
|
MessageFactory();
|
|
~MessageFactory();
|
|
|
|
typedef Message* (*CreateFunction)();
|
|
|
|
template <class T> void Register()
|
|
{
|
|
RegisterInternal(
|
|
T::GetExactTypeInfo()->GetName(),
|
|
T::Create,
|
|
nullptr,
|
|
0_s,
|
|
String::Blank());
|
|
}
|
|
|
|
template <class T> void Unregister()
|
|
{
|
|
UnregisterInternal(T::GetExactTypeInfo()->GetName());
|
|
}
|
|
|
|
template <class T, class U, class V> void Register(U* self,
|
|
V func,
|
|
Seconds cachePeriodInSec = 0_s,
|
|
const String& defaultRole = GetRoleDefault())
|
|
{
|
|
RegisterInternal(
|
|
T::GetExactTypeInfo()->GetName(),
|
|
T::Create,
|
|
DT_NEW(MessageCallbackAdapter<T>)(Functor2<const ConnectionDescriptor&, T*>::Bind(func, self)),
|
|
cachePeriodInSec,
|
|
defaultRole);
|
|
}
|
|
|
|
template <class T, class U, class V> void RegisterWithRoute(U* self,
|
|
V func,
|
|
Seconds cachePeriodInSec = 0_s,
|
|
const String& defaultRole = GetRoleDefault())
|
|
{
|
|
RegisterInternal(
|
|
T::GetExactTypeInfo()->GetName(),
|
|
T::Create,
|
|
DT_NEW(MessageCallbackAdapterWithRoute<T>)(Functor3<const ConnectionDescriptor&, const String&, T*>::Bind(func, self)),
|
|
cachePeriodInSec,
|
|
defaultRole);
|
|
}
|
|
|
|
template <class T, class U, class V> void RegisterAs(U* self,
|
|
V func,
|
|
const String& alias,
|
|
Seconds cachePeriodInSec = 0_s,
|
|
const String& defaultRole = GetRoleDefault())
|
|
{
|
|
RegisterInternal(
|
|
alias,
|
|
T::Create,
|
|
DT_NEW(MessageCallbackAdapter<T>)(Functor2<const ConnectionDescriptor&, T*>::Bind(func, self)),
|
|
cachePeriodInSec,
|
|
defaultRole);
|
|
}
|
|
|
|
bool IsKnown(const String& msgType) const;
|
|
|
|
Message* Create(const String& msgType) const;
|
|
|
|
Seconds GetCachePeriodInSec(const String& msgType) const;
|
|
|
|
const String& GetRole(const String& msgType) const;
|
|
|
|
static const String& GetRoleGuest();
|
|
|
|
static const String& GetRoleReader();
|
|
|
|
static const String& GetRoleAdmin();
|
|
|
|
static const String& GetRoleInvalid();
|
|
|
|
static String GetRoleDefault();
|
|
static void SetRoleDefaultGetterFunction(const Functor0R<String>& getter);
|
|
|
|
bool Callback(const ConnectionDescriptor& descriptor, const String& route, Message* msg);
|
|
|
|
private:
|
|
void RegisterInternal(const String& typeName,
|
|
CreateFunction createFunc,
|
|
MessageCallbackAdapterBase* callback,
|
|
Seconds cachePeriodInSec,
|
|
const String& defaultRole);
|
|
void UnregisterInternal(const String& typeName);
|
|
|
|
|
|
MessageFactoryImpl* m_Impl;
|
|
};
|
|
|
|
}
|
|
|