This is a compiler that will generate most of the binding code from a bit of markup and additional build configuration. Statistically, the gain is approximately 80% less code to write to connect your C++ code to SGScript.
The compiler can be found at "ext/cppbc/cppbc.sgs". It takes one argument (which should be the header file to process) and it generates one file with the name "cppbc_"+header_file, thus it can be called like this: "sgsvm -p path/to/cppbc.sgs path/to/my_cpp_header.h".
This is a basic example of how things are done with SGS/CPP-BC:
struct UIFrame { typedef sgsHandle< UIFrame > Handle; SGS_OBJECT; UIFrame(); SGS_METHOD void event( UIEvent* e ); SGS_METHOD void render(); SGS_METHOD void doMouseMove( float x, float y ); SGS_METHOD void doMouseButton( int btn, bool down ); SGS_METHOD void doKeyPress( int key, bool down ); SGS_IFUNC(GCMARK) int sgs_gcmark( SGS_CTX, sgs_VarObj* obj, int ); SGS_PROPERTY float x; SGS_PROPERTY float y; SGS_PROPERTY float width; SGS_PROPERTY float height; SGS_PROPERTY sgsHandle< UIControl > root; float prevMouseX; float prevMouseY; };
The SGS_OBJECT tag marks the structs/classes that need to have the binding code. SGS_METHOD would then mark methods that require exporting and SGS_PROPERTY generates property exports. For read-only/write-only properties, all you'd need to add is "READ" or "WRITE" after the tag.
sgsVariable and sgsHandle are classes that are used to store SGScript objects. Handles are for storing exported object pointers and variables are for everything. Handles make it easier to use the included objects, thus they are preferred to plain variable containers.
GCMARK handlers are more like the raw API but all that needs to be done in the function is calling gcmark() on each variable or handle. Due to the possibility of having many unknown kinds of containers of variables, it is unlikely that this function could ever be automatically generated, except for the most primitive of cases.
SGS_PROPERTY float x;
SGS_PROPERTY SGS_ALIAS( float x );
SGS_PROPERTY_FUNC( READ WRITE WRITE_CALLBACK myWriteCallback ) float x;
SGS_PROPERTY_FUNC( READ getX WRITE setX ) SGS_ALIAS( float x );
SGS_PROPERTY_FUNC( READ WRITE VARNAME sgsName ) float x;
SGS_PROPERTY_FUNC( READ WRITE VARNAME sgsName ) SGS_ALIAS( float x );
SGS_METHOD float calc( float x );
SGS_METHOD SGS_MULTRET complexFunc();
typedef sgsHandle< struct sgsObj > sgsObjHandle; struct sgsObj { SGS_OBJECT; static sgsObjHandle HandleFromPtr( Obj* ); // resolve the link through object's user data pointer or some similar method sgsObj( Obj* obj ) : m_obj( obj ){} ~sgsObj(){ cleanup(); } void cleanup() // this is pulled out of constructor in case it might be called by a parent object to invalidate the handle on destruction of the owning system { if( m_obj ) { // *** free m_obj *** m_obj = NULL; } } Obj* m_obj; // declare additional properties and methods with SGS_PROPERTY(_FUNC) and SGS_METHOD, respectively // most properties/methods will most likely have to include a NULL test for m_obj, like this: int _getProp(){ return m_obj ? m_obj->GetProp() : 0; } void _setProp( int v ){ if( m_obj ) m_obj->SetProp( v ); } SGS_PROPERTY_FUNC( READ _getProp WRITE _setProp ) SGS_ALIAS( int prop ); };
struct sgsData : Data { SGS_OBJECT_LITE; sgsData(){} sgsData( const Data& t ) : Data( t ){} // properties with direct access (non-private) SGS_PROPERTY SGS_ALIAS( item1 ); // data struct properties (original type: SubData, wrapped type: sgsSubData) sgsSubData _getSubData(){ return subData; } void _setSubData( const sgsSubData& sd ){ subData = sd; } SGS_PROPERTY_FUNC( READ _getSubData WRITE _setSubData ) SGS_ALIAS( sgsSubData subData ); // properties with method access int _getProp(){ return GetProp(); } void _setProp( int v ){ SetProp( v ); } SGS_PROPERTY_FUNC( READ _getProp WRITE _setProp ) SGS_ALIAS( int prop ); // aliases (second names) for all properties: SGS_PROPERTY_FUNC( READ WRITE VARNAME item1alt ) SGS_ALIAS( item1 ); SGS_PROPERTY_FUNC( READ _getSubData WRITE _setSubData VARNAME subDataAlt ) SGS_ALIAS( sgsSubData subData ); SGS_PROPERTY_FUNC( READ _getProp WRITE _setProp VARNAME propAlt ) SGS_ALIAS( int prop ); }; SGS_DEFAULT_LITE_OBJECT_INTERFACE( sgsData ); // this line can be replaced with a modified combo of sgs_PushVar/sgs_GetVar/sgs_GetVarP declarations
Marks the objects/structures for parsing.
SGS_OBJECT_LITE does not add helper variables (sgs_VarObj* m_sgsObject; sgs_Context* C) to the class
Marks the methods that should be made available to the scripting engine.
Syntax: SGS_METHOD <type> <name>(<arguments>);
Alt. syntax (bind without declaration): SGS_METHOD SGS_ALIAS( <type> <name>(<arguments>) );
Marks the properties that should be made available to the scripting engine. Currently supports only one property at a time.
Syntax: SGS_PROPERTY [READ|WRITE] <type> <name>;
Alt. syntax (bind without declaration): SGS_PROPERTY [READ|WRITE] SGS_ALIAS( <type> <name> );
Modifiers:
Marks the properties that should be made available to the scripting engine. Has additional options for reading, writing and callbacks.
Syntax: SGS_PROPERTY_FUNC( <tag-args> ) <type> <name>;
Alt. syntax (bind without declaration): SGS_PROPERTY_FUNC( <tag-args> ) SGS_ALIAS( <type> <name> );
Tag arguments: a space separated list of none or more of the following constructs
Marks the method as a native object interface function that would override any generated one.
Syntax: SGS_IFUNC( <ifunc-type> ) <type> <name>( sgs_Context*, sgs_VarObj*, int );
"ifunc-type" must be one of SGS_OP_* defines.
sgs_VarObj* object
- the pointer to object with interface equal to T::_sgs_interface or NULL
SGS_CTX
(sgs_Context* C
) - associated contextsgsHandle()
- initializes a NULL handle
sgsHandle( const sgsHandle& h )
- initializes a handle from another handle
sgsHandle( sgs_VarObj* obj, sgs_Context* c )
- initializes a handle from object pointer if it has the right interface, otherwise handle is initialized to NULLSGSRESULT gcmark()
- mark the object in handle as accessible (using sgs_ObjGCMark)
void _acquire()
- increment reference count on variable
void _release()
- decrement reference count on variable, remove it from the classconst sgsHandle& operator = ( const sgsHandle& h )
- handle assignment
operator T*()
, operator const T*() const
- implicit conversion to valid T* or NULL
T* operator -> ()
, const T* operator -> () const
- object access
bool operator <
, bool operator ==
- comparison operators (the required minimum used for sorting)sgs_Variable var
- the internal variable data
SGS_CTX
(sgs_Context* C
) - associated contextsgsVariable()
- initializes a NULL variable
sgsVariable( const sgsVariable& h )
- initializes variable from another variable
sgsVariable( sgs_Context* c )
- initialize a NULL variable and associate context
sgsVariable( sgs_Context* c, int item )
- initialize a variable from current stack frame
sgsVariable( sgs_Context* c, sgs_Variable* v )
- initialize a variable from data pointervoid push( sgs_Context* c = NULL )
- push the variable (optionally specify context if variable might not have it)
SGSRESULT gcmark()
- mark the variable as accessible (using sgs_GCMark)
bool not_null()
- return if variable is not NULL
bool is_object( sgs_ObjInterface* iface )
- check if variable is an object with the specified interface
template< class T > bool is_handle()
- check if variable is an instance of the specified SGS_OBJECT class
template< class T > T* get_object_data()
- get object pointer from variable (WARNING: this method does not do any safety checks)
void _acquire()
- increment reference count on variable
void _release()
- decrement reference count on variable, remove it from the classconst sgsVariable& operator = ( const sgsVariable& h )
- handle assignment
bool operator <
, bool operator ==
- comparison operators (the required minimum used for sorting)This function should not be used with existing instances, as it would make two or more SGScript objects responsible for the same data. Use sgs_PushVar, sgs_PushHandle or sgs_Push(Lite)ClassFrom with existing instances.
This function should not be used with existing instances, as it would make two or more SGScript objects responsible for the same data. Use sgs_PushVar, sgs_PushHandle or sgs_Push(Lite)ClassFrom with existing instances.
inst
Usage example:
SGS_PUSHCLASS( C, myClass, ( param1, 5.0f ) );