Squirrel

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

Overwriting C++ virtual methods in Squirel side. (Read a bunch of similar posts)

Last post 08-11-2008, 9:03 AM by hexdump. 3 replies.
Sort Posts: Previous Next
  •  08-09-2008, 12:41 PM 2679

    Overwriting C++ virtual methods in Squirel side. (Read a bunch of similar posts)

    Hi all,

    I know this has been asked thousand of times, but I haven´t seen any clear answer for it. Anyway the information given is around 1, 1.5 years old, and I don´t know if new additions have been included for this in squirrel.

    My problem is simple, and I think everyone has face it before. I have a C++ base class that defines some virtual functions (I don´t reall need pure virtual here, I could implement base ones with just empty body) and I want to create some derived classes in squirrel that rewrite/overload the base method. After that I want to get a instance of the class created in squirrel and call one of the virtual functions. By now I have everything done despite the virtual call, the one allways is done to the base class method of the instance.

    Could anyone give any clear tip about it? I would really apreciate it.

    P.D. I´m using sqplus.

    Thanks in advance,
    HexDump.
  •  08-10-2008, 6:26 AM 2683 in reply to 2679

    Re: Overwriting C++ virtual methods in Squirel side. (Read a bunch of similar posts)

    Well I came across a solution I don´t know if it is good or not. For the Base class I could have a non virtual Update function that could, using the spell instance name call the Update method on the squirrel object instance.

    I think this could work but don´t know if it is a good way to do things, and if it is, how to accomplish it, any tip please?.

    Thanks in advance,
    HexDump.
  •  08-11-2008, 5:08 AM 2687 in reply to 2679

    Re: Overwriting C++ virtual methods in Squirel side. (Read a bunch of similar posts)

    Hello,

    Yes, I encountered this situation a while ago and implemented a more generic way of implementing / extending a virtual C++ class in Squirrel. This approach has a couple of steps to it.

    Say we have something like:

      class EntityI {
        virtual int GetHealth(){ return 0; }
        virtual const char* GetName(){ return "NoNameYet"; }
        // ...
      };


    We'd like to override the virtuals in Squirrel:

      class ScriptedEntityI : public EntityI {
         // Do whatever to be able to route virtual function calls to most derived Squirrel
         // class (for the instance).
      }

    The soultion has a couple of parts:

    1 - A helper base class: ScriptedVirtualHelper
    It does a few things (which all classes extended in this way need):
    1a - Storing a reference to the C++ instance and the corresponding Squirrel instance
    1b - It stores a reference to the Squirrel class for the instance
    1c - It stores the last Squirrel function called (and its name):

      SquirrelFunction<int> m_sf;
      const SQChar*          m_func;

    These three are strictly not necessary but will speed up function invocation a lot,
    since often two or three of them are the same from call to call.

    Then it has a function:

        bool SetupCall( void *pv_this, const SQChar *func );

    which is called before each virtual function call. It prepares everything (and does
    nothing if everything is already set up right).

    Finally we cast the SquirrelFunction to its right return value (from whatever type
    the overridden function returns):

        template<class RT>
        SquirrelFunctionSafe<RT>& GetSqFn(){
            return (SquirrelFunction<RT>&)m_sf;
        }


    Now, the base class can be used to override a function in Squirrel:

      class ScriptedEntityI : public EntityI, ScriptedVirtualHelper {
          int ScriptedEntityI::GetHealth( ){
              return SetupCall(this,_SC("GetHealth")) ?
                   GetSqFn<int>() () :  // Get function and invoke it
                   0;
          }
          // Override other functions in the same way.
      }

    Then you extend ScriptedEntityI on the Squirrel side:

      class SqEntityI extends ScriptedEntityI {
          function GetHealth(){ return m_health }
         // ... other methods
        local m_health
      }


    One key point (which is not handled by SqPlus at the moment) is to bind a C++ instance
    with the same Squirrel object instance each time it is used. Otherwise in the SqEntityI above,
    we would use different m_health at different calls for the same C++ object. Some way of
    tracking instantiated Squirrel objects is needed, and some fast lookup scheme (C++ object
    => Squirrel object).

    One must also be careful with correctly maintaing Squirrel references on the instance, the class
    and the function (in  ScriptedVirtualHelper).


    Source for this is available through SVN:

      http://trac2.assembla.com/File_Workbench/browser

    Directory: trunk/FileWorkbench/script/squirrel/BindUtils.h

    Regards
    // ATS.




     











  •  08-11-2008, 9:03 AM 2688 in reply to 2687

    Re: Overwriting C++ virtual methods in Squirel side. (Read a bunch of similar posts)

    Thanks a lot for the answer ATS. You have been really kind.

    I think all you posted is really cool, and more or less is based on my previous solution (but yours more generic and it fits better). Anyway from your words I understand it is in a early development stage and it needs more work, so, I will implement things the way I explained and later if I need more speed I will recheck the post and hopefully you got a final solution for this without the problems you stated :).

    For my game right now, I will move the C++ base class (the one with the virutal methods) I have now to squirrel because I don´t need it in the C++ side. Then everything will be dervied/instantiated there. Instances of this class (derived) has to be added to a list in one of the c++ class, so I will just return an ID to a global table where I store my instances and will resolve this id to an SquirrelObject when needed. I understand this way I don´t need to have strong references to the squirrel clases because when this squirrel clases are not needed I will have a squirrel method that receives the id and nulls the object in squirrel side. What do you think?

    Thanks again for the help and all the information you provided,
    HexDump.
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems