mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
1142 lines
52 KiB
C++
1142 lines
52 KiB
C++
|
|
#pragma once
|
|
|
|
#include "reflection/type.h"
|
|
#include "reflection/member.h"
|
|
#include "security/SecurityContext.h"
|
|
#include "util/standardout.h"
|
|
#include "boost/any.hpp"
|
|
#include "boost/cast.hpp"
|
|
#include "boost/bind.hpp"
|
|
#include "boost/static_assert.hpp"
|
|
#include "boost/shared_ptr.hpp"
|
|
#include <algorithm>
|
|
|
|
#include "rbx/Countable.h"
|
|
#include "rbx/signal.h"
|
|
#include "reflection/type.h"
|
|
|
|
namespace RBX
|
|
{
|
|
class SystemAddress;
|
|
|
|
namespace Reflection
|
|
{
|
|
/*
|
|
TODO: Review all this code
|
|
|
|
This is an event system inspired by boost's signal library.
|
|
|
|
It allows clients to connect slots to a signal both in a typed way, but also
|
|
using a generic argument list. This makes it possible to interface the signals
|
|
with Lua and other runtime interfaces
|
|
|
|
|
|
*/
|
|
typedef std::vector< Variant > EventArguments;
|
|
|
|
|
|
template<class GenericSlot> class TGenericSlotWrapper;
|
|
|
|
// A GenericSlot is a slot that takes "EventArguments" instead of typed function arguments
|
|
// Thus, it can slot to any signal.
|
|
// This wrapper defines an interface to such a slot
|
|
class RBXInterface GenericSlotWrapper
|
|
: boost::noncopyable
|
|
, public RBX::Diagnostics::Countable< GenericSlotWrapper >
|
|
{
|
|
// TODO: make members private/protected as much as possible
|
|
public:
|
|
virtual ~GenericSlotWrapper() {}
|
|
virtual void execute(const EventArguments& arguments) = 0;
|
|
template<class Arg1>
|
|
void execute1(const Arg1& arg1)
|
|
{
|
|
EventArguments args(1);
|
|
args[0] = arg1;
|
|
execute(args);
|
|
}
|
|
template<class Arg1, class Arg2>
|
|
void execute2(const Arg1& arg1, const Arg2& arg2)
|
|
{
|
|
EventArguments args(2);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
execute(args);
|
|
}
|
|
template<class Arg1, class Arg2, class Arg3>
|
|
void execute3(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)
|
|
{
|
|
EventArguments args(3);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
execute(args);
|
|
}
|
|
|
|
template<class Arg1, class Arg2, class Arg3, class Arg4>
|
|
void execute4(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
|
|
{
|
|
EventArguments args(4);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
execute(args);
|
|
}
|
|
|
|
template<class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
|
|
void execute5(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
|
|
{
|
|
EventArguments args(5);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
execute(args);
|
|
}
|
|
|
|
template<class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
|
|
void execute6(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6)
|
|
{
|
|
EventArguments args(6);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
args[5] = arg6;
|
|
execute(args);
|
|
}
|
|
|
|
template<class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
|
|
void execute7(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6, const Arg7& arg7)
|
|
{
|
|
EventArguments args(7);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
args[5] = arg6;
|
|
args[6] = arg7;
|
|
execute(args);
|
|
}
|
|
template<class GenericSlot>
|
|
static shared_ptr<GenericSlotWrapper> create(GenericSlot slot)
|
|
{
|
|
return shared_ptr<GenericSlotWrapper>(new TGenericSlotWrapper<GenericSlot>(slot));
|
|
}
|
|
};
|
|
|
|
template<class GenericSlot>
|
|
class TGenericSlotWrapper
|
|
: public GenericSlotWrapper
|
|
, public RBX::Diagnostics::Countable< TGenericSlotWrapper<GenericSlot> >
|
|
{
|
|
friend class GenericSlotWrapper;
|
|
public:
|
|
TGenericSlotWrapper(const GenericSlot& slot)
|
|
:slot(slot)
|
|
{
|
|
}
|
|
GenericSlot slot;
|
|
virtual void execute(const EventArguments& arguments)
|
|
{
|
|
try
|
|
{
|
|
slot(arguments);
|
|
}
|
|
catch(RBX::base_exception& e)
|
|
{
|
|
RBX::StandardOut::singleton()->printf(RBX::MESSAGE_ERROR, "Exception caught in TGenericSlotWrapper. %s", e.what());
|
|
}
|
|
}
|
|
};
|
|
|
|
//Forward declare EventDescriptor
|
|
class EventDescriptor;
|
|
// The base class of any object that fires Events
|
|
class EventSource
|
|
{
|
|
public:
|
|
virtual ~EventSource() {}
|
|
|
|
// This is used for processing of remote events
|
|
virtual void processRemoteEvent(const EventDescriptor& descriptor, const EventArguments& args, const SystemAddress& source);
|
|
|
|
// This is used to replicate events:
|
|
virtual void raiseEventInvocation(const EventDescriptor& descriptor, const EventArguments& args, const SystemAddress* target = NULL);
|
|
|
|
// If the event source can exist between multiple data models then we need to use submit task
|
|
// when running lua subscribers to ensure the right data model is locked.
|
|
virtual bool useSubmitTaskForLuaListeners() const { return false; }
|
|
};
|
|
|
|
/*
|
|
Describes a signal of a SignalSource/DescribedBase
|
|
*/
|
|
class Event;
|
|
class RBXBaseClass EventDescriptor : public MemberDescriptor
|
|
{
|
|
public:
|
|
typedef Event ConstMember;
|
|
typedef Event Member;
|
|
|
|
protected:
|
|
SignatureDescriptor signature;
|
|
EventDescriptor(ClassDescriptor& classDescriptor, const char* name, Security::Permissions security, Attributes attributes);
|
|
|
|
public:
|
|
virtual rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const = 0;
|
|
const SignatureDescriptor& getSignature() const { return signature; }
|
|
|
|
virtual bool isScriptable() const { return true; }
|
|
bool isPublic() const { return isScriptable(); }
|
|
|
|
virtual bool isBroadcast() const { return false; }
|
|
virtual void fireEvent(EventSource* source, const EventArguments& args) const = 0;
|
|
virtual void sendEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBXASSERT(false); // Should only be called on RemoteEventDesc
|
|
}
|
|
|
|
bool operator==(const EventDescriptor& other) const {
|
|
return this == &other;
|
|
}
|
|
bool operator!=(const EventDescriptor& other) const {
|
|
return this != &other;
|
|
}
|
|
virtual void disconnectAll(EventSource* source) const = 0;
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename EventGetter = SignalType EventClass::*>
|
|
class RBXBaseClass EventDescBase;
|
|
|
|
template<class EventClass, typename Signature, typename SignalType>
|
|
class RBXBaseClass EventDescBase<EventClass, Signature, SignalType, SignalType EventClass::*> : public EventDescriptor
|
|
{
|
|
private:
|
|
SignalType EventClass::*sig;
|
|
protected:
|
|
EventDescBase(SignalType EventClass::*sig, const char* name, Security::Permissions security, Attributes attributes)
|
|
:EventDescriptor(EventClass::classDescriptor(), name, security, attributes)
|
|
,sig(sig)
|
|
{}
|
|
|
|
SignalType& getSignal(EventClass* obj) const
|
|
{
|
|
return (obj->*sig);
|
|
}
|
|
public:
|
|
inline rbx::signals::connection connect(EventSource* source, const boost::function<Signature>& slot) const
|
|
{
|
|
if (source)
|
|
{
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
return (e->*sig).connect(slot);
|
|
}
|
|
else
|
|
return rbx::signals::connection(); // return an empty connection
|
|
}
|
|
|
|
inline void disconnectAll(EventSource* source) const
|
|
{
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
(e->*sig).disconnectAll();
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType>
|
|
class RBXBaseClass EventDescBase<EventClass, Signature, SignalType, SignalType* (EventClass::*)(bool)> : public EventDescriptor
|
|
{
|
|
private:
|
|
SignalType* (EventClass::*getOrCreate)(bool);
|
|
protected:
|
|
EventDescBase(SignalType* (EventClass::*getOrCreate)(bool), const char* name, Security::Permissions security, Attributes attributes)
|
|
:EventDescriptor(EventClass::classDescriptor(), name, security, attributes)
|
|
,getOrCreate(getOrCreate)
|
|
{}
|
|
|
|
SignalType& getSignal(EventClass* obj) const
|
|
{
|
|
SignalType* s = (obj->*getOrCreate)(true);
|
|
RBXASSERT(s);
|
|
return *s;
|
|
}
|
|
public:
|
|
inline rbx::signals::connection connect(EventSource* source, const boost::function<Signature>& slot) const
|
|
{
|
|
if (source)
|
|
{
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
return getSignal(e).connect(slot);
|
|
}
|
|
else
|
|
return rbx::signals::connection(); // return an empty connection
|
|
}
|
|
|
|
inline void disconnectAll(EventSource* source) const
|
|
{
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
SignalType* s = (e->*getOrCreate)(false);
|
|
|
|
if (s)
|
|
s->disconnectAll();
|
|
}
|
|
};
|
|
|
|
template<int arity, class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl;
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<0, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const
|
|
{
|
|
EventArguments foo2;
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute, wrapper, foo2));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 0);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
return this->getSignal(e)();
|
|
}
|
|
void fireEvent(EventClass* instance) const
|
|
{
|
|
getSignal(instance)();
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<1, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute1<
|
|
typename boost::function_traits<Signature>::arg1_type>,
|
|
wrapper, _1));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 1);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1) const
|
|
{
|
|
this->getSignal(instance)(arg1);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<2, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute2<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type>,
|
|
wrapper, _1, _2));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 2);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<3, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute3<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type,
|
|
typename boost::function_traits<Signature>::arg3_type>,
|
|
wrapper, _1, _2, _3));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 3);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>(),
|
|
args[2].cast<typename boost::function_traits<Signature>::arg3_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2,arg3);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<4, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute4<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type,
|
|
typename boost::function_traits<Signature>::arg3_type,
|
|
typename boost::function_traits<Signature>::arg4_type>,
|
|
wrapper, _1, _2, _3, _4));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 4);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>(),
|
|
args[2].cast<typename boost::function_traits<Signature>::arg3_type>(),
|
|
args[3].cast<typename boost::function_traits<Signature>::arg4_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3, typename boost::function_traits<Signature>::arg4_type arg4) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2,arg3,arg4);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<5, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute5<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type,
|
|
typename boost::function_traits<Signature>::arg3_type,
|
|
typename boost::function_traits<Signature>::arg4_type,
|
|
typename boost::function_traits<Signature>::arg5_type>,
|
|
wrapper, _1, _2, _3, _4, _5));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 5);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>(),
|
|
args[2].cast<typename boost::function_traits<Signature>::arg3_type>(),
|
|
args[3].cast<typename boost::function_traits<Signature>::arg4_type>(),
|
|
args[4].cast<typename boost::function_traits<Signature>::arg5_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3, typename boost::function_traits<Signature>::arg4_type arg4, typename boost::function_traits<Signature>::arg5_type arg5) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2,arg3,arg4,arg5);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<6, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute6<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type,
|
|
typename boost::function_traits<Signature>::arg3_type,
|
|
typename boost::function_traits<Signature>::arg4_type,
|
|
typename boost::function_traits<Signature>::arg5_type,
|
|
typename boost::function_traits<Signature>::arg6_type>,
|
|
wrapper, _1, _2, _3, _4, _5, _6));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 6);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>(),
|
|
args[2].cast<typename boost::function_traits<Signature>::arg3_type>(),
|
|
args[3].cast<typename boost::function_traits<Signature>::arg4_type>(),
|
|
args[4].cast<typename boost::function_traits<Signature>::arg5_type>(),
|
|
args[5].cast<typename boost::function_traits<Signature>::arg6_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3, typename boost::function_traits<Signature>::arg4_type arg4, typename boost::function_traits<Signature>::arg5_type arg5, typename boost::function_traits<Signature>::arg6_type arg6) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2,arg3,arg4,arg5,arg6);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class EventDescImpl<7, EventClass, Signature, SignalType, SignalGetter> : public EventDescBase<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
EventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDescBase<EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
rbx::signals::connection connectGeneric(EventSource* source, shared_ptr<GenericSlotWrapper> wrapper) const {
|
|
return this->connect(source, boost::bind(&GenericSlotWrapper::execute7<
|
|
typename boost::function_traits<Signature>::arg1_type,
|
|
typename boost::function_traits<Signature>::arg2_type,
|
|
typename boost::function_traits<Signature>::arg3_type,
|
|
typename boost::function_traits<Signature>::arg4_type,
|
|
typename boost::function_traits<Signature>::arg5_type,
|
|
typename boost::function_traits<Signature>::arg6_type,
|
|
typename boost::function_traits<Signature>::arg7_type>,
|
|
wrapper, _1, _2, _3, _4, _5, _6, _7));
|
|
}
|
|
inline void fireEvent(EventSource* source, const EventArguments& args) const
|
|
{
|
|
RBX_SIGNALS_ASSERT(args.size() == 7);
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
this->getSignal(e)(
|
|
args[0].cast<typename boost::function_traits<Signature>::arg1_type>(),
|
|
args[1].cast<typename boost::function_traits<Signature>::arg2_type>(),
|
|
args[2].cast<typename boost::function_traits<Signature>::arg3_type>(),
|
|
args[3].cast<typename boost::function_traits<Signature>::arg4_type>(),
|
|
args[4].cast<typename boost::function_traits<Signature>::arg5_type>(),
|
|
args[5].cast<typename boost::function_traits<Signature>::arg6_type>(),
|
|
args[6].cast<typename boost::function_traits<Signature>::arg7_type>()
|
|
);
|
|
}
|
|
void fireEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3, typename boost::function_traits<Signature>::arg4_type arg4, typename boost::function_traits<Signature>::arg5_type arg5, typename boost::function_traits<Signature>::arg6_type arg6, typename boost::function_traits<Signature>::arg7_type arg7) const
|
|
{
|
|
this->getSignal(instance)(arg1,arg2,arg3,arg4,arg5,arg6,arg7);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
// This is the final class used for defining Events.
|
|
template<
|
|
class EventClass, // The class type that fires the event
|
|
typename Signature, // The signature of the event
|
|
typename SignalType = rbx::signal<Signature>, // Optional specialization of the signal type
|
|
typename SignalGetter = SignalType EventClass::* // Optional signal getter, raw member pointer by default
|
|
>
|
|
class EventDesc : public EventDescImpl<boost::function_traits<Signature>::arity, EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
public:
|
|
EventDesc(SignalGetter sig, const char* name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<0, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 0);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, Descriptor::Attributes attributes)
|
|
:EventDescImpl<0, EventClass, Signature, SignalType, SignalGetter>(sig, name, Security::None, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 0);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<1, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 1);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, Descriptor::Attributes attributes)
|
|
:EventDescImpl<1, EventClass, Signature, SignalType, SignalGetter>(sig, name, Security::None, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 1);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<2, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 2);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<3, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 3);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
SignatureDescriptor::Item arg3(&RBX::Name::declare(arg3name), &Type::singleton<typename boost::function_traits<Signature>::arg3_type>());
|
|
this->signature.arguments.push_back(arg3);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<4, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 4);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
SignatureDescriptor::Item arg3(&RBX::Name::declare(arg3name), &Type::singleton<typename boost::function_traits<Signature>::arg3_type>());
|
|
this->signature.arguments.push_back(arg3);
|
|
SignatureDescriptor::Item arg4(&RBX::Name::declare(arg4name), &Type::singleton<typename boost::function_traits<Signature>::arg4_type>());
|
|
this->signature.arguments.push_back(arg4);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<5, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 5);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
SignatureDescriptor::Item arg3(&RBX::Name::declare(arg3name), &Type::singleton<typename boost::function_traits<Signature>::arg3_type>());
|
|
this->signature.arguments.push_back(arg3);
|
|
SignatureDescriptor::Item arg4(&RBX::Name::declare(arg4name), &Type::singleton<typename boost::function_traits<Signature>::arg4_type>());
|
|
this->signature.arguments.push_back(arg4);
|
|
SignatureDescriptor::Item arg5(&RBX::Name::declare(arg5name), &Type::singleton<typename boost::function_traits<Signature>::arg5_type>());
|
|
this->signature.arguments.push_back(arg5);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<6, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 6);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
SignatureDescriptor::Item arg3(&RBX::Name::declare(arg3name), &Type::singleton<typename boost::function_traits<Signature>::arg3_type>());
|
|
this->signature.arguments.push_back(arg3);
|
|
SignatureDescriptor::Item arg4(&RBX::Name::declare(arg4name), &Type::singleton<typename boost::function_traits<Signature>::arg4_type>());
|
|
this->signature.arguments.push_back(arg4);
|
|
SignatureDescriptor::Item arg5(&RBX::Name::declare(arg5name), &Type::singleton<typename boost::function_traits<Signature>::arg5_type>());
|
|
this->signature.arguments.push_back(arg5);
|
|
SignatureDescriptor::Item arg6(&RBX::Name::declare(arg6name), &Type::singleton<typename boost::function_traits<Signature>::arg6_type>());
|
|
this->signature.arguments.push_back(arg6);
|
|
}
|
|
EventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, const char* arg7name, Security::Permissions security = Security::None, Descriptor::Attributes attributes = Descriptor::Attributes())
|
|
:EventDescImpl<7, EventClass, Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 7);
|
|
SignatureDescriptor::Item arg1(&RBX::Name::declare(arg1name), &Type::singleton<typename boost::function_traits<Signature>::arg1_type>());
|
|
this->signature.arguments.push_back(arg1);
|
|
SignatureDescriptor::Item arg2(&RBX::Name::declare(arg2name), &Type::singleton<typename boost::function_traits<Signature>::arg2_type>());
|
|
this->signature.arguments.push_back(arg2);
|
|
SignatureDescriptor::Item arg3(&RBX::Name::declare(arg3name), &Type::singleton<typename boost::function_traits<Signature>::arg3_type>());
|
|
this->signature.arguments.push_back(arg3);
|
|
SignatureDescriptor::Item arg4(&RBX::Name::declare(arg4name), &Type::singleton<typename boost::function_traits<Signature>::arg4_type>());
|
|
this->signature.arguments.push_back(arg4);
|
|
SignatureDescriptor::Item arg5(&RBX::Name::declare(arg5name), &Type::singleton<typename boost::function_traits<Signature>::arg5_type>());
|
|
this->signature.arguments.push_back(arg5);
|
|
SignatureDescriptor::Item arg6(&RBX::Name::declare(arg6name), &Type::singleton<typename boost::function_traits<Signature>::arg6_type>());
|
|
this->signature.arguments.push_back(arg6);
|
|
SignatureDescriptor::Item arg7(&RBX::Name::declare(arg7name), &Type::singleton<typename boost::function_traits<Signature>::arg7_type>());
|
|
this->signature.arguments.push_back(arg7);
|
|
}
|
|
};
|
|
|
|
// A light-weight convenience class that associates a EventDescriptor
|
|
// with a described object to create a "Event"
|
|
class Event
|
|
{
|
|
protected:
|
|
const EventDescriptor* descriptor;
|
|
shared_ptr<EventSource> instance;
|
|
|
|
public:
|
|
inline Event(const EventDescriptor& descriptor, const shared_ptr<EventSource>& instance)
|
|
:descriptor(&descriptor),instance(instance)
|
|
{}
|
|
|
|
inline Event(const Event& other)
|
|
:descriptor(other.descriptor),instance(other.instance)
|
|
{}
|
|
inline Event& operator =(const Event& other)
|
|
{
|
|
this->descriptor = other.descriptor;
|
|
this->instance = other.instance;
|
|
return *this;
|
|
}
|
|
|
|
inline const RBX::Name& getName() const {
|
|
return descriptor->name;
|
|
}
|
|
|
|
inline const EventDescriptor* getDescriptor() const {
|
|
return descriptor;
|
|
}
|
|
inline shared_ptr<EventSource> getInstance() const
|
|
{
|
|
return instance;
|
|
}
|
|
|
|
bool operator==(const Event& other) const {
|
|
return this->descriptor == other.descriptor && this->instance == other.instance;
|
|
}
|
|
bool operator!=(const Event& other) const {
|
|
return !operator==(other);
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
std::size_t hash_value(const Event& prop);
|
|
|
|
// class used to hold the arguments/EventDesc of an event
|
|
class EventInvocation
|
|
{
|
|
public:
|
|
const Event event;
|
|
EventArguments args;
|
|
|
|
EventInvocation(const Event& event, const EventArguments& args)
|
|
: event(event)
|
|
, args(args)
|
|
{}
|
|
EventInvocation(const Event& event)
|
|
: event(event)
|
|
, args()
|
|
{}
|
|
|
|
void fireEvent()
|
|
{
|
|
event.getDescriptor()->fireEvent(event.getInstance().get(), args);
|
|
}
|
|
|
|
void replicateEvent()
|
|
{
|
|
event.getDescriptor()->sendEvent(event.getInstance().get(), args);
|
|
}
|
|
|
|
bool operator==(const EventInvocation& other) const {
|
|
return this->event == other.event/* && this->args == other.args*/;
|
|
}
|
|
bool operator!=(const EventInvocation& other) const {
|
|
return this->event != other.event/* || this->args == other.args*/;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
template<int arity, class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl;
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<0,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalGetter sig, const char* name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
: EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance)
|
|
{
|
|
this->getSignal(instance)();
|
|
replicateEvent(instance);
|
|
}
|
|
void replicateEvent(EventSource* instance)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 0);
|
|
EventArguments args(0);
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<1,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalGetter sig, const char* name, const char* arg1name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1)
|
|
{
|
|
this->fireEvent(instance, arg1);
|
|
replicateEvent(instance, arg1);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance, typename boost::function_traits<Signature>::arg1_type arg1)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 1);
|
|
EventArguments args(1);
|
|
args[0] = arg1;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<2,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2);
|
|
replicateEvent(instance, arg1, arg2);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 2);
|
|
EventArguments args(2);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<3,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, arg3name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2,arg3);
|
|
replicateEvent(instance, arg1, arg2, arg3);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance, typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 3);
|
|
EventArguments args(3);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<4,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalType EventClass::*sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2,arg3,arg4);
|
|
replicateEvent(instance, arg1, arg2, arg3, arg4);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 4);
|
|
EventArguments args(4);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<5,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalType EventClass::*sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2,arg3,arg4,arg5);
|
|
replicateEvent(instance, arg1, arg2, arg3, arg4, arg5);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 5);
|
|
EventArguments args(5);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<6,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalType EventClass::*sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, arg6name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5,
|
|
typename boost::function_traits<Signature>::arg6_type arg6)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2,arg3,arg4,arg5,arg6);
|
|
replicateEvent(instance, arg1, arg2, arg3, arg4, arg5, arg6);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5,
|
|
typename boost::function_traits<Signature>::arg6_type arg6)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 6);
|
|
EventArguments args(6);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
args[5] = arg6;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
template<class EventClass, typename Signature, typename SignalType, typename SignalGetter>
|
|
class RemoteEventDescImpl<7,EventClass,Signature,SignalType,SignalGetter> : public EventDesc<EventClass, Signature, SignalType, SignalGetter>
|
|
{
|
|
protected:
|
|
RemoteEventDescImpl(SignalType EventClass::*sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, const char* arg7name, Security::Permissions security, Descriptor::Attributes attributes)
|
|
:EventDesc<EventClass,Signature, SignalType, SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, arg6name, arg7name, security, attributes)
|
|
{}
|
|
public:
|
|
void fireAndReplicateEvent(EventClass* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5,
|
|
typename boost::function_traits<Signature>::arg6_type arg6,
|
|
typename boost::function_traits<Signature>::arg7_type arg7)
|
|
{
|
|
this->fireEvent(instance, arg1,arg2,arg3,arg4,arg5,arg6,arg7);
|
|
replicateEvent(instance, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
|
}
|
|
|
|
void replicateEvent(EventSource* instance,
|
|
typename boost::function_traits<Signature>::arg1_type arg1,
|
|
typename boost::function_traits<Signature>::arg2_type arg2,
|
|
typename boost::function_traits<Signature>::arg3_type arg3,
|
|
typename boost::function_traits<Signature>::arg4_type arg4,
|
|
typename boost::function_traits<Signature>::arg5_type arg5,
|
|
typename boost::function_traits<Signature>::arg6_type arg6,
|
|
typename boost::function_traits<Signature>::arg7_type arg7)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 7);
|
|
EventArguments args(7);
|
|
args[0] = arg1;
|
|
args[1] = arg2;
|
|
args[2] = arg3;
|
|
args[3] = arg4;
|
|
args[4] = arg5;
|
|
args[5] = arg6;
|
|
args[6] = arg7;
|
|
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
|
|
|
|
class RemoteEventCommon
|
|
{
|
|
public:
|
|
typedef enum {
|
|
SCRIPTING = 1,
|
|
REPLICATE_ONLY = 0
|
|
} Functionality;
|
|
|
|
struct Attributes : public Descriptor::Attributes
|
|
{
|
|
Functionality flags;
|
|
|
|
Attributes(Functionality flags):flags(flags) {}
|
|
static Attributes deprecated(Functionality flags, const MemberDescriptor* preferred);
|
|
};
|
|
typedef enum {
|
|
CLIENT_SERVER = 0, // Used to communicate between clients and servers
|
|
BROADCAST = 1 // A full broadcasts, all clients will recieve the message
|
|
} Behavior;
|
|
};
|
|
|
|
template<
|
|
class EventClass, // The class type that fires the event
|
|
typename Signature, // The signature of the event
|
|
typename SignalType = rbx::remote_signal<Signature>, // Optional specialization of the signal type
|
|
typename SignalGetter = SignalType EventClass::* // Optional signal getter, raw member pointer by default
|
|
>
|
|
class RemoteEventDesc : public RemoteEventDescImpl<boost::function_traits<Signature>::arity, EventClass, Signature, SignalType, SignalGetter>
|
|
, public RemoteEventCommon
|
|
{
|
|
protected:
|
|
const RemoteEventCommon::Behavior behavior;
|
|
const RemoteEventCommon::Functionality flags;
|
|
public:
|
|
RemoteEventDesc(SignalGetter sig, const char* name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<0,EventClass,Signature,SignalType,SignalGetter>(sig, name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 0);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<1,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 1);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<2,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 2);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<3,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, arg3name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 3);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<4,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 4);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name ,const char* arg5name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<5,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 5);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<6,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, arg6name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 6);
|
|
}
|
|
RemoteEventDesc(SignalGetter sig, const char* name, const char* arg1name, const char* arg2name, const char* arg3name, const char* arg4name, const char* arg5name, const char* arg6name, const char* arg7name, Security::Permissions security, RemoteEventCommon::Attributes attributes, RemoteEventCommon::Behavior behavior)
|
|
:RemoteEventDescImpl<7,EventClass,Signature,SignalType,SignalGetter>(sig, name, arg1name, arg2name, arg3name, arg4name, arg5name, arg6name, arg7name, security, attributes)
|
|
,flags(attributes.flags)
|
|
,behavior(behavior)
|
|
{
|
|
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 7);
|
|
}
|
|
|
|
SignalType* getSignalPtr(EventSource* source)
|
|
{
|
|
if (source)
|
|
{
|
|
EventClass* e = boost::polymorphic_downcast<EventClass*>(source);
|
|
|
|
return &this->getSignal(e);
|
|
}
|
|
RBXASSERT(0);
|
|
return NULL;
|
|
}
|
|
|
|
/*override*/ bool isScriptable() const
|
|
{
|
|
return (flags & 1) != 0;
|
|
}
|
|
|
|
/*override*/ bool isBroadcast() const
|
|
{
|
|
return (behavior & 1) != 0;
|
|
}
|
|
|
|
/*override*/ void sendEvent(EventSource* instance, const EventArguments& args) const
|
|
{
|
|
instance->raiseEventInvocation(*this, args);
|
|
}
|
|
};
|
|
}
|
|
}
|