Show Changes Show Changes
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Administration Page Administration Page
Topic Locks Topic Locks

Search

History

7/5/2007 6:48:36 AM
-220.211.116.217
5/30/2007 12:38:59 PM
-125.72.28.38
5/28/2007 6:49:52 AM
-69.136.148.27
7/13/2006 9:51:28 PM
-71.225.31.29
7/12/2006 12:04:48 PM
-71.224.62.52
List all versions List all versions

RSS feed for the SquirrelWiki namespace

Sq Plus Native Created Instances With Correct Ancestry
.

To expose the bug:

 #include <string>
 #include <sqplus.h>


 class Base 
 {
        public:
                Base() {}
                virtual ~Base() {}


                static void Bind()
                {
                        SqPlus::SQClassDef<Base>(_T("Base")).
                                func(&Base::GetBaseId,"getBaseId");
                }


                std::string GetBaseId() { return "Base"; }


 };


 DECLARE_INSTANCE_TYPE(Base);


 class Derived : public Base 
 {


        public:
                Derived() : Base() {}
                virtual ~Derived() {}


                static void Bind()
                {
                        SqPlus::SQClassDef<Derived>(_T("Derived"),_T("Base")).
                                staticFunc( &Derived::GetNativeCreated, "getNativeCreated" );
                                func( &Derived::GetDerivedId, "getDerivedId");
                }


                std::string GetDerivedId() { return "Derived"; }


                static Derived* GetNativeCreated() { return instance; }


      private:
                static Derived* instance;
 };


 Derived* Derived::instance = new Derived();


 DECLARE_INSTANCE_TYPE(Derived);


 int _tmain(int argc, _TCHAR* argv[])
 {
      printf("Initialize Squirrel\n");
      SquirrelVM::Init();
      printf("Binding classes to squirrel\n");
      Base::Bind();
      Derived::Bind();


      try
      {
                SquirrelObject script = SquirrelVM::CompileBuffer(_T(
                        " \
                                local shouldWork = Derived(); \
                                print(\"Base id is \" + shouldWork.getBaseId()); \
                                local shouldFail = shouldWork.getNativeCreated(); \
                                print(\"Base id is \" + shouldFail.getBaseId()); \
                        "
                ));


                SquirrelVM::RunScript(script);
        }
        catch(SquirrelError& error)
        {
                printf("Error: %s\n",std::string(error.desc).c_str());
        }
 }

To fix it:

In sqplus.h add this after #define SQ_ANCESTOR_CLASS_INDEX T("_ci")

 inline void PopulateAncestry(HSQUIRRELVM v, SquirrelObject& instance, SQUserPointer up) {


        SquirrelObject objectTable = SquirrelVM::CreateTable();
    instance.SetValue(SQ_CLASS_OBJECT_TABLE_NAME,objectTable);


        SquirrelObject classHierArray = instance.GetValue(SQ_CLASS_HIER_ARRAY);
        INT heirarchyIndex = instance.GetValue(SQ_ANCESTOR_CLASS_INDEX).ToInteger();
        INT count = classHierArray.Len();
        if (heirarchyIndex < count) 
        { 
                for (INT i=0; i <= heirarchyIndex; i++) {
                        SquirrelObject so = classHierArray.GetValue(i);
                        sq_pushobject(v,so.GetObjectHandle());
                        SQUserPointer typeTag;
                        sq_gettypetag(v,-1,&typeTag);
                        objectTable.SetUserPointer(INT(size_t(typeTag)),up);
                        sq_poptop(v); 
                } // for
                instance.SetValue(SQ_ANCESTOR_CLASS_INDEX,SquirrelObject()); // Store an OT_NULL object to free SQ_ANCESTOR_CLASS_INDEX var.
        } // if
 }

Replace the PostConstruct function with this

 template<typename T>
 inline int PostConstruct(HSQUIRRELVM v,T * newClass,SQRELEASEHOOK hook) {


 #ifdef SQ_USE_CLASS_INHERITANCE
  StackHandler sa(v);
  HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE
  SquirrelObject instance(ho);
  PopulateAncestry(v,instance,newClass);
 #endif


  sq_setinstanceup(v,1,newClass);
  sq_setreleasehook(v,1,hook);
  return 1;
 } // PostConstruct

in the RegisterClassType function replace

 classHierArray.ArrayAppend(newClass);          // Add the class to the hierarchy array. The array values will be released and replaced with UserData to free created ancestor classes.
 newClass.SetValue(SQ_ANCESTOR_CLASS_INDEX,-1); // When the class hierarchy is created, this var will be used to help in recursively creating ancestor classes.

with

  INT count = classHierArray.Len();
  classHierArray.ArrayAppend(newClass); // Add the class to the hierarchy array. The array values will be released and replaced with UserData to free created ancestor classes.
  newClass.SetValue(SQ_ANCESTOR_CLASS_INDEX,count); // When the class hierarchy is created, this var will be used to help in recursively creating ancestor classes.

In SquirrelBindingsUtils.h replace CreateNativeClassInstance with this

 BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook)
 {
        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;
 }
Not logged in. Log in

squirrel's community wiki

This is FlexWiki, an open source wiki engine.

Change Style

Recent Topics