Function Binding Special thanks to: John Edwards Randy Gaul
Introspection Generic Variable Function Binding Simple Case Uses Demo Overview Function Binding
Introspection Run-time knows little about types Introspection saves compile-time data Generic code
Introspection Questions we can Answer What methods does this class have What members are in this struct What type of data is this Can I convert type A to type B How can I send this type to script How can I send this type to a file How can I create this type from file What sort of messaging can I achieve
Introspection Register your Data We want tables of data Type Name - "int" Size - 4 bytes Members - none Methods - none Inherits from - none
Introspection Register your Data Store data in a struct struct TypeInfo { const char *name; int size; TypeInfo *inheritsfrom; Method *methods; Members *members; };
Introspection Register your Data Use a macro to register info into your tables void RegisterSomeData( void ) { REGISTER_TYPE( int ); REGISTER_TYPE( SomeStruct ); REGISTER_MEMBER( SomeStruct, x ); }
Magic Macros! Introspection Register your Data #define REGISTER_TYPE( T ) \ Introspection::Get( )->RegisterType<T>( sizeof( T ), #T )
Introspection Register your Data Introspection singleton struct IntrospectionManager { static IntrospectionManager *Get( void ) { static IntrospectionManager instance; return &instance; } template <typename T> TypeInfo *RegisterType( int size, char *name ) { static TypeInfo instance; TypeInfo *typeinfo = &instance; m_typemap.add( name, typeinfo ); return typeinfo; } private: HashTable<const char *, TypeInfo *> m_typemap; };
Introspection Retrieve Data Retrieve data from Singleton Make single Get for a type Wrap this in a GET_TYPE( T ) macro template <typename T> const TypeInfo *IntrospectionManager::GetType( void ) const { static TypeInfo instance; return &instance; }
Introspection The Macros Might want something like these #define REGISTER( T ) #define TYPE( T ) #define TYPE_OF( OBJECT ) #define TYPE_OF_MEMBER( T, MEMBER ) #define STR_TYPE( STR ) #define ADD_MEMBER( T, MEMBER ) #define SET_SERIALIZER( T, SERIALIZER ) #define SET_DESERIALIZER( T, DESERIALIZER )
Variable Generic Variable needed for generic code We want to do this: Variable v; int x = 5; v = x; v.tolua( ); // Send 5 to Lua v.serialize( file ); // write 5 in a file // Valid SomeStruct s; v = s;
TypeInfo * Void * Variable
Variable GetValue template <typename T> T& Variable::GetValue( void ) { return *((T *)m_data )); }
Function Binding Lets create generic Function Lets pass it Variables as arguments
Function Binding Step 1: Lets create generic Function Store function pointer as template type template <typename FunctionType, FunctionType FunctionPtr> Function BuildFunction( void (*fn)( void ) ) { return Function; // Not finished! }
Function Binding Function needs function pointer template type Pass address of Call Helper template <typename FunctionType, FunctionType FunctionPtr> Function BuildFunction( void (*fn)( void ) ) { return Function( &Call<FunctionType, FunctionPtr> ); }
Function Binding Call helper calls the real function pointer template <typename FunctionType, FunctionType FunctionPtr> void Call( Variable *ret, Variable *args, unsigned argcount ) { assert( argcount == 0 ); } (*FunctionPtr)( );
Can now call void (*)( void ) Function Binding Function f = BuildFunction<decltype( &Func ), &Func>( &Func ); f( ); // calls Func
What about arguments? Make some overloads Function Binding template <typename FunctionType, FunctionType FunctionPtr, typename Arg1> Function BuildFunction( void (*fn)( Arg1 ) ) { return Function( &Call<FunctionType, FunctionPtr, Arg1> ); } template <typename FunctionType, FunctionType FunctionPtr, typename Arg1> void Call( Variable *ret, Variable *args, unsigned argcount ) { assert( argcount == 0 ); } (*FunctionPtr)( args[0].getvalue<arg1>( ) );
What about more arguments? Make some more overloads Function Binding
What about non-void return? Function Binding
What about non-void return? MAKE SOME MORE OVERLOADS Function Binding
Function Binding My final function binding: 1783 lines in header Screenshot is about 1/10 th of file
Properties!! Function for Get/Set methods Function Binding - Uses
Function Binding - Uses Visual scripting Attach and pass around Function objects
Bind functions to call from script Function Binding - Uses REGISTER_FUNCTION( glbegin ); REGISTER_FUNCTION( glend ); // in script glbegin( blah );... // Render a beautiful scene glend( );
Messaging omg Function Binding - Uses void Object::SendMessage( Variable v1 ); void Object::SendMessage( Variable v1, Variable v2 ); void Object::SendMessage( Variable v1, Variable v2, Variable v3 );
Function Binding - Uses Listeners Messaging even better super omg void Object::Subscribe( Function& f ); void Object::PostMSG( MSG_ID id ); void Object::PostMSG( MSG_ID id, Variable v1 ); void Object::PostMSG( MSG_ID id, Variable v1, Variable v2 );
And more..? Function Binding - Uses
Demo
Questions?
Resources Template Metaprogramming John Edwards My website Sean middleditche s website Engine Arch online files (Sean made some demos)