Squirrel

The programming language
Welcome to Squirrel Sign in | Join | Help
in Search

Getting the instance class name out of a SquirrelObject

Last post 06-30-2008, 2:59 AM by AndiNo. 10 replies.
Sort Posts: Previous Next
  •  03-08-2006, 8:52 AM 690

    Hmm [^o)] Getting the instance class name out of a SquirrelObject

    Let's say that I have a squirrel function that takes in an instance from c++ and returns it:



    ////////////////////////////////////////////
    Squirrel Function
    ////////////////////////////////////////////
        function onInstanceRemoved(instance) {
            print("Executing onInstanceRemoved");
            return instance;
        }
    ////////////////////////////////////////////
    End Squirrel Function
    ////////////////////////////////////////////



    and I call the function like this, by passing in a pointer instead of a reference (assuming I've bound Ogre::Vector3):



    ////////////////////////////////////////////
    C++
    ////////////////////////////////////////////
        Ogre::Vector3 instance(1,2,3);
        SquirrelObject retVal;

        SqPlus::SquirrelFunction func("onInstanceRemoved");
        retVal = func(&instance);
    ////////////////////////////////////////////
    End C++
    ////////////////////////////////////////////



    Testing retVal for type yeilds OT_INSTANCE, as expected. Lets say that I wanted another portion of the program to test what kind of class that is, and create a pointer to the instance.

    The functionality could best be described as:

    if(SquirrelObject.getInstanceClassName == "Vector3")
    {
        Ogre::Vector3* ptr = SquirrelObject.getInstancePointer();
        //do something with ptr here
    }

    I know that the commands don't exist, but it shows what I'm trying to do.

    How would I go about that if all I have is the SquirrelObject? How do I get the instance's class name and pointer out of that SquirrelObject?

    At first guess, I thought that the information must be somewhere at the end of
    object.GetObjectHandle()._unVal.pInstance->
    but I was unsure of what I was finding.

    Does anyone know how to do this?

    --Ben
  •  04-20-2006, 6:29 AM 775 in reply to 690

    Re: Getting the instance class name out of a SquirrelObject

    Is this even possible? :-)

    --Ben
  •  04-20-2006, 11:37 AM 779 in reply to 690

    Re: Getting the instance class name out of a SquirrelObject

    I recently wrote something similar:

        SquirrelObject gs = SquirrelVM::GetRootTable().GetValue("gameSystem");
        SquirrelObject so = gs.GetValue("waypointSoundEffect");
        SoundEffect * waypointSoundEffect = (SoundEffect *)so.GetInstanceUP(ClassType<SoundEffect>::type());
        if (wayPointSoundEffect) {
          // ...
        } // if

    Example with Vector3:

        SquirrelObject so = SquirrelVM::GetRootTable().GetValue("MyInstanceName");
        Vector3  * myVector3  = (Vector3 *)so.GetInstanceUP(ClassType<Vector3>::type());
        if (myVector3) {
          // ...
        } // if

  •  04-21-2006, 7:18 AM 781 in reply to 779

    Re: Getting the instance class name out of a SquirrelObject

    First, thanks a lot, that'll make the first part of this easier :-)

    Secondly, this example assumes that I know what type SquirrelObject so is before I start casting. Will it throw an error if you attempt to cast to something that it is not? That's why I wanted to see if there was a way to test for what class it was as well as getting the pointer out.

    Thanks a lot for your help,

    --Ben
  •  04-21-2006, 1:23 PM 786 in reply to 781

    Re: Getting the instance class name out of a SquirrelObject

    See http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlus.html . I made a small change to make this work in a useful way. It works like a cast attempt: if the cast fails, NULL is returned (but no error is set/thrown).

    SqPlus stores the instance type name in the VarRef (see SqPlus.cpp). It may be useful in the future to create a GetInstanceTypeName() function for debugging, _tostring() support, etc. Such a function would operate on the owning class or table (the VarRef is stored at that level, not in the instance itself).

    Here's how to examine the type (using GetInstanceUP() is simpler and faster if a valid pointer is needed):


        SQUserPointer instanceType=NULL;
        if (so.GetTypeTag(&instanceType)) {
          if (instanceType == ClassType<SoundEffect>::type()) {
            lprintf("type is SoundEffect ");
          } else {
            lprintf("Incorrect type ");
          } // if
        } else {
          lprintf("TypeTag not set: incorrect type ");    
        } // if
    <soundeffect><soundeffect><soundeffect>



    Please ignore the "soundeffect " garbage at the bottom of the post: forum software bug (can't delete it).
  •  04-21-2006, 4:50 PM 787 in reply to 786

    Re: Getting the instance class name out of a SquirrelObject

    Added two more functions (useful for debugging), SquirrelObject::GetTypeName(SQChar * key) and SquirrelObject::GetTypeName():


        SquirrelObject gs = SquirrelVM::GetRootTable().GetValue("gameSystem");
        SquirrelObject so = gs.GetValue("waypointSoundEffect");

        const SQChar * typeNameFromOwningObject = gs.GetTypeName("waypointSoundEffect");
        const SQChar * typeNameFromObject       = so.GetTypeName();
        lprintf("TypeName: %s, %s ",typeNameFromOwningObject,typeNameFromObject);

  •  04-22-2006, 10:10 AM 794 in reply to 787

    Re: Getting the instance class name out of a SquirrelObject

    As one final request, can you add the function:
    SquirrelObject::GetTypeName(SQInteger key)
    as well?

    I use some numeric keys now and again in my tables, and this would be perfect :-)

    Thanks again for your help,

    --Ben
  •  04-22-2006, 11:53 AM 795 in reply to 794

    Re: Getting the instance class name out of a SquirrelObject

  •  04-30-2007, 9:04 PM 1824 in reply to 795

    Re: Getting the instance class name out of a SquirrelObject

    Has anyone successfully tested this functionality? I was hoping that this would return the actual name of the class. Here's what I'm trying:

    In squirrel:

    class MassiveBanana
    {
       constructor()
       {
          print ("A massive banana has been summoned\n");
       }
    }

    In c++:

    SqPlus::CreateConstructNativeClassInstance(SquirrelVM::GetVMPtr(), "MassiveBanana");
    SquirrelObject sqObj;
    sqObj.AttachToStackObject(-1);
    const SQChar * typeName = sqObj.GetTypeName();
    printf("%s", typeName);

    When I run the program, I see:

    "A massive banana has been summoned"
    int

    If I debug the program, sqObj is of type OT_INSTANCE and the constructor is clearly firing. I was hoping that typeName would be "MassiveBanana" after the call to GetTypeName.

  •  10-22-2007, 10:55 PM 2223 in reply to 1824

    Re: Getting the instance class name out of a SquirrelObject

    GetTypeName still doesn't do for me what I think it's supposed to do.

    Here's a complete example (using SqPlus):

    void nativefunc(SquirrelObject obj)
    {
    #ifdef SQ_SUPPORT_INSTANCE_TYPE_INFO
       printf ("TypeName = %s \n", obj.GetTypeName());
    #endif

       SquirrelObject key, value, rt = SquirrelVM::GetRootTable();

       rt.BeginIteration();
       while (rt.Next(key, value))
       {
          //If the UPs have the same address, the values match
          //and key holds the class name
          if (value.GetObjectHandle()._unVal.pUserPointer ==
              obj.GetObjectHandle()._unVal.pUserPointer)
          {
             printf ("If you were a %s class, would you instantiate yourself?\n",
                      key.ToString());
          }
       }
       rt.EndIteration();

       return;
    }

    int main(int argc, char *argv[])
    {
       SquirrelVM::Init();

       RegisterGlobal(nativefunc, "nativefunc");

       SquirrelObject test = SquirrelVM::CompileBuffer(_T("\
        class HotDog {                     \n\
          static id = 0;                   \n\
        }                                  \n\
                                           \n\
        //Pass the OT_CLASS to native func \n\
        nativefunc(HotDog);                \n\
       "));
      
       SquirrelVM::RunScript(test);

       return 0;
    }

    When I run this code, I get the following output:

    TypeName = (null)
    If you were a HotDog class, would you instantiate yourself?

    I would expect that GetTypeName would return the name of the class or at least "class" instead of NULL. If not, is there a better way to get this same functionality?

    Also, shouldn't the GetUserPointer() function have an override that doesn't require a key? I had to do this to get the UP:

    obj.GetObjectHandle()._unVal.pUserPointer

    Thanks
  •  06-30-2008, 2:59 AM 2596 in reply to 2223

    Re: Getting the instance class name out of a SquirrelObject

    This thread is old, but the question is still unanswered^^
    I have a C++ class "CGameObject" and a script class "GameObject" that is derived of CGameObject. In C++ I create an instance of the script-class with CreateConstructNativeClassInstance. Then I attach a SquirrelObject to it with AttachToStackObject. This works so far, but I tried to get a CGameObject pointer out of this SquirrelObject. I tried it with
    CGameObject *obj = sqobj.Get<CGameObject*>();
    and
    CGameObject *obj  = (CGameObject*)sqobj.GetInstanceUP(ClassType<CGameObject>::type());
    as it was written in some posts, but the only working solution so far seems to be juggernauts
    CGameObject *obj = (CGameObject*)sqobj.GetObjectHandle()._unVal.pUserPointer;
    What did I do wrong? Isn't there any nicer way to obtain a valid pointer?
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems