albertodemichelis / squirrel

Official repository for the programming language Squirrel
http://www.squirrel-lang.org
MIT License
894 stars 148 forks source link

Class member variables under C++ #251

Closed sneakyevil closed 2 years ago

sneakyevil commented 2 years ago

Hello,

I been reading docs for past hours and I still can't figure out how I can set/get member variables for class that is binded under C++. I could easily define class funcs and even successfully call them and "deference" it to script variable under different name.

defined in C++

namespace TestClass
{
    HSQOBJECT m_sqObject;

    SQInteger Get(HSQUIRRELVM v)
    {
        sq_pushobject(v, m_sqObject);
        sq_createinstance(v, -1); // no clue if this is even correct

        // somehow set data?
        return 1;
    }

    SQInteger Test(HSQUIRRELVM v)
    {
        // retrieve data for task?
        return 1;    
    }
}

SQInteger oldtop = sq_gettop(m_VM);

sq_pushroottable(m_VM);
sq_pushstring(m_VM, "TestClass", -1);

if (SQ_SUCCEEDED(sq_newclass(m_VM, SQFalse)))
{
    sq_resetobject(&TestClass::m_sqObject);
    sq_getstackobj(m_VM, -1, &TestClass::m_sqObject);
    sq_addref(m_VM, &TestClass::m_sqObject);

    std::unordered_map<const char*, SQFUNCTION> m_TestClassMembers =
    {
        { "Get", TestClass::Get },
        { "Test", TestClass::Test },
    };

    for (auto m_TestClassMember : m_TestClassMembers)
    {
        sq_pushstring(m_VM, m_TestClassMember.first, -1);
        sq_newclosure(m_VM, m_TestClassMember.second, 0);
        sq_setparamscheck(m_VM, 0, 0);
        sq_setnativeclosurename(m_VM, -1, m_TestClassMember.first);
        sq_newslot(m_VM, -3, SQFalse);
    }

    sq_newslot(m_VM, -3, SQFalse);
    sq_pop(m_VM, 1);
}
else
    sq_settop(m_VM, oldtop);

defined in Script

c_class <- TestClass.Get();
c_class.Test();

I would like to be able to somehow set data for class and retrieve them later.

zeromus commented 2 years ago

I haven't used squirrel in a while so I might be rusty, but I think you've found it difficult to do what you want becausethere isn't any provision for doing it directly; you do it creatively with_ making getter and setter methods in c++ for each class member, or possibly a single get/set (for each type) with upvalues indicating what offset in the class member to get. You should invest the time in learning a binding library, probably

sneakyevil commented 2 years ago

I haven't used squirrel in a while so I might be rusty, but I think you've found it difficult to do what you want becausethere isn't any provision for doing it directly; you do it creatively with_ making getter and setter methods in c++ for each class member, or possibly a single get/set (for each type) with upvalues indicating what offset in the class member to get. You should invest the time in learning a binding library, probably

Is there any actual binding library that actually works properly? I only tried sqrat which seemed outdated after I binded class function and tried to call it and I got instant crash somewhere so I didn't even bother with it.

Also isn't there way to push to stack class with pointer? Or I would need to push it as table or something?

zeromus commented 2 years ago

you can push an object instance to to the stack with sq_pushuserpointer but as with everything it will take creativity to use it effectively. squirrel is not updated very often so I am surprised if the binding libraries break; contrariwise, I am not surprised if the binding libraries crash because using them is difficult in its own way. I suggest you use squirrel 3.1 since it's more likely to be compatible with the binding libraries, and begin with a working example and modify it one step at a time until you get what you want rather than start from scratch trying to understand how the binding library works so you won't go too far off track.

sneakyevil commented 2 years ago

Well I though about like pushing user pointer with class so I can basically "dereference" class to variable and call another member and still have access to some different pointer, and I'll try use the sqrat once more again with squirrel 3.1 and gonna give feedback if it works or not.

sneakyevil commented 2 years ago

Well I got the sqrat binding library working fine with 3.1 version, thanks for help also I got working the thing I wanted (passing own pointer)

Ex. image