You are on page 1of 6

/*-----------------------------------------------------------------------------Filename: MetaFunction.

hpp Author : Jeffrey Morgan Purpose : Date : 2012/06/18 All content (C) 2012 DigiPen (USA) Corporation, all rights reserved. ------------------------------------------------------------------------------*/ #pragma once #include #include #include #include "Meta.hpp" "Variant.hpp" "FunctionSignature.hpp" "MetaFunctionWrapper.hpp"

namespace SqueakyClean { class MetaFunction { typedef void (*FreeFuncWrapper)( void ); public: MetaFunction() : m_name( "unbound" ) , m_wrapper( nullptr ) , m_sig( FunctionSignature() ) , m_size( 0 ) {} //Free Function overloads // No args template <typename Ret> MetaFunction( cstr name, Ret (*fn)( void ), MetaPrivate::WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( 4 ) , m_freeFn( (FreeFuncWrapper)fn ) {} // 1 args template <typename Ret, typename Arg1> MetaFunction( cstr name, Ret (*fn)( Arg1 ), MetaPrivate::WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( 4 ) , m_freeFn( (FreeFuncWrapper)fn ) {} // 2 args template <typename Ret, typename Arg1, typename Arg2> MetaFunction( cstr name, Ret (*fn)( Arg1, Arg2 ), MetaPrivate::WrapperFunc wra pper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( 4 ) , m_freeFn( (FreeFuncWrapper)fn ) {} // 3 args template <typename Ret, typename Arg1, typename Arg2, typename Arg3>

MetaFunction( cstr name, Ret (*fn)( Arg1, Arg2, Arg3 ), MetaPrivate::WrapperFu nc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( 4 ) , m_freeFn( (FreeFuncWrapper)fn ) {} // Member Function overloads // No args // non-const template<typename Ret, class C> MetaFunction( cstr name, Ret (C::*fn)( void ), MetaPrivate::WrapperFunc wrappe r ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // const template<typename Ret, class C> MetaFunction( cstr name, Ret (C::*fn)( void ) const, MetaPrivate::WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // 1 args // non-const template<typename Ret, class C, typename Arg1> MetaFunction( cstr name, Ret (C::*fn)( Arg1 ), MetaPrivate::WrapperFunc wrappe r ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // const template<typename Ret, class C, typename Arg1> MetaFunction( cstr name, Ret (C::*fn)( Arg1 ) const, MetaPrivate::WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // 2 args // non-const template<typename Ret, class C, typename Arg1, typename Arg2> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2 ), MetaPrivate::WrapperFunc wrapper ) : m_name( name )

, , , ,

m_wrapper( wrapper ) m_sig( FunctionSignature( fn ) ) m_size( sizeof( wrapper ) ) m_freeFn( nullptr )

{} // const template<typename Ret, class C, typename Arg1, typename Arg2> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2 ) const, MetaPrivate::Wrappe rFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // 3 args // non-const template<typename Ret, class C, typename Arg1, typename Arg2, typename Arg3> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2, Arg3 ), MetaPrivate::Wrappe rFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // const template<typename Ret, class C, typename Arg1, typename Arg2, typename Arg3> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2, Arg3 ) const, MetaPrivate:: WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // 3 args // non-const template<typename Ret, class C, typename Arg1, typename Arg2, typename Arg3, t ypename Arg4> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2, Arg3, Arg4 ), MetaPrivate:: WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {} // const template<typename Ret, class C, typename Arg1, typename Arg2, typename Arg3, t ypename Arg4> MetaFunction( cstr name, Ret (C::*fn)( Arg1, Arg2, Arg3, Arg4 ) const, MetaPri vate::WrapperFunc wrapper ) : m_name( name ) , m_wrapper( wrapper ) , m_sig( FunctionSignature( fn ) ) , m_size( sizeof( wrapper ) ) , m_freeFn( nullptr ) {}

Variant Invoke( MemPtr obj, VariantRef *args, u32 argc ) const { if ( !obj && m_freeFn ) obj = (MemPtr)m_freeFn; return m_wrapper( obj, args, argc ); } cstr const GetName() const { return m_name; } const MemPtr GetWrapper() const { return m_wrapper; } FunctionSignature GetSignature() const { return m_sig; } u32 GetSize() const { return m_size; } public: TODO( "Jeff, Test Free func support. --Jeff" ); TODO( "Jeff, change function to store pointers like MemFuncs do. --Jeff" ); // Free func wrappers // 0 args versions // ret version template <typename Ret> static Variant InvokeFreeFunc( MemPtr fn, VariantRef *, u32 ) { return ((Ret(*)())fn)(); } template <typename Ret> static MetaPrivate::WrapperFunc Make( Ret ( *fn )( void ) ) { return &InvokeFreeFunc<Ret>; } // no ret version static Variant InvokeFreeFuncNoRet( MemPtr fn, VariantRef *, u32 ) { ((void(*)())fn)(); return Variant(); } static MetaPrivate::WrapperFunc Make( void ( *fn )( void ) ) { return &InvokeFreeFuncNoRet; } // 1 args // ret version template <typename Ret, typename Arg1> static Variant InvokeFreeFunc( MemPtr fn, VariantRef *args, u32 ) { return ((Ret(*)( Arg1 ))fn)( args[0].Convert<Arg1>() ); } template <typename Ret, typename Arg1> static MetaPrivate::WrapperFunc Make( Ret ( *fn )( Arg1 ) ) { return &InvokeFreeFunc<Ret, Arg1>; } // no ret version template <typename Arg1> static Variant InvokeFreeFuncNoRet( MemPtr fn, VariantRef *args, u32 ) { return ((void(*)( Arg1 ))fn)( args[0].Convert<arg1>() ); } template <typename Arg1> static MetaPrivate::WrapperFunc Make( void ( *fn )( Arg1 ) ) { return &InvokeFreeFuncNoRet<Arg1>; } // 2 args // ret version template <typename Ret, typename Arg1, typename Arg2> static Variant InvokeFreeFunc( MemPtr fn, VariantRef *args, u32 ) { Arg1 a1 = args[0].Convert<Arg1>(); Arg2 a2 = args[1].Convert<Arg2>(); return ((Ret(*)( Arg1, Arg2 ))fn)( a1, a2 ); } template <typename Ret, typename Arg1, typename Arg2>

static MetaPrivate::WrapperFunc Make( Ret ( *fn )( Arg1, Arg2 ) ) { return &InvokeFreeFunc<Ret, Arg1, Arg2>; } // no ret version template <typename Arg1, typename Arg2> static Variant InvokeFreeFuncNoRet( MemPtr fn, VariantRef *args, u32 ) { Arg1 a1 = args[0].Convert<Arg1>(); Arg2 a2 = args[1].Convert<Arg2>(); ((void(*)( Arg1, Arg2 ))fn)( a1, a2 ) return Variant(); } template <typename Arg1, typename Arg2> static MetaPrivate::WrapperFunc Make( void ( *fn )( Arg1, Arg2 ) ) { return &InvokeFreeFuncNoRet<Arg1, Arg2>; } // 3 args // ret version template <typename Ret, typename Arg1, typename Arg2, typename Arg3> static Variant InvokeFreeFunc( MemPtr fn, VariantRef *args, u32 ) { Arg1 a1 = args[0].Convert<Arg1>(); Arg2 a2 = args[1].Convert<Arg2>(); Arg3 a3 = args[2].Convert<Arg3>(); return ((Ret(*)( Arg1, Arg2, Arg3 ))fn)( a1, a2, a3 ); } template <typename Ret, typename Arg1, typename Arg2, typename Arg3> static MetaPrivate::WrapperFunc Make( Ret ( *fn )( Arg1, Arg2, Arg3 ) ) { return &InvokeFreeFunc<Ret, Arg1, Arg2, Arg3>; } // no ret version template <typename Arg1, typename Arg2, typename Arg3> static Variant InvokeFreeFuncNoRet( MemPtr fn, VariantRef *args, u32 ) { Arg1 a1 = args[0].Convert<Arg1>(); Arg2 a2 = args[1].Convert<Arg2>(); Arg3 a3 = args[2].Convert<Arg3>(); ((void(*)( Arg1, Arg2, Arg3 ))fn)( a1, a2, a3 ) return Variant(); } template <typename Arg1, typename Arg2, typename Arg3> static MetaPrivate::WrapperFunc Make( void ( *fn )( Arg1, Arg2, Arg3 ) ) { return &InvokeFreeFuncNoRet<Arg1, Arg2, Arg3>; } private: cstr m_name; FunctionSignature m_sig; MetaPrivate::WrapperFunc m_wrapper; u32 m_size; FreeFuncWrapper m_freeFn; }; // class to store separate invocation of MetaFunction from creation of it. // stores the obj instance of the caller. class MetaDelegate { public: MetaDelegate( VariantRef inst, const MetaFunction &func ) : m_func( func ) , m_inst( inst ) {} ~MetaDelegate() {}

Variant Invoke( MemPtr *, VariantRef *args, u32 argc ) const { return m_func.Invoke( m_inst.GetData(), args, argc ); } MetaFunction VariantRef private: MetaFunction VariantRef }; GetFunction( void ) const { return m_func; } GetInstance( void ) const { return m_inst; } m_func; m_inst; //stores the function to call //stores the function caller

#define INTERNAL_GENERATE_MEMBER_FN( CType, func ) \ MemberFuncWrapper< sizeof( void(CType::*)(void) )>::Make<reinterpret_cast<Ge nericMemFuncTyper<sizeof( void(CType::*)(void ) )>::MemPtrSizeType>( &CType::fun c )>( &CType::func ) #define MAKE_META_MEM_FUNCTION( class, func ) \ MetaFunction( #func, &class::func, INTERNAL_GENERATE_MEMBER_FN( class, func ) ) #define MAKE_META_FREE_FUNCTION( func ) \ MetaFunction( #func, func, MetaFunction::Make( func ) ) } //namespace SqueakyClean

You might also like