Hi All,
I am a beginner to Squirrel and SqPlus, in here I would like to share my experiences when I am embedding Squirrel into my 3d graphics framework.
This example shows how to access a C++ object which is created and returned from script; and shows the life-cycle of the object. It may not be the official way; and it may contains error. Please help to point them out if any.
Thanks
#include <sqplus.h>
class Counter
{
public:
Counter()
: mCnt( 0 )
{
printf("Counter::cstor\n");
}
~Counter()
{
printf("Counter::dstor\n");
}
void Inc()
{
mCnt++;
}
int GetCount() const
{
return mCnt;
}
static void DoBinding()
{
SQClassDef<Counter>("Counter")
.func( &Counter::Inc, "Inc" )
.var( &Counter::mCnt, "Cnt", VAR_ACCESS_READ_ONLY )
;
}
private:
int mCnt;
};
static void MyPrintFunc( HSQUIRRELVM v, const SQChar * s, ... )
{
static SQChar temp[2048];
va_list vl;
va_start( vl, s );
scvsprintf( temp, s, vl );
SCPUTS( temp );
va_end( vl );
}
static void RunTestScript( const SQChar * script )
{
SquirrelObject buf = SquirrelVM::CompileBuffer( script );
printf( "----- RunTestScript -----\n" );
try
{
SquirrelVM::RunScript( buf );
SquirrelFunction<squirrelobject> callFunc(_T("GetCounter"));
SquirrelObject ret = callFunc();
if ( !ret.IsNull() )
{
// assume the type must be Counter
Counter * counter = (Counter *)ret.GetInstanceUP( ClassType<Counter>::type() );
if ( counter )
printf( "C++: counter.Cnt = %d\n", counter->GetCount() );
}
}
catch ( SquirrelError & e )
{
scprintf(
_T( "Error: %s\n" )
, e.desc
);
}
printf( "\n" );
}
int main()
{
const SQChar * script1 = _T(
"function GetCounter()\n"
"{\n"
" local counter1 = Counter();\n"
" counter1.Inc();\n"
" print( format( \"Squirrel: counter1.Cnt = %d\", counter1.Cnt ) );\n"
" return counter1;\n"
"}\n"
);
const SQChar * script2 = _T(
"function GetCounter()\n"
"{\n"
" local counter2 = Counter();\n"
" counter2.Inc();\n"
" counter2.Inc();\n"
" print( format( \"Squirrel: counter2.Cnt = %d\", counter2.Cnt ) );\n"
" return counter2;\n"
"}\n"
);
const SQChar * script3 = _T(
"function GetCounter()\n"
"{\n"
" local counter3 = Counter();\n"
" counter3.Inc();\n"
" counter3.Inc();\n"
" counter3.Inc();\n"
" print( format( \"Squirrel: counter3.Cnt = %d\", counter3.Cnt ) );\n"
" return counter3;\n"
"}\n"
);
printf("VM Init\n");
SquirrelVM::Init();
sq_setprintfunc( SquirrelVM::GetVMPtr(), MyPrintFunc );
Counter::DoBinding();
// run script1
RunTestScript( script1 );
// run script2
RunTestScript( script2 );
// run script3
RunTestScript( script3 );
printf("VM Shutdown\n");
SquirrelVM::Shutdown();
return 0;
}
Expected Output:
VM Init
----- RunTestScript -----
Counter::cstor
Squirrel: counter1.Cnt = 1
C++: counter.Cnt = 1
----- RunTestScript -----
Counter::dstor
Counter::cstor
Squirrel: counter2.Cnt = 2
C++: counter.Cnt = 2
----- RunTestScript -----
Counter::dstor
Counter::cstor
Squirrel: counter3.Cnt = 3
C++: counter.Cnt = 3
VM Shutdown
Counter::dstor
3D = Design, Develop and Debug