2012-07-08 21:01:08 +00:00
#include "sqplus.h"
BOOL CreateStaticNamespace ( HSQUIRRELVM v , ScriptNamespaceDecl * sn )
{
int n = 0 ;
sq_pushroottable ( v );
sq_pushstring ( v , sn -> name , - 1 );
sq_newtable ( v );
const ScriptClassMemberDecl * members = sn -> members ;
const ScriptClassMemberDecl * m = NULL ;
while ( members [ n ]. name ) {
m = & members [ n ];
sq_pushstring ( v , m -> name , - 1 );
sq_newclosure ( v , m -> func , 0 );
sq_setparamscheck ( v , m -> params , m -> typemask );
sq_setnativeclosurename ( v , - 1 , m -> name );
sq_createslot ( v , - 3 );
n ++ ;
}
const ScriptConstantDecl * consts = sn -> constants ;
const ScriptConstantDecl * c = NULL ;
n = 0 ;
while ( consts [ n ]. name ) {
c = & consts [ n ];
sq_pushstring ( v , c -> name , - 1 );
switch ( c -> type ) {
case OT_STRING : sq_pushstring ( v , c -> val . s , - 1 ); break ;
case OT_INTEGER : sq_pushinteger ( v , c -> val . i ); break ;
case OT_FLOAT : sq_pushfloat ( v , c -> val . f ); break ;
}
sq_createslot ( v , - 3 );
n ++ ;
}
if ( sn -> delegate ) {
const ScriptClassMemberDecl * members = sn -> delegate ;
const ScriptClassMemberDecl * m = NULL ;
sq_newtable ( v );
while ( members [ n ]. name ) {
m = & members [ n ];
sq_pushstring ( v , m -> name , - 1 );
sq_newclosure ( v , m -> func , 0 );
sq_setparamscheck ( v , m -> params , m -> typemask );
sq_setnativeclosurename ( v , - 1 , m -> name );
sq_createslot ( v , - 3 );
n ++ ;
}
sq_setdelegate ( v , - 2 );
}
sq_createslot ( v , - 3 );
sq_pop ( v , 1 );
return TRUE ;
}
BOOL CreateClass ( HSQUIRRELVM v , SquirrelClassDecl * cd )
{
int n = 0 ;
int oldtop = sq_gettop ( v );
sq_pushroottable ( v );
sq_pushstring ( v , cd -> name , - 1 );
if ( cd -> base ) {
sq_pushstring ( v , cd -> base , - 1 );
if ( SQ_FAILED ( sq_get ( v , - 3 ))) { // Make sure the base exists if specified by cd->base name.
sq_settop ( v , oldtop );
return FALSE ;
}
}
if ( SQ_FAILED ( sq_newclass ( v , cd -> base ? 1 : 0 ))) { // Will inherit from base class on stack from sq_get() above.
sq_settop ( v , oldtop );
return FALSE ;
}
// sq_settypetag(v,-1,(unsigned int)cd);
#ifdef _WIN32
#pragma warning(disable : 4311)
#endif
sq_settypetag ( v , - 1 , reinterpret_cast < SQUserPointer > ( cd ));
const ScriptClassMemberDecl * members = cd -> members ;
const ScriptClassMemberDecl * m = NULL ;
if ( members ) {
while ( members [ n ]. name ) {
m = & members [ n ];
sq_pushstring ( v , m -> name , - 1 );
sq_newclosure ( v , m -> func , 0 );
sq_setparamscheck ( v , m -> params , m -> typemask );
sq_setnativeclosurename ( v , - 1 , m -> name );
sq_createslot ( v , - 3 );
n ++ ;
}
} // if
sq_createslot ( v , - 3 );
sq_pop ( v , 1 );
return TRUE ;
}
BOOL CreateNativeClassInstance ( HSQUIRRELVM v ,
const SQChar * classname ,
SQUserPointer ud ,
SQRELEASEHOOK hook )
{
// If we don't do this, SquirrelVM keeps an old pointer around and this
// will be used by SquirrelObject. That crashes when using several VMs.
SquirrelVM :: Init ( v );
int oldtop = sq_gettop ( v );
sq_pushroottable ( v );
sq_pushstring ( v , classname , - 1 );
if ( SQ_FAILED ( sq_rawget ( v , - 2 ))){ //Get the class (created with sq_newclass()).
sq_settop ( v , oldtop );
return FALSE ;
}
//sq_pushroottable(v);
if ( SQ_FAILED ( sq_createinstance ( v , - 1 ))) {
sq_settop ( v , oldtop );
return FALSE ;
}
#ifdef SQ_USE_CLASS_INHERITANCE
HSQOBJECT ho ;
sq_getstackobj ( v , - 1 , & ho ); // OT_INSTANCE
SquirrelObject instance ( ho );
SqPlus :: PopulateAncestry ( v , instance , ud );
#endif
sq_remove ( v , - 3 ); //removes the root table
sq_remove ( v , - 2 ); //removes the class
if ( SQ_FAILED ( sq_setinstanceup ( v , - 1 , ud ))) {
sq_settop ( v , oldtop );
return FALSE ;
}
sq_setreleasehook ( v , - 1 , hook );
return TRUE ;
}
// Create native class instance and leave on stack.
BOOL CreateConstructNativeClassInstance ( HSQUIRRELVM v , const SQChar * className ) {
int oldtop = sq_gettop ( v );
sq_pushroottable ( v );
sq_pushstring ( v , className , - 1 );
if ( SQ_FAILED ( sq_rawget ( v , - 2 ))) { // Get the class (created with sq_newclass()).
sq_settop ( v , oldtop );
return FALSE ;
} // if
#if 0
sq_remove(v,-3); // Remove the root table.
sq_push(v,1); // Push the 'this'.
#else // Kamaitati's change. 5/28/06 jcs.
sq_remove ( v , - 2 ); // Remove the root table.
sq_pushroottable ( v ); // Push the 'this'.
#endif
if ( SQ_FAILED ( sq_call ( v , 1 , SQTrue , SQ_CALL_RAISE_ERROR ))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called).
sq_settop ( v , oldtop );
return FALSE ;
} // if
sq_remove ( v , - 2 ); // Remove the class.
// int newtop = sq_gettop(v);
return TRUE ;
} // CreateConstructNativeClassInstance