#pragma once #include "reflection/property.h" #include "reflection/object.h" #include "reflection/enumconverter.h" #include "reflection/Type.h" #include "rbx/make_shared.h" #include #include #include #if defined RBX_PLATFORM_IOS #define NULL_FUNCTION_PTR typeof(NULL) #else #define NULL_FUNCTION_PTR int #endif #define _PRISM_PYRAMID_ #ifdef RBX_RCC_SECURITY // data_seg = init rw // const_seg = init ro // bss_seg = rw #define REFLECTION_BEGIN() __pragma(data_seg(".lua")) __pragma(const_seg(".lua")) __pragma(bss_seg(".lua")) #define REFLECTION_END() __pragma(data_seg()) __pragma(const_seg()) __pragma(bss_seg()) #else #define REFLECTION_BEGIN() #define REFLECTION_END() #endif namespace RBX { namespace Reflection { // This class is designed to prevent clients of the library // from forgetting to initialize their class descriptors template class ClassRegistrar : boost::noncopyable { int x; ClassRegistrar(int i):x(i) { // This call registers the class descriptor // in the reflection database Class::classDescriptor(); } public: void dummy() { x++; } // The instantiation of this static member must be in a unit // that is initialized in the main thread before any objects // are created. Otherwise the reflection database // can change at runtime, which would be a disaster static ClassRegistrar registrar; }; // A CRTP class for implementing reflection. Must be a descendant of DescribedBase template< class Class, const char* const& sClassName, class BaseClass = DescribedBase, ClassDescriptor::Functionality functionality = Reflection::ClassDescriptor::PERSISTENT, Security::Permissions security = Security::None > class RBXBaseClass Described : public BaseClass { void forceRegistration() { // Force linking of ClassRegistrar, which will force clients // of this library to define ClassRegistrar::registrar in // their startup code. ClassRegistrar::registrar.dummy(); } public: static ClassDescriptor& classDescriptor() { static ClassDescriptor describedClassDescriptor(BaseClass::classDescriptor(), sClassName, functionality, security); return describedClassDescriptor; } inline Described() { this->descriptor = &classDescriptor(); forceRegistration(); } template inline Described(Arg0 arg0):BaseClass(arg0) { this->descriptor = &classDescriptor(); forceRegistration(); } template inline Described(Arg0 arg0, Arg1 arg1):BaseClass(arg0, arg1) { this->descriptor = &classDescriptor(); forceRegistration(); } template inline Described(Arg0 arg0, Arg1 arg1, Arg2 arg2):BaseClass(arg0, arg1, arg2) { this->descriptor = &classDescriptor(); forceRegistration(); } template inline Described(Arg0 arg0, Arg1 arg1, Arg2 arg2, Arg3 arg3):BaseClass(arg0, arg1, arg2, arg3) { this->descriptor = &classDescriptor(); forceRegistration(); } }; // Handy macro for registering a class #define RBX_REGISTER_CLASS(Class) template<> RBX::Reflection::ClassRegistrar RBX::Reflection::ClassRegistrar::registrar(0) // This CRTP class puts a property declaration all together. // It binds a PropertyDescriptor with getter/setter functions. template class PropDescriptor : public TypedPropertyDescriptor { template class GetSetImpl : public Reflection::TypedPropertyDescriptor::GetSet { Get get; Set set; public: GetSetImpl(Get get, Set set):get(get),set(set) {} /*implement*/ bool isReadOnly() const { return false; } /*implement*/ bool isWriteOnly() const { return false; } /*implement*/ V getValue(const DescribedBase* object) const { const Class* c = boost::polymorphic_downcast(object); return (c->*get)(); } /*implement*/ void setValue(DescribedBase* object, const V& value) const { Class* c = boost::polymorphic_downcast(object); (c->*set)(value); } }; template class GetImpl : public Reflection::TypedPropertyDescriptor::GetSet { Get get; public: GetImpl(Get get):get(get) {} /*implement*/ bool isReadOnly() const { return true; } /*implement*/ bool isWriteOnly() const { return false; } /*implement*/ V getValue(const DescribedBase* object) const { const Class* c = boost::polymorphic_downcast(object); return (c->*get)(); } /*implement*/ void setValue(DescribedBase* object, const V& value) const { throw std::runtime_error("can't set value"); } }; template class SetImpl : public Reflection::TypedPropertyDescriptor::GetSet { Set set; public: SetImpl(Set set):set(set) {} /*implement*/ bool isReadOnly() const { return false; } /*implement*/ bool isWriteOnly() const { return true; } /*implement*/ V getValue(const DescribedBase* object) const { throw std::runtime_error("can't get value"); } /*implement*/ void setValue(DescribedBase* object, const V& value) const { Class* c = boost::polymorphic_downcast(object); (c->*set)(value); } }; public: template PropDescriptor(const char* name, const char* category, Get get, Set set, PropertyDescriptor::Attributes flags = PropertyDescriptor::Attributes(), Security::Permissions security = Security::None) :TypedPropertyDescriptor(Class::classDescriptor(), name, category, getset(get, set), flags, security) { } template static std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet > getset(Get get, Set set) { return std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet >(new GetSetImpl(get, set)); } // Partial specialization for read-only case template static std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet > getset(Get get, NULL_FUNCTION_PTR set) { return std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet >(new GetImpl(get)); } // Partial specialization for write-only case template static std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet > getset(NULL_FUNCTION_PTR get, Set set) { return std::auto_ptr< typename Reflection::TypedPropertyDescriptor::GetSet >(new SetImpl(set)); } }; // This CRTP class puts an enum property declaration all together. // It binds a PropertyDescriptor with getter/setter functions. // TODO: Refactor: This duplicates code it TypedPropertyDescriptor template class EnumPropDescriptor : public EnumPropertyDescriptor { std::auto_ptr::GetSet> getset; const EnumDesc& enumDesc; public: template EnumPropDescriptor(const char* name, const char* category, Get get, Set set, PropertyDescriptor::Attributes flags = PropertyDescriptor::Attributes(), Security::Permissions security=Security::None) :EnumPropertyDescriptor(Class::classDescriptor(), EnumDesc::singleton(), name, category, flags, security) ,getset(PropDescriptor::template getset(get, set)) ,enumDesc(EnumDesc::singleton()) { this->checkFlags(); } virtual bool isReadOnly() const { return getset->isReadOnly(); } virtual bool isWriteOnly() const { return getset->isWriteOnly(); } /*implement*/ void getVariant(const DescribedBase* instance, Variant& value) const { value = getEnumValue(instance); } /*implement*/ void setVariant(DescribedBase* instance, const Variant& value) const { setEnumValue(instance, value.get()); } /*implement*/ void copyValue(const DescribedBase* source, DescribedBase* destination) const { setValue(destination, getValue(source)); } V getValue(const DescribedBase* object) const { return getset->getValue(object); } void setValue(DescribedBase* object, V value) const { getset->setValue(object, value); } /*implement*/ bool equalValues(const DescribedBase* a, const DescribedBase* b) const { return getValue(a) == getValue(b); } /*implement*/ const EnumDescriptor::Item* getEnumItem(const DescribedBase* instance) const { const EnumDescriptor::Item* result = enumDesc.convertToItem(getValue(instance)); return result; } /*implement*/ int getEnumValue(const DescribedBase* instance) const { return (int) getValue(instance); } /*implement*/ bool setEnumValue(DescribedBase* instance, int intValue) const { if (enumDesc.isValue(intValue)) { setValue(instance, (V) intValue); return true; } else return false; } virtual size_t getIndexValue(const DescribedBase* instance) const { return enumDesc.convertToIndex(getValue(instance)); } virtual bool setIndexValue(DescribedBase* instance, size_t index) const { V value; if (enumDesc.convertToValue(index, value)) { setValue(instance, value); return true; } else return false; } bool setIntValue(DescribedBase* instance, int intValue) const { V v; if (!enumDesc.mapIntValue(intValue, v)) return false; setValue(instance, v); return true; } // PropertyDescriptor implementation: virtual bool hasStringValue() const { return true; } virtual std::string getStringValue(const DescribedBase* instance) const { return enumDesc.convertToString(getValue(instance)); } virtual bool setStringValue(DescribedBase* instance, const std::string& text) const { V value; if (enumDesc.convertToValue(text.c_str(), value)) { setValue(instance, value); return true; } else return false; } // An alternate, more efficient version of setStringValue virtual bool setStringValue(DescribedBase* instance, const RBX::Name& name) const { V value; if (enumDesc.convertToValue(name, value)) { setValue(instance, value); return true; } else return false; } virtual void readValue(DescribedBase* instance, const XmlElement* element, RBX::IReferenceBinder& binder) const { if (!element->isXsiNil()) { int value; if (element->getValue(value)) { if (setIntValue(instance, value)) return; } if (element->isValueType()) { // Legacy code to handle files older than 10/29/05 // TODO: Opt: Remove this legacy code sometime? It slows text XML down a bit std::string sValue; if (element->getValue(sValue)) { V e; if (enumDesc.convertToValue(sValue.c_str(), e)) { setValue(instance, e); return; } if (sValue.size()==0) { if (setIndexValue(instance, 0)) return; } } } // TODO: throw error? RBXASSERT(false); } } virtual void writeValue(const DescribedBase* instance, XmlElement* element) const { element->setValue(static_cast(getValue(instance))); } }; // Helper class template class RefType : public Type { public: static const Type& singleton() { static RefType type("Object"); return type; } private: RefType(const char* name) :Type(name, "Ref", (T*)NULL) {} }; template class RefPropDescriptor : public RefPropertyDescriptor , public IIDREF { std::auto_ptr::GetSet> getset; public: template RefPropDescriptor(const char* name, const char* category, Get get, Set set, PropertyDescriptor::Attributes attributes = PropertyDescriptor::Attributes(), Security::Permissions security=Security::None) :RefPropertyDescriptor( Class::classDescriptor(), RefType::singleton(), name, category, attributes, security ) ,getset(PropDescriptor::template getset(get, set)) { this->checkFlags(); } virtual bool isReadOnly() const { return getset->isReadOnly(); } virtual bool isWriteOnly() const { return getset->isWriteOnly(); } /*implement*/ void getVariant(const DescribedBase* instance, Variant& value) const { shared_ptr ref = shared_from(getValue(instance)); value = ref; } /*implement*/ void setVariant(DescribedBase* instance, const Variant& value) const { shared_ptr ref = value.get >(); setRefValue(instance, ref.get()); } /*implement*/ void copyValue(const DescribedBase* source, DescribedBase* destination) const { setValue(destination, getValue(source)); } RefClass* getValue(const DescribedBase* object) const { return getset->getValue(object); } void setValue(DescribedBase* object, RefClass* value) const { getset->setValue(object, value); } /*implement*/ bool equalValues(const DescribedBase* a, const DescribedBase* b) const { return getValue(a) == getValue(b); } /*implement*/ DescribedBase* getRefValue(const DescribedBase* instance) const { return getValue(instance); } /*implement*/ void setRefValue(DescribedBase* instance, DescribedBase* value) const { // if value!=NULL then ensure it is the proper type. If value==NULL then it is OK RefClass* v = value!=NULL ? boost::polymorphic_cast(value) : NULL; setValue(instance, v); } /*implement*/ void setRefValueUnsafe(DescribedBase* instance, DescribedBase* value) const { setValue(instance, boost::polymorphic_downcast(value)); } void readValue(DescribedBase* instance, const XmlElement* element, IReferenceBinder& binder) const { binder.announceIDREF(element, instance, this); } void writeValue(const DescribedBase* instance, XmlElement* element) const { element->setValue(InstanceHandle(getValue(instance))); } /*implement*/ void assignIDREF(DescribedBase* propertyOwner, const InstanceHandle& handle) const { // We know (assume) that this is the right type. If not, then the file is corrupt! shared_ptr t = handle.getTarget(); RefClass* r = boost::polymorphic_downcast(t.get()); setValue(propertyOwner, r); } }; template class FuncDesc : public FunctionDescriptor { protected: FuncDesc(const char* name, Security::Permissions security, Attributes attributes) :FunctionDescriptor(Class::classDescriptor(), name, security, attributes) { } }; class ArgHelper { template static bool try_integral(FunctionDescriptor::Arguments& arguments, bool& arg) { return arguments.getBool(index, arg); } template static bool try_integral(FunctionDescriptor::Arguments& arguments, int& arg) { long a; if (!arguments.getLong(index, a)) return false; arg = (int) a; return true; } template static bool try_integral(FunctionDescriptor::Arguments& arguments, long& arg) { return arguments.getLong(index, arg); } template static inline bool try_integral(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_floating_point(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { double a; if (!arguments.getDouble(index, a)) return false; arg = a; return true; } template static inline bool try_floating_point(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_string(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getString(index, arg); } template static inline bool try_string(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_Vector3int16(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getVector3int16(index, arg); } template static inline bool try_Vector3int16(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_Region3int16(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getRegion3int16(index, arg); } template static inline bool try_Region3int16(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_Vector3(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getVector3(index, arg); } template static inline bool try_Vector3(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_Region3(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getRegion3(index, arg); } template static inline bool try_Region3(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_Rect(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { return arguments.getRect(index, arg); } template static inline bool try_Rect(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } template static bool try_object(FunctionDescriptor::Arguments& arguments, shared_ptr& arg, typename boost::enable_if< boost::is_base_of >::type* dummy = 0) { shared_ptr instance; if (!arguments.getObject(index, instance)) return false; arg = shared_static_cast(instance); return true; } template static inline bool try_object(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if > >::type* dummy = 0) { return false; } template static bool try_enum(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::enable_if >::type* dummy = 0) { int a; if (!arguments.getEnum(index, EnumDesc::singleton(), a)) return false; arg = (T) a; return true; } template static inline bool try_enum(FunctionDescriptor::Arguments& arguments, T& arg, typename boost::disable_if >::type* dummy = 0) { return false; } public: template static T getArg(FunctionDescriptor::Arguments& arguments, const scoped_ptr& defaultArg, typename boost::disable_if > >::type* dummy = 0) { // Use default if no argument exists if (arguments.size() >= index) { // Try using direct argument access // Good compilers will nicely no-opt all // but one of these calls: T arg; if (try_integral(arguments, arg)) return arg; if (try_floating_point(arguments, arg)) return arg; if (try_string(arguments, arg)) return arg; if (try_enum(arguments, arg)) return arg; if (try_object(arguments, arg)) return arg; if (try_Vector3int16(arguments, arg)) return arg; if (try_Region3int16(arguments, arg)) return arg; if (try_Vector3(arguments, arg)) return arg; if (try_Region3(arguments, arg)) return arg; if (try_Rect(arguments, arg)) return arg; // Fall back to Variant Variant v; // nil args return false, so we use the default // See http://lua-users.org/wiki/TrailingNilParameters if (arguments.getVariant(index, v)) return v.convert(); } if (defaultArg) return *defaultArg; else throw RBX::runtime_error("Argument %d missing or nil", index); } // Specialization for Tuple, which takes all arguments >= index template static T getArg(FunctionDescriptor::Arguments& arguments, const scoped_ptr& defaultArg, typename boost::enable_if > >::type* dummy = 0) { if (arguments.size() < index) return shared_ptr(); // no arguments. Return an null Tuple, which is shorthand for empty // Create a tuple that is the same size as the number of arguments in the stack shared_ptr tuple = rbx::make_shared(arguments.size() - index + 1); for (size_t i = 0; i < tuple->values.size(); ++i) { // Ignore the result. It might return false for nil args, but that is OK arguments.getVariant(index + i, tuple->values[i]); } // According to http://lua-users.org/wiki/TrailingNilParameters we might // want to strip trailing nils. return tuple; } }; template ::arity > class BoundFuncDesc; /////////////////// // 0 argument template class Call0Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue) { returnValue = (o->*function)(); } }; // Specialization for void return types: template class Call0Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue) { (o->*function)(); } }; // A simple version of FunctionDescriptor for member functions that take no arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef result_type (Class::*FunctionPtr)(); FunctionPtr function; void declareSignature() { this->signature.resultType = &Type::singleton(); } public: BoundFuncDesc(FunctionPtr function, const char* name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) { declareSignature(); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call0Helper::call(boost::polymorphic_downcast(instance),function, arguments.returnValue); } }; /////////////////// // 1 argument template class Call1Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1) { returnValue = (o->*function)(arg1); } }; // Specialization for void return types: template class Call1Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1) { (o->*function)(arg1); } }; // A simple version of FunctionDescriptor for member functions that take 1 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef result_type (Class::*FunctionPtr)(Arg1); FunctionPtr function; const boost::scoped_ptr default1; void declareSignature(const char* arg1Name, Variant arg1Default) { this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default1() { declareSignature(arg1Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call1Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1) ); } }; /////////////////// // 2 arguments template class Call2Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2) { returnValue = (o->*function)(arg1, arg2 ); } }; // Specialization for void return types: template class Call2Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2) { (o->*function)(arg1, arg2); } }; // A simple version of FunctionDescriptor for member functions that take 3 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call2Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2)); } }; /////////////////// // 3 arguments template class Call3Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { returnValue = (o->*function)(arg1, arg2, arg3 ); } }; // Specialization for void return types: template class Call3Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { (o->*function)(arg1, arg2, arg3); } }; // A simple version of FunctionDescriptor for member functions that take 3 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2, Arg3); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call3Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3)); } }; /////////////////// // 4 arguments template class Call4Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { returnValue = (o->*function)(arg1, arg2, arg3, arg4 ); } }; // Specialization for void return types: template class Call4Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { (o->*function)(arg1, arg2, arg3, arg4); } }; // A simple version of FunctionDescriptor for member functions that take 4 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2, Arg3, Arg4); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call4Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4)); } }; /////////////////// // 5 arguments template class Call5Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { returnValue = (o->*function)(arg1, arg2, arg3, arg4, arg5 ); } }; // Specialization for void return types: template class Call5Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) { (o->*function)(arg1, arg2, arg3, arg4, arg5); } }; // A simple version of FunctionDescriptor for member functions that take 5 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef typename boost::function_traits::arg5_type Arg5; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2, Arg3, Arg4, Arg5); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; const boost::scoped_ptr default5; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default, const char* arg5Name, Variant arg5Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); this->signature.addArgument(RBX::Name::declare(arg5Name), Type::singleton(), arg5Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4, arg5Name, default5); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, default5); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call5Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), ArgHelper::getArg(arguments, default5)); } }; /////////////////// // 6 arguments template class Call6Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6) { returnValue = (o->*function)(arg1, arg2, arg3, arg4, arg5, arg6); } }; // Specialization for void return types: template class Call6Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6) { (o->*function)(arg1, arg2, arg3, arg4, arg5, arg6); } }; // A simple version of FunctionDescriptor for member functions that take 5 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef typename boost::function_traits::arg5_type Arg5; typedef typename boost::function_traits::arg6_type Arg6; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; const boost::scoped_ptr default5; const boost::scoped_ptr default6; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default, const char* arg5Name, Variant arg5Default, const char* arg6Name, Variant arg6Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); this->signature.addArgument(RBX::Name::declare(arg5Name), Type::singleton(), arg5Default); this->signature.addArgument(RBX::Name::declare(arg6Name), Type::singleton(), arg6Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4, arg5Name, default5, arg6Name, default6); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, default5, arg6Name, default6); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, const char* arg6Name, Arg6 default6, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6(new Arg6(default6)) ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant(), arg6Name, default6); } BoundFuncDesc(FunctionPtr function, 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 = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default6() ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant(), arg6Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call6Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), ArgHelper::getArg(arguments, default5), ArgHelper::getArg(arguments, default6)); } }; /////////////////// // 7 arguments template class Call7Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6, const Arg7& arg7) { returnValue = (o->*function)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } }; // Specialization for void return types: template class Call7Helper { public: static void call(Class1* o, FunctionPtr1 function, Variant& returnValue, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5, const Arg6& arg6, const Arg7& arg7) { (o->*function)(arg1, arg2, arg3, arg4, arg5, arg6, arg7); } }; // A simple version of FunctionDescriptor for member functions that take 5 arguments template class BoundFuncDesc : public FuncDesc { typedef typename boost::function_traits::result_type result_type; typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef typename boost::function_traits::arg5_type Arg5; typedef typename boost::function_traits::arg6_type Arg6; typedef typename boost::function_traits::arg7_type Arg7; typedef result_type (Class::*FunctionPtr)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7); FunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; const boost::scoped_ptr default5; const boost::scoped_ptr default6; const boost::scoped_ptr default7; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default, const char* arg5Name, Variant arg5Default, const char* arg6Name, Variant arg6Default, const char* arg7Name, Variant arg7Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); this->signature.addArgument(RBX::Name::declare(arg5Name), Type::singleton(), arg5Default); this->signature.addArgument(RBX::Name::declare(arg6Name), Type::singleton(), arg6Default); this->signature.addArgument(RBX::Name::declare(arg7Name), Type::singleton(), arg7Default); } public: BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4, arg5Name, default5, arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4, arg5Name, default5, arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Arg5 default5, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5(new Arg5(default5)) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, default5, arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, const char* arg6Name, Arg6 default6, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7(new Arg7(default7)) ,default6(new Arg6(default6)) ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant(), arg6Name, default6, arg7Name, default7); } BoundFuncDesc(FunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, const char* arg6Name, const char* arg7Name, Arg7 default7, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,default7(new Arg7(default7)) ,default6() ,default5() ,default4() ,default3() ,default2() ,default1() ,function(function) { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant(), arg6Name, Variant(), arg7Name, default7); } BoundFuncDesc(FunctionPtr function, 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 = Descriptor::Attributes()) :FuncDesc(name, security, attributes) ,function(function) ,default7() ,default6() ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant(), arg6Name, Variant(), arg7Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments) const { Call7Helper::call(boost::polymorphic_downcast(instance), function, arguments.returnValue, ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), ArgHelper::getArg(arguments, default5), ArgHelper::getArg(arguments, default6), ArgHelper::getArg(arguments, default7)); } }; template class YieldFuncDesc : public YieldFunctionDescriptor { protected: YieldFuncDesc(const char* name, Security::Permissions security, Attributes attributes) :YieldFunctionDescriptor(Class::classDescriptor(), name, security, attributes) { } }; template static void resume_adapter(boost::function resumeFunction, ReturnType returnValue) { Variant value = returnValue; resumeFunction(value); } template ::result_type, int arity = boost::function_traits::arity > class BoundYieldFuncDesc; // ReturnType() specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef void (Class::*YieldFunctionPtr)(boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; void declareSignature() { this->signature.resultType = &Type::singleton(); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) { declareSignature(); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void() specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef void (Class::*YieldFunctionPtr)(boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; void declareSignature() { this->signature.resultType = &Type::singleton(); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) { declareSignature(); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( boost::bind(resumeFunction, Variant()), errorFunction); } }; // A simple version of FunctionDescriptor for member functions that take 1 arguments template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef void (Class::*YieldFunctionPtr)(Arg1, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; void declareSignature(const char* arg1Name, Variant arg1Default) { this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default1() { declareSignature(arg1Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void(Arg1) specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef void (Class::*YieldFunctionPtr)(Arg1, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; void declareSignature(const char* arg1Name, Variant arg1Default) { this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default1() { declareSignature(arg1Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), boost::bind(resumeFunction, Variant()), errorFunction); } }; // A simple version of FunctionDescriptor for member functions that take 2 arguments template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void(Arg1, Arg2) specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), boost::bind(resumeFunction, Variant()), errorFunction); } }; // A simple version of FunctionDescriptor for member functions that take 3 arguments template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void(Arg1, Arg2, Arg3) specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), boost::bind(resumeFunction, Variant()), errorFunction); } }; // A simple version of FunctionDescriptor for member functions that take 4 arguments template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, Arg4, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void(Arg1, Arg2, Arg3, Arg4) specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, Arg4, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), boost::bind(resumeFunction, Variant()), errorFunction); } }; // A simple version of FunctionDescriptor for member functions that take 4 arguments template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef typename boost::function_traits::arg5_type Arg5; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, Arg4, Arg5, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; const boost::scoped_ptr default5; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default, const char* arg5Name, Variant arg5Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); this->signature.addArgument(RBX::Name::declare(arg5Name), Type::singleton(), arg5Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), ArgHelper::getArg(arguments, default5), boost::bind(&resume_adapter, resumeFunction, _1), errorFunction); } }; // void(Arg1, Arg2, Arg3, Arg4, Arg5) specialization template class BoundYieldFuncDesc : public YieldFuncDesc { typedef typename boost::function_traits::arg1_type Arg1; typedef typename boost::function_traits::arg2_type Arg2; typedef typename boost::function_traits::arg3_type Arg3; typedef typename boost::function_traits::arg4_type Arg4; typedef typename boost::function_traits::arg5_type Arg5; typedef void (Class::*YieldFunctionPtr)(Arg1, Arg2, Arg3, Arg4, Arg5, boost::function resumeFunction, boost::function errorFunction); YieldFunctionPtr function; const boost::scoped_ptr default1; const boost::scoped_ptr default2; const boost::scoped_ptr default3; const boost::scoped_ptr default4; const boost::scoped_ptr default5; void declareSignature(const char* arg1Name, Variant arg1Default, const char* arg2Name, Variant arg2Default, const char* arg3Name, Variant arg3Default, const char* arg4Name, Variant arg4Default, const char* arg5Name, Variant arg5Default) { BOOST_STATIC_ASSERT((!boost::is_same >::value)); BOOST_STATIC_ASSERT((!boost::is_same >::value)); this->signature.resultType = &Type::singleton(); this->signature.addArgument(RBX::Name::declare(arg1Name), Type::singleton(), arg1Default); this->signature.addArgument(RBX::Name::declare(arg2Name), Type::singleton(), arg2Default); this->signature.addArgument(RBX::Name::declare(arg3Name), Type::singleton(), arg3Default); this->signature.addArgument(RBX::Name::declare(arg4Name), Type::singleton(), arg4Default); this->signature.addArgument(RBX::Name::declare(arg5Name), Type::singleton(), arg5Default); } public: BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, Arg1 default1, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1(new Arg1(default1)) { declareSignature(arg1Name, default1, arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Arg2 default2, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2(new Arg2(default2)) ,default1() { declareSignature(arg1Name, Variant(), arg2Name, default2, arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Arg3 default3, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg5 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3(new Arg3(default3)) ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, default3, arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Arg4 default4, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4(new Arg4(default4)) ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, default4, arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Arg4 default5, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5(new Arg5(default5)) ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, default5); } BoundYieldFuncDesc(YieldFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, const char* arg5Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) :YieldFuncDesc(name, security, attributes) ,function(function) ,default5() ,default4() ,default3() ,default2() ,default1() { declareSignature(arg1Name, Variant(), arg2Name, Variant(), arg3Name, Variant(), arg4Name, Variant(), arg5Name, Variant()); } /*implement*/ void execute(Reflection::DescribedBase* instance, FunctionDescriptor::Arguments& arguments, boost::function resumeFunction, boost::function errorFunction) const { (boost::polymorphic_downcast(instance)->*function)( ArgHelper::getArg(arguments, default1), ArgHelper::getArg(arguments, default2), ArgHelper::getArg(arguments, default3), ArgHelper::getArg(arguments, default4), ArgHelper::getArg(arguments, default5), boost::bind(resumeFunction, Variant()), errorFunction); } }; template ::arity > class CustomBoundFuncDesc; template class CustomBoundFuncDesc : public BoundFuncDesc { typedef int (Class::*CustomFunctionPtr)(lua_State*); CustomFunctionPtr customFunction; public: CustomBoundFuncDesc(CustomFunctionPtr function, const char* name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) : BoundFuncDesc(NULL, name, security, attributes) , customFunction(function) { this->kind = FunctionDescriptor::Kind_Custom; } /*implement*/ int executeCustom(DescribedBase* instance, lua_State* state) const { return (boost::polymorphic_downcast(instance)->*customFunction)(state); } }; template class CustomBoundFuncDesc : public BoundFuncDesc { typedef int (Class::*CustomFunctionPtr)(lua_State*); CustomFunctionPtr customFunction; public: CustomBoundFuncDesc(CustomFunctionPtr function, const char* name, const char* arg1Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) : BoundFuncDesc(NULL, name, arg1Name, security, attributes) , customFunction(function) { this->kind = FunctionDescriptor::Kind_Custom; } /*implement*/ int executeCustom(DescribedBase* instance, lua_State* state) const { return (boost::polymorphic_downcast(instance)->*customFunction)(state); } }; template class CustomBoundFuncDesc : public BoundFuncDesc { typedef int (Class::*CustomFunctionPtr)(lua_State*); CustomFunctionPtr customFunction; public: CustomBoundFuncDesc(CustomFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) : BoundFuncDesc(NULL, name, arg1Name, arg2Name, security, attributes) , customFunction(function) { this->kind = FunctionDescriptor::Kind_Custom; } /*implement*/ int executeCustom(DescribedBase* instance, lua_State* state) const { return (boost::polymorphic_downcast(instance)->*customFunction)(state); } }; template class CustomBoundFuncDesc : public BoundFuncDesc { typedef int (Class::*CustomFunctionPtr)(lua_State*); CustomFunctionPtr customFunction; public: CustomBoundFuncDesc(CustomFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) : BoundFuncDesc(NULL, name, arg1Name, arg2Name, arg3Name, security, attributes) , customFunction(function) { this->kind = FunctionDescriptor::Kind_Custom; } /*implement*/ int executeCustom(DescribedBase* instance, lua_State* state) const { return (boost::polymorphic_downcast(instance)->*customFunction)(state); } }; template class CustomBoundFuncDesc : public BoundFuncDesc { typedef int (Class::*CustomFunctionPtr)(lua_State*); CustomFunctionPtr customFunction; public: CustomBoundFuncDesc(CustomFunctionPtr function, const char* name, const char* arg1Name, const char* arg2Name, const char* arg3Name, const char* arg4Name, Security::Permissions security, Descriptor::Attributes attributes = Descriptor::Attributes()) : BoundFuncDesc(NULL, name, arg1Name, arg2Name, arg3Name, arg4Name, security, attributes) , customFunction(function) { this->kind = FunctionDescriptor::Kind_Custom; } /*implement*/ int executeCustom(DescribedBase* instance, lua_State* state) const { return (boost::polymorphic_downcast(instance)->*customFunction)(state); } }; } }