diff --git a/Engine/source/core/stream/ioHelper.h b/Engine/source/core/stream/ioHelper.h index 1255356d0..ed006aff6 100644 --- a/Engine/source/core/stream/ioHelper.h +++ b/Engine/source/core/stream/ioHelper.h @@ -31,6 +31,18 @@ /// template expansion. namespace IOHelper { + template + inline bool reads(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k,L& l,M& m) + { s->read(&a); s->read(&b); s->read(&c); s->read(&d); s->read(&e); s->read(&f); s->read(&g); s->read(&h); s->read(&i); s->read(&j); s->read(&k); s->read(&l); return s->read(&m); } + + template + inline bool reads(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k,L& l) + { s->read(&a); s->read(&b); s->read(&c); s->read(&d); s->read(&e); s->read(&f); s->read(&g); s->read(&h); s->read(&i); s->read(&j); s->read(&k); return s->read(&l); } + + template + inline bool reads(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k) + { s->read(&a); s->read(&b); s->read(&c); s->read(&d); s->read(&e); s->read(&f); s->read(&g); s->read(&h); s->read(&i); s->read(&j); return s->read(&k); } + template inline bool reads(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j) { s->read(&a); s->read(&b); s->read(&c); s->read(&d); s->read(&e); s->read(&f); s->read(&g); s->read(&h); s->read(&i); return s->read(&j); } @@ -71,6 +83,18 @@ namespace IOHelper inline bool reads(Stream *s,A& a) { return s->read(&a); } + template + inline bool writes(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k,L& l,M& m) + { s->write(a); s->write(b); s->write(c); s->write(d); s->write(e); s->write(f); s->write(g); s->write(h); s->write(i); s->write(j); s->write(k); s->write(l); return s->write(m); } + + template + inline bool writes(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k,L& l) + { s->write(a); s->write(b); s->write(c); s->write(d); s->write(e); s->write(f); s->write(g); s->write(h); s->write(i); s->write(j); s->write(k); return s->write(l); } + + template + inline bool writes(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j,K& k) + { s->write(a); s->write(b); s->write(c); s->write(d); s->write(e); s->write(f); s->write(g); s->write(h); s->write(i); s->write(j); return s->write(k); } + template inline bool writes(Stream *s,A& a,B& b,C& c,D& d,E& e,F& f,G& g,H& h,I& i,J& j) { s->write(a); s->write(b); s->write(c); s->write(d); s->write(e); s->write(f); s->write(g); s->write(h); s->write(i); return s->write(j); } diff --git a/Engine/source/core/util/FastDelegate.h b/Engine/source/core/util/FastDelegate.h index 4ac73c6cb..b977a6a12 100644 --- a/Engine/source/core/util/FastDelegate.h +++ b/Engine/source/core/util/FastDelegate.h @@ -1613,6 +1613,261 @@ private: // Invoker for static functions return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8); } }; +//N=11 +template +class FastDelegate11 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate11 type; + + // Construction and comparison functions + FastDelegate11() { clear(); } + FastDelegate11(const FastDelegate11 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate11 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate11 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate11 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate11 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate11 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate11(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate11(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate11(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8), Param9 p9, Param10 p10, Param11 p11) { + m_Closure.bindstaticfunc(this, &FastDelegate11::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } +}; + +//N=12 +template +class FastDelegate12 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate12 type; + + // Construction and comparison functions + FastDelegate12() { clear(); } + FastDelegate12(const FastDelegate12 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate12 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate12 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate12 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate12 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate12 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate12(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate12(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate12(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8), Param9 p9, Param10 p10, Param11 p11, Param12 p12) { + m_Closure.bindstaticfunc(this, &FastDelegate12::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,p12); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } +}; + +//N=13 +template +class FastDelegate13 { +private: + typedef typename detail::DefaultVoidToVoid::type DesiredRetType; + typedef DesiredRetType (*StaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); + typedef RetType (*UnvoidStaticFunctionPtr)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); + typedef RetType (detail::GenericClass::*GenericMemFn)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13); + typedef detail::ClosurePtr ClosureType; + ClosureType m_Closure; +public: + // Typedefs to aid generic programming + typedef FastDelegate13 type; + + // Construction and comparison functions + FastDelegate13() { clear(); } + FastDelegate13(const FastDelegate13 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + void operator = (const FastDelegate13 &x) { + m_Closure.CopyFrom(this, x.m_Closure); } + bool operator ==(const FastDelegate13 &x) const { + return m_Closure.IsEqual(x.m_Closure); } + bool operator !=(const FastDelegate13 &x) const { + return !m_Closure.IsEqual(x.m_Closure); } + bool operator <(const FastDelegate13 &x) const { + return m_Closure.IsLess(x.m_Closure); } + bool operator >(const FastDelegate13 &x) const { + return x.m_Closure.IsLess(m_Closure); } + // Binding to non-const member functions + template < class X, class Y > + FastDelegate13(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { + m_Closure.bindmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Binding to const member functions. + template < class X, class Y > + FastDelegate13(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + template < class X, class Y > + inline void bind(const Y *pthis, DesiredRetType (X::* function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { + m_Closure.bindconstmemfunc(detail::implicit_cast(pthis), function_to_bind); } + // Static functions. We convert them into a member function call. + // This constructor also provides implicit conversion + FastDelegate13(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { + bind(function_to_bind); } + // for efficiency, prevent creation of a temporary + void operator = (DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) ) { + bind(function_to_bind); } + inline void bind(DesiredRetType (*function_to_bind)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8), Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) { + m_Closure.bindstaticfunc(this, &FastDelegate13::InvokeStaticFunction, + function_to_bind); } + // Invoke the delegate + RetType operator() (Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { + return (m_Closure.GetClosureThis()->*(m_Closure.GetClosureMemPtr()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,p12,p13); } + // Implicit conversion to "bool" using the safe_bool idiom +private: + typedef struct SafeBoolStruct { + int a_data_pointer_to_this_is_0_on_buggy_compilers; + StaticFunctionPtr m_nonzero; + } UselessTypedef; + typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type; +public: + operator unspecified_bool_type() const { + return empty()? 0: &SafeBoolStruct::m_nonzero; + } + // necessary to allow ==0 to work despite the safe_bool idiom + inline bool operator==(StaticFunctionPtr funcptr) { + return m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator!=(StaticFunctionPtr funcptr) { + return !m_Closure.IsEqualToStaticFuncPtr(funcptr); } + inline bool operator ! () const { // Is it bound to anything? + return !m_Closure; } + inline bool empty() const { + return !m_Closure; } + void clear() { m_Closure.clear();} + // Conversion to and from the DelegateMemento storage class + const DelegateMemento & GetMemento() { return m_Closure; } + void SetMemento(const DelegateMemento &any) { m_Closure.CopyFrom(this, any); } + +private: // Invoker for static functions + RetType InvokeStaticFunction(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const { + return (*(m_Closure.GetStaticFunction()))(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } +}; + //////////////////////////////////////////////////////////////////////////////// // Fast Delegates, part 4: @@ -1965,6 +2220,117 @@ public: *static_cast(this) = x; } }; +//N=11 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > +// instead of +// FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11 ) > + // Inherit from FastDelegate11 so that it can be treated just like a FastDelegate11 + : public FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate11 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=12 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > +// instead of +// FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12 ) > + // Inherit from FastDelegate12 so that it can be treated just like a FastDelegate12 + : public FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate12 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + +//N=13 +// Specialization to allow use of +// FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > +// instead of +// FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > +template +class FastDelegate< R ( Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13 ) > + // Inherit from FastDelegate13 so that it can be treated just like a FastDelegate13 + : public FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > +{ +public: + // Make using the base type a bit easier via typedef. + typedef FastDelegate13 < Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, R > BaseType; + + // Allow users access to the specific type of this delegate. + typedef FastDelegate SelfType; + + // Mimic the base class constructors. + FastDelegate() : BaseType() { } + + template < class X, class Y > + FastDelegate(Y * pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) + : BaseType(pthis, function_to_bind) { } + + template < class X, class Y > + FastDelegate(const Y *pthis, + R (X::* function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 ) const) + : BaseType(pthis, function_to_bind) + { } + + FastDelegate(R (*function_to_bind)( Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13 )) + : BaseType(function_to_bind) { } + void operator = (const BaseType &x) { + *static_cast(this) = x; } +}; + #endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX @@ -2097,6 +2463,39 @@ FastDelegate8(x, func); } +//N=11 +template +FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11)) { + return FastDelegate11(x, func); +} + +template +FastDelegate11 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11) const) { + return FastDelegate11(x, func); +} + +//N=12 +template +FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12)) { + return FastDelegate12(x, func); +} + +template +FastDelegate12 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12) const) { + return FastDelegate12(x, func); +} + +//N=13 +template +FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13)) { + return FastDelegate13(x, func); +} + +template +FastDelegate13 MakeDelegate(Y* x, RetType (X::*func)(Param1 p1, Param2 p2, Param3 p3, Param4 p4, Param5 p5, Param6 p6, Param7 p7, Param8 p8, Param9 p9, Param10 p10, Param11 p11, Param12 p12, Param13 p13) const) { + return FastDelegate13(x, func); +} + // clean up after ourselves... #undef FASTDLGT_RETTYPE diff --git a/Engine/source/core/util/journal/journal.h b/Engine/source/core/util/journal/journal.h index aefebcd23..9db84e2f6 100644 --- a/Engine/source/core/util/journal/journal.h +++ b/Engine/source/core/util/journal/journal.h @@ -73,6 +73,33 @@ class Journal void dispatch() { (*ptr)(); } }; + template + struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K,L,M) >: public Functor { + typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K,L,M); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; M m; + FunctorDecl(FuncPtr p): ptr(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l,m); } + void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k,l,m); } + }; + + template + struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K,L) >: public Functor { + typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K,L); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; + FunctorDecl(FuncPtr p): ptr(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l); } + void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k,l); } + }; + + template + struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J,K) >: public Functor { + typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J,K); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; + FunctorDecl(FuncPtr p): ptr(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k); } + void dispatch() { (*ptr)(a,b,c,d,e,f,g,h,i,j,k); } + }; + template struct FunctorDecl< void(*)(A,B,C,D,E,F,G,H,I,J) >: public Functor { typedef void(*FuncPtr)(A,B,C,D,E,F,G,H,I,J); @@ -174,6 +201,36 @@ class Journal void dispatch() { (obj->*method)(); } }; + template + struct MethodDecl: public Functor { + typedef T* ObjPtr; + typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K,L,M); + ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; M m; + MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l,m); } + void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k,l,m); } + }; + + template + struct MethodDecl: public Functor { + typedef T* ObjPtr; + typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K,L); + ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; L l; + MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k,l); } + void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k,l); } + }; + + template + struct MethodDecl: public Functor { + typedef T* ObjPtr; + typedef void(T::*MethodPtr)(A,B,C,D,E,F,G,H,I,J,K); + ObjPtr obj; MethodPtr method; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; K k; + MethodDecl(ObjPtr o,MethodPtr p): obj(o), method(p) {} + void read(Stream *file) { IOHelper::reads(file,a,b,c,d,e,f,g,h,i,j,k); } + void dispatch() { (obj->*method)(a,b,c,d,e,f,g,h,i,j,k); } + }; + template struct MethodDecl: public Functor { typedef T* ObjPtr; @@ -445,6 +502,12 @@ public: return value; \ } + template + Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k, L l, M m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) + template + Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k, L l),(a,b,c,d,e,f,g,h,i,j,k,l)) + template + Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j, K k),(a,b,c,d,e,f,g,h,i,j,k)) template Method(Func,(Func func,A a,B b,C c,D d,E e,F f, G g, H h, I i, J j),(a,b,c,d,e,f,g,h,i,j)) template @@ -493,6 +556,12 @@ public: return; \ } + template + Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l,m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) + template + Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l),(a,b,c,d,e,f,g,h,i,j,k,l)) + template + Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k),(mFile,id,a,b,c,d,e,f,g,h,i,j,k),(a,b,c,d,e,f,g,h,i,j,k)) template Method((Func func,A a,B b,C c,D d,E e,F f,G g,H h,I i,J j),(mFile,id,a,b,c,d,e,f,g,h,i,j),(a,b,c,d,e,f,g,h,i,j)) template @@ -537,6 +606,12 @@ public: } + template + Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K,L,M),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l,M m),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l,m),(a,b,c,d,e,f,g,h,i,j,k,l,m)) + template + Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K,L),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k,L l),(mFile,id,a,b,c,d,e,f,g,h,i,j,k,l),(a,b,c,d,e,f,g,h,i,j,k,l)) + template + Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J,K),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j,K k),(mFile,id,a,b,c,d,e,f,g,h,i,j,k),(a,b,c,d,e,f,g,h,i,j,k)) template Method((Obj* obj,void (Obj::*method)(A,B,C,D,E,F,G,H,I,J),A a,B b,C c,D d,E e,F f,G g,H h,I i,J j),(mFile,id,a,b,c,d,e,f,g,h,i,j),(a,b,c,d,e,f,g,h,i,j)) template @@ -574,6 +649,12 @@ public: return false; \ } + template + Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k,L& l,M& m),(mFile,a,b,c,d,e,f,g,h,i,j,k,l,m)); + template + Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k,L& l),(mFile,a,b,c,d,e,f,g,h,i,j,k,l)); + template + Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j,K& k),(mFile,a,b,c,d,e,f,g,h,i,j,k)); template Method((A& a,B& b,C& c,D& d,E& e, F& f, G& g, H& h, I& i,J& j),(mFile,a,b,c,d,e,f,g,h,i,j)); template @@ -608,6 +689,12 @@ public: return false; \ } + template + Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k, L& l, M& m),(mFile,a,b,c,d,e,f,g,h,i,j,k,l,m)); + template + Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k, L& l),(mFile,a,b,c,d,e,f,g,h,i,j,k,l)); + template + Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j, K& k),(mFile,a,b,c,d,e,f,g,h,i,j,k)); template Method((A& a,B& b,C& c,D& d,E& e,F& f,G& g, H& h, I& i, J& j),(mFile,a,b,c,d,e,f,g,h,i,j)); template diff --git a/Engine/source/core/util/journal/journaledSignal.h b/Engine/source/core/util/journal/journaledSignal.h index 99843fcf5..8c0057937 100644 --- a/Engine/source/core/util/journal/journaledSignal.h +++ b/Engine/source/core/util/journal/journaledSignal.h @@ -243,6 +243,75 @@ public: } }; +/// @copydoc JournaledSignal +template +class JournaledSignal : public Signal +{ + typedef Signal Parent; + +public: + JournaledSignal() + { + Journal::DeclareFunction((Parent*)this, &Parent::trigger); + } + + ~JournaledSignal() + { + Journal::RemoveFunction((Parent*)this, &Parent::trigger); + } + + void trigger(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) + { + Journal::Call((Parent*)this, &Parent::trigger, a, b, c, d, e, f, g, h, i, j, k); + } +}; + +/// @copydoc JournaledSignal +template +class JournaledSignal : public Signal +{ + typedef Signal Parent; + +public: + JournaledSignal() + { + Journal::DeclareFunction((Parent*)this, &Parent::trigger); + } + + ~JournaledSignal() + { + Journal::RemoveFunction((Parent*)this, &Parent::trigger); + } + + void trigger(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) + { + Journal::Call((Parent*)this, &Parent::trigger, a, b, c, d, e, f, g, h, i, j, k, l); + } +}; + +/// @copydoc JournaledSignal +template +class JournaledSignal : public Signal +{ + typedef Signal Parent; + +public: + JournaledSignal() + { + Journal::DeclareFunction((Parent*)this, &Parent::trigger); + } + + ~JournaledSignal() + { + Journal::RemoveFunction((Parent*)this, &Parent::trigger); + } + + void trigger(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m) + { + Journal::Call((Parent*)this, &Parent::trigger, a, b, c, d, e, f, g, h, i, j, k, l, m); + } +}; + //----------------------------------------------------------------------------- // Common event callbacks definitions diff --git a/Engine/source/core/util/tSignal.h b/Engine/source/core/util/tSignal.h index 1fbbb0758..ea2e67954 100644 --- a/Engine/source/core/util/tSignal.h +++ b/Engine/source/core/util/tSignal.h @@ -463,6 +463,75 @@ class Signal : public SignalBaseT +class Signal : public SignalBaseT +{ + public: + + bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k ) ) + { + this->mTriggerNext.pop_back(); + return false; + } + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + return true; + } +}; + +template +class Signal : public SignalBaseT +{ + public: + + bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l ) ) + { + this->mTriggerNext.pop_back(); + return false; + } + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + return true; + } +}; + +template +class Signal : public SignalBaseT +{ + public: + + bool trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + if( !this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l, m ) ) + { + this->mTriggerNext.pop_back(); + return false; + } + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + return true; + } +}; + // Non short-circuit signal implementations template<> @@ -663,4 +732,58 @@ class Signal : public SignalBaseT +class Signal : public SignalBaseT +{ + public: + + void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k ); + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + } +}; + +template +class Signal : public SignalBaseT +{ + public: + + void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l ); + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + } +}; + +template +class Signal : public SignalBaseT +{ + public: + + void trigger( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l, M m ) + { + this->mTriggerNext.push_back(NULL); + for( SignalBase::DelegateLink* ptr = this->mList.next; ptr != &this->mList; ) + { + this->mTriggerNext.last() = ptr->next; + this->getDelegate( ptr )( a, b, c, d, e, f, g, h, i, j, k, l, m ); + ptr = this->mTriggerNext.last(); + } + this->mTriggerNext.pop_back(); + } +}; + #endif // _TSIGNAL_H_