![]() |
Show Changes |
![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
![]() |
Administration Page |
![]() |
Topic Locks |
| Search |
History
| 10/4/2007 9:51:01 PM |
| -82.148.98.34 |
| 7/10/2007 3:39:56 PM |
| ad-remover-84.49.122.139 |
| 5/30/2007 12:38:14 PM |
| -125.72.28.38 |
| 5/30/2007 10:53:38 AM |
| -83.237.111.118 |
| 5/28/2007 6:50:12 AM |
| -69.136.148.27 |
![]() |
List all versions |
acsitdo
The following code produces an error:
#include <stdarg.h>
#include <stdio.h>
#include <squirrel.h>
#include <sqstdio.h>
#include <sqstdaux.h>
#include <sqplus.h>
#ifdef SQUNICODE
#define scvprintf vwprintf
#else
#define scvprintf vprintf
#endif
class Point3
{
public:
float x, y, z;
};
DECLARE_INSTANCE_TYPE(Point3);
class Entity
{
public:
void test(Point3& p)
{
if (scriptTest.func.IsNull())
printf("invalid function\n");
else
{
printf("p = {%f, %f, %f}\n", p.x, p.y, p.z);
scriptTest(p);
}
}
static int construct(HSQUIRRELVM v)
{
printf("construct()\n");
StackHandler sa(v);
Entity *self = new Entity();
self->scriptTest = SqPlus::SquirrelFunction<void>(sa.GetObjectHandle(1),_T("test"));
self->scriptObjHandle = sa.GetObjectHandle(1);
sq_addref(SquirrelVM::GetVMPtr(), &self->scriptObjHandle);
return SqPlus::PostConstruct<Entity>(v, self, release);
}
SQ_DECLARE_RELEASE(Entity);
private:
SqPlus::SquirrelFunction<void> scriptTest;
HSQOBJECT scriptObjHandle;
};
DECLARE_INSTANCE_TYPE(Entity);
void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
va_list arglist;
va_start(arglist, s);
vprintf(s, arglist);
va_end(arglist);
}
int main()
{
SquirrelVM::Init();
sq_setprintfunc(SquirrelVM::GetVMPtr(), printfunc);
HSQUIRRELVM v = SquirrelVM::GetVMPtr();
SqPlus::SQClassDef<Entity>("Entity")
.staticFuncVarArgs(&Entity::construct, "constructor", "*")
;
SqPlus::SQClassDef<Point3>("Point3")
;
SquirrelObject inst = SquirrelVM::CompileBuffer("\
class A extends Entity {\n\
function test(pos) {value=1; print(\"pos.x = \"+pos.x);}\n\
value = 10;\n\
};\n\
function create() {return A();}\n\
");
SquirrelVM::RunScript(inst);
Entity *e = SqPlus::SquirrelFunction<Entity*>("create")();
Point3 pt = {1,2,3};
e->test(pt);
SquirrelVM::Shutdown();
return 0;
}
When executed it produces the following output:
construct()
p = {1.000000, 2.000000, 3.000000}
AN ERROR HAS OCCURED [the index 'value' does not exist]
CALLSTACK
*FUNCTION [test()] console buffer line [2]
LOCALS
[pos] INSTANCE
[this] TABLE
Note that error is in referencing member value and type of this is table.
That is because of bug in CreateConstructNativeClassInstance function.
inline 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
sq_remove(v,-3); // Remove the root table.
sq_push(v,1); // Push the 'this'.
if (SQ_FAILED(sq_call(v,1,SQTrue))) { // 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
Bug is in these lines:
sq_remove(v,-3); // Remove the root table. //^ -3 is index before root table pushed first at beginning of this function! sq_push(v,1); // Push the 'this'. //^ 1 is also invalid index because there was something on stack before
To fix this it is needed to replace them with
sq_remove(v,-2); // Remove the root table. sq_pushroottable(v); // Push the 'this'.