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".
Arguments:
-o
- specify output file (default = <input_path>/cppbc_<input_name>.cpp)
-i
- specify include file (to be parsed before the source file)
-add-timestamp
- add current date/time to headerThis 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 sgsString name; 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_PROPERTY_FUNC( READ WRITE VALIDATE parent SOURCE parent->name ) SGS_ALIAS( sgsString parentName );
SGS_METHOD float calc( float x );
SGS_METHOD_NAMED( func ) void sgsFunc( int i );
// ctx is passed automatically, does not affect argument count/order SGS_METHOD void coroAware( sgs_Context* coroCtx, float arg0 ); // SGS_CTX works too, but may trigger a warning about variable shadowing
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( bool 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 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
SGS_OBJECT_INHERIT specifies class or classes to inherit definitions from
Object binding modifiers.
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>) );
sgs_Context*
arguments are not counted in the SGScript argument listMarks the renamed methods that should be made available to the scripting engine.
Syntax: SGS_METHOD_NAMED( <sgsname> ) <type> <realname>(<arguments>)
See SGS_METHOD for more info.
Marks the static methods that should be made available to the scripting engine.
Syntax: SGS_STATICMETHOD <type> <name>(<arguments>)
Alt. syntax (bind without declaration): SGS_STATICMETHOD SGS_ALIAS( <type> <name>(<arguments>) );
sgs_Context*
arguments can be used to get the context (the C
member variable is unavailable) and are not counted in the SGScript argument listMarks the renamed methods that should be made available to the scripting engine.
Syntax: SGS_STATICMETHOD_NAMED( <sgsname> ) <type> <realname>(<arguments>)
See SGS_STATICMETHOD for more info.
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 object interface function defines (destruct, getindex, expr etc.).
Marks objects to be marked for garbage collection.
Syntax: SGS_GCREF( <var1> <var2> ... )
Marks member variables as available for dumping.
Syntax: SGS_DUMP( <var1> <var2> ... )
All readable properties are dumped by default, this is used to specify variables that are not already specified as readable properties.
To prevent certain properties from being dumped, see SGS_NODUMP
Marks readable properties as unavailable for dumping.
Syntax: SGS_NODUMP( <var1> <var2> ... )
All readable properties are dumped by default, this is used to disable that for certain variables.
Marks a variable to be used as backing store (read from and write to it if a property/index-related action doesn't match any of this object's properties).
Syntax SGS_BACKING_STORE( (READ|WRITE) <var> )
* var
should be sgsVariable.
* It is not automatically initialized - to enable the system, it should be initialized to an object with free write capabilities (like dict
/map
)
This is the class used to minimally save/restore stack state (its size).
If stack is popped too far, it is not restorable.
SGS_CTX
(= sgs_Context* C
) - the current context
sgs_StkIdx m_stackSize
- required stack sizesgsScope( sgs_Context* c )
- initialize scope using current context and its stack sizebool is_restored()
- check if saved stack size matches the current oneThis is the class used for handling nullable values.
T data
- the data variable
bool isset
- specifies whether the data variable contains any useful data (false if value is null
)sgsMaybe()
- initializes a null
nullable value
sgsMaybe( EsgsMaybeNot )
- initializes a null
nullable value, to be used in functions returning sgsMaybe
by returning sgsMaybeNot
sgsMaybe( const T& val )
- initializes a nullable value from another such valuevoid set( const T& val )
- sets the variable to the specified (non-`null`) value
void unset()
- sets the variable to nulltemplate< class OwningClass > class sgsArrayIterator
This is an array access iterator class for the owning class that supports array indexing and size retrieval. The owning class needs to have these specific access points:
static const char* IteratorTypeName
- used for the object name definition
T operator [] ( sgs_SizeVal i ) const
- used to retrieve the specific item
sgs_SizeVal size() const
- used to retrieve item countOwningClass* m_owner
- the owning class (SGS_OBJECT)
sgs_SizeVal m_origsize
- original item count, retrieved from object
sgs_SizeVal m_offset
- current item offsetsgsArrayIterator( OwningClass* owner )
- create an iterator for a SGS_OBJECT
sgsArrayIterator( const sgsArrayIterator& other )
- create a copy of an iteratorvoid gcmark()
- implements the GCMARK callback, not to be generally called directly
int convert( SGS_CTX, sgs_VarObj* obj, int to )
- implements the CONVERT callback, not to be generally called directly
int getnext( SGS_CTX, int mode )
- implements the GETNEXT callback, not to be generally called directlyThis is the class used for handling SGS_OBJECT classes.
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_Context* c, sgs_VarObj* obj )
- initializes a handle from object pointer if it has the right interface, otherwise handle is initialized to NULL
sgsHandle( sgs_Context* c, sgs_StkIdx item )
- initializes a handle from stack index if it has the right interface, otherwise handle is initialized to NULL
sgsHandle( sgs_Context* c, sgs_Variable* var )
- initializes a handle from variable pointer if it has the right interface, otherwise handle is initialized to NULL
explicit sgsHandle( T* obj )
- initializes a handle from class (SGS_OBJECT) instance pointervoid gcmark()
- mark the object in handle as accessible (using sgs_ObjGCMark)
void push( sgs_Context* c = NULL )
- push the handle on the stack as object/null
bool not_null()
- returns if object handle points to an instance
sgsVariable get_variable()
- returns this handle as sgsVariable
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 ==
, bool operator !=
- comparison operatorsThis is the string interface and handling class.
sgs_iStr* str
- the string data pointer
SGS_CTX
(sgs_Context* C
) - associated contextsgsString()
- initializes a NULL handle
sgsString( const sgsString& h )
- initializes a handle from another handle
sgsString( sgs_Context* c, sgs_iStr* s )
- initializes a handle from string data pointer
sgsString( sgs_Context* c, sgs_StkIdx item )
- initializes a handle from stack index if it has the right interface, otherwise handle is initialized to NULL
sgsString( sgs_Context* c, sgs_Variable* var )
- initializes a handle from variable pointer if it has the right interface, otherwise handle is initialized to NULL
sgsString( sgs_Context* c, const char* s, size_t sz )
- creates a new string buffer and sets the handle to it
sgsString( sgs_Context* c, const char* s )
- creates a new 0-terminated string and sets the handle to itconst char* c_str()
- returns C string pointer or NULL for NULL handles
size_t size()
- returns string buffer size or 0 for NULL handles
bool get_string( std::string& out )
- creates a std::string for valid handles, returns if handle is valid (available only with SGS_CPPBC_WITH_STD_STRING
defined)
int compare( const sgsString& s ) const
- compare this string with another one (strcmp return rules)
bool same_as( const sgsString& s ) const
- returns if this string is exactly the same as the other string
bool equals( const char* s ) const
- returns if the specified C string is equal to this string
bool equals( const char* s, size_t sz ) const
- returns if the specified buffer is equal to this string
void push( sgs_Context* c = NULL ) const
- push the handle on the stack as string/null
bool not_null()
- returns if string handle points to a string
sgsVariable get_variable()
- returns this string as sgsVariable
void _acquire()
- increment reference count on variable
void _release()
- decrement reference count on variable, remove it from the classconst sgsString& operator = ( const sgsString& h )
- string assignment
bool operator <
, bool operator ==
, bool operator !=
- comparison operatorsThis is the class used for handling all SGScript variables.
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, sgs_StkIdx item )
- initialize a variable from current stack frame
sgsVariable( sgs_Context* c, sgs_StkIdx item, EMayNotExist )
- initialize a variable from current stack frame (index may not be valid, in which case the variable is initialized to NULL)
sgsVariable( sgs_Context* c, EPickAndPop )
- initialize a variable from the topmost stack item, pop it afterwards
sgsVariable( sgs_Context* c, sgs_Variable* v )
- initialize a variable from data pointer
sgsVariable( const sgsString& s )
- initialize a variable from the specified string handle
template< class T > sgsVariable( const sgsHandle<T>& h )
- initialize a variable from the specified class handlevoid push( sgs_Context* c = NULL ) const
- push the variable (optionally specify context if variable might not have it)
void gcmark()
- mark the variable as accessible (using sgs_GCMark)
bool not_null() const
- 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
sgs_VarObj* get_object_struct() const
- get the internal object structure
template< class T > T* get_object_data()
- get object pointer from variable (WARNING: this method does not do any safety checks)
template< class T > sgsHandle<T> get_handle()
- get the class handle
template< class T > sgsHandle<T> downcast()
- get the class handle (allow casting to inherited types)
int type_id() const
- get the type ID (one of SGS_VT_*** constants)
bool is_string() const
- return if this variable is a string
sgsString get_string()
- get the string handle
void set_meta_obj( sgsVariable metaobj )
- set the metaobject for this object
sgsVariable get_meta_obj()
- get the metaobject of this object
bool get_metamethods_enabled()
- check if metamethods are enabled for this object
void enable_metamethods( bool e )
- set if metamethods are enabled for this object
sgsVariable getsubitem( sgsVariable key, bool prop )
- retrieve an index/property value
sgsVariable getsubitem( const char* key, bool prop )
- retrieve an index/property value (string key)
sgsVariable getprop( sgsVariable key )
- retrieve a property value
sgsVariable getindex( sgsVariable key )
- retrieve an index value
sgsVariable getprop( const char* key )
- retrieve a property value (string key)
sgsVariable getindex( const char* key )
- retrieve an index value (string key)
bool setsubitem( sgsVariable key, sgsVariable val, bool prop )
- set an index/property value
bool setsubitem( const char* key, sgsVariable val, bool prop )
- set an index/property value (string key)
bool setprop( sgsVariable key, sgsVariable val )
- set a property value
bool setindex( sgsVariable key, sgsVariable val )
- set an index value
bool setprop( const char* key, sgsVariable val )
- set a property value (string key)
bool setindex( const char* key, sgsVariable val )
- set an index value (string key)
template< class T > T get()
- retrieve a C++ value from the variable
template< class T > T getdef( const T& def )
- retrieve a C++ value from the variable, using def
for null
sgsVariable& set_null()
- set variable to null
sgsVariable& set_bool( bool v )
- set variable to the specified boolean value
sgsVariable& set_int( sgs_Int v )
- set variable to the specified integer value
sgsVariable& set_real( sgs_Real v )
- set variable to the specified real number value
sgsVariable& set( sgsString v )
- set variable to the specified string value
sgsVariable& set( sgs_CFunc v )
- set variable to the specified C function value
template< class T > sgsVariable& set( sgsHandle< T > v )
- set variable to the specified class handle
template< class T > sgsVariable& set( T* v )
- set variable to the specified C++/SGScript class
bool call( sgs_Context* c, int args = 0, int ret = 0 )
- call variable as function using arguments from stack
bool thiscall( sgs_Context* c, sgsVariable func, int args = 0, int ret = 0 )
- use variable as this
in a method call to func
bool thiscall( sgs_Context* c, const char* key, int args = 0, int ret = 0 )
- use variable as this
in a method call to its function
RT tcall( sgs_Context* c, ... )
- call the variable with specified arguments on the given context
RT tthiscall( sgs_Context* c, sgsVariable func, ... )
- use variable as this
in a method call to func
RT tthiscall( sgs_Context* c, const char* key, ... )
- use variable as this
in a method call to its function
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)out
is specified, that variable receives the class, otherwise it is pushed on the stack.This function should not be used with existing instances, as it would make more than one SGScript object responsible for the same data. Use sgs_CreateVar or sgs_Create(Lite)ClassFrom with existing instances.
out
is specified, that variable receives the class, otherwise it is pushed on the stack.inst
.out
is specified, that variable receives the class, otherwise it is pushed on the stack.inst
.out
is specified, that variable receives the class, otherwise it is pushed on the stack.
Usage example:
SGS_CREATECLASS( C, NULL, myClass, ( param1, 5.0f ) );
Wrapper of sgs_GetEnv
C API function.