Squirrel as alt scripting language
#11
Geeze.. finally!!

main.cpp
Code:
#include "cMCLogger.h"

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <sqplus/sqplus.h>
#include <sqplus/SquirrelObject.h>


class MyCppClass
{
public:
    static MyCppClass* s_Singleton;
    int classVal;
    MyCppClass()
        : classVal(123)
    {
        LOGINFO("Created new class");
        s_Singleton = this;
    }
    virtual bool process(int iVal,const SQChar * sVal)
    {
        LOGINFO("classVal: %d, iVal: %d, sVal %s\n",classVal,iVal,sVal);
        classVal += iVal;
        return iVal > 1;
    }
    virtual void lulwut() = 0;
};
MyCppClass* MyCppClass::s_Singleton = 0;

extern bool IsTopClosure( HSQUIRRELVM v );

class MyCppClass__Squirrel : public MyCppClass
{
public:
    MyCppClass__Squirrel()
    {
    }
    virtual void lulwut()
    {
        if( !IsTopClosure(vm) ) // Avoid recursion
        {    //Called from C++
            SqPlus::SquirrelFunction<void> startFunc = SqPlus::SquirrelFunction<void>(obj, "lulwut");
            startFunc();
        }
        else // Called from Squirrel
        {
            //MyCppClass::lulwut(); // Can't do this, it's a pure virtual
        }
    }
    virtual bool process(int iVal,const SQChar * sVal)
    {
        return MyCppClass::process(iVal, sVal);
    }

    static int constructor(HSQUIRRELVM v)
    {
        LOG("construct__MyCppClass__Squirrel()");

        MyCppClass__Squirrel* newClass = new MyCppClass__Squirrel();

        StackHandler sa(v);
        HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE
        SquirrelObject instance(ho);
        SqPlus::PopulateAncestry(v, instance, newClass);
        newClass->SetInstance( instance, v );

        sq_setinstanceup(v, 1, newClass);
        sq_setreleasehook(v, 1, SqPlus::ReleaseClassPtr<MyCppClass__Squirrel>::release);
        return TRUE;
    };

    void SetInstance( SquirrelObject & a_Inst, HSQUIRRELVM & a_VM ) { obj = a_Inst; vm = a_VM; }

    HSQUIRRELVM vm;
    SquirrelObject obj;
};

static void printFunc(HSQUIRRELVM v,const SQChar * s,...)
{
    va_list vl;
    va_start(vl,s);
    cMCLogger::GetInstance()->Log( s, vl );
    va_end(vl);
}

int main( int argc, char **argv )
{
    new cMCLogger();

    SquirrelVM::Init();
    sq_setprintfunc(SquirrelVM::GetVMPtr(),printFunc,printFunc);

    SqPlus::SQClassDef<MyCppClass__Squirrel>( "MyCppClass" ).
        staticFunc(&MyCppClass__Squirrel::constructor, "constructor").
        func(&MyCppClass__Squirrel::process, "process").
        func(&MyCppClass__Squirrel::lulwut, "lulwut").
        var(&MyCppClass__Squirrel::classVal, "classVal");

    try
    {
        SquirrelObject helloSqPlus = SquirrelVM::CompileScript( "squirreltest.nut" );
        try
        {
            SquirrelVM::RunScript(helloSqPlus);
            LOGWARN("About to call function from C++");
            MyCppClass::s_Singleton->lulwut();
        }
        catch (SquirrelError & e)
        {
            printf("Error: %s, %s\n", e.desc, "Squirrel::helloSqPlus");
        }
    }
    catch (SquirrelError & e)
    {
        printf("Error: %s, %s\n", e.desc, "Compiling");
    }

    getchar();

    SquirrelVM::Shutdown();
    return 0;
}

squirreltest.nut
Code:
class TestClass extends MyCppClass
{
    function print(msg)
    {
        ::print(msg);
    }
    function process(iVal, sVal)
    {
        print("Printed from Squirrel");
        base.process(iVal, sVal);
    }

    function lulwut()
    {
        print("Lulwut from Squirrel!");
    }
}

myClass <- TestClass();

local rVal = myClass.process(1, "MyClass1");

print("Returned: " + ( rVal ? "true" : "false") );

rVal = myClass.process(2, "MyClass2");

print("Returned: " + (rVal ? "true" : "false") );
print("classVal: " + myClass.classVal );

FINALLY produces this:
[Image: 30801124583-orig.png]


bedtime now ...
Reply
Thanks given by:
#12
Awesome!
Reply
Thanks given by:
#13
Nice. Almost makes me regret working on this cuboid plugin in lua... almost.
[Image: clapping-squirrel.jpg]
Reply
Thanks given by:
#14
I'm not sure if this is gonna work. I can't figure out how to do something as simple as passing the newly created cPlugin to cPluginManager::AddPlugin() as a pointer or whatever.

But what worries me most is that Squirrel has no idea of the underlaying inheritance of classes, I mean I might export cSpider to Squirrel, but how does Squirrel know it extends cMonster or even cEntity? You won't be able to call the most basic functions such as GetPosition() without casting to a cEntity (if that is even possible)

In case you're wondering, Lua DOES know about the inheritance of the classes by using tolua_cclass(...), looks like this:
Code:
tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup);

This tells Lua cPickup extends cEntity, and the same is done for cSpider -> cMonster and cMonster -> cEntity, this way Lua knows cSpider is a cEntity


EDIT:
Nvm, Squirrel does know this. However I'm still stuck XD
Reply
Thanks given by:
#15
Now I can't get it to compile in Linux T_T
Reply
Thanks given by:
#16
D:

http://www.maniacworld.com/squirrel-vs-penguin.htm
Reply
Thanks given by:
#17
(11-07-2011, 10:56 AM)FakeTruth Wrote: Now I can't get it to compile in Linux T_T

I finally found some time for MCServer.

I really like squirrel and did some little projects with it already. So I created a simple plugin system. I used Sqrat instead of SqPlus because I think it is much easier.

This time everything compiles on windows and linux but at the moment there isnĀ“t very much bound to squirrel. (Only AddHook, Player::GetName)
But I will bind the other classes step-by-step later on.
Others can also help me with this, because I will take some time to do manual bindingBig Grin
It is not very hard. Just take a look at the SquirrelBinding.cpp Wink

Simon
Reply
Thanks given by:




Users browsing this thread: 5 Guest(s)