Derived Lua objects in C++ containers (with smart pointers)

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Derived Lua objects in C++ containers (with smart pointers)

Glen F
Hi there, I've been following section 12.1 of the luabind documentation to make Lua classes deriving from a C++ class.  I got it all working fine, but I still don't understand how to put Lua-created objects into a C++ container (STL vector, for example).  I'd like to iterate over them (in C++) and, calling their overridden (or not) virtual methods.  The complicating factor (maybe) is that I'd like to use smart pointers in the containing STL vector, and I don't see how to use both luabind::wrap_base and a smart pointer at the same time, in the class_ binding.

(in the below code, assume ofLog() is like cout, and ofPtr is just shared_ptr)

C++ code:

class MyItem
{
public:
    MyItem(const string &s = "MYITEM DEFAULT")
    : mStr(s) {
        ofLog() << "MyItem::MyItem(" << mStr << ")";
    }

    

    virtual void f(int a) {
        ofLog() << mStr << " -- MyItem::f(" << a << ")";
    }

    

protected:
    string  mStr;
};

struct MyItem_wrapper : MyItem, luabind::wrap_base
{
    MyItem_wrapper(const string &s)
    : MyItem(s) {}

    

    virtual void f(int a) {
        call<void>("f", a);
    }

    

    static void default_f(MyItem* ptr, int a) {
        return ptr->MyItem::f(a);
    }
};

class Holder
{
public:
    void addItem(ofPtr<MyItem> inItem) {
        mObjs.push_back(inItem);
    }

    void traverse() {
        vector<ofPtr<MyItem> >::iterator    it;
        int num = 0;
        for (it = mObjs.begin(); it != mObjs.end(); it++, num++) {
            (*it)->f(num);
        }
    }

    

protected:
    vector<ofPtr<MyItem> >    mObjs;
};

and to register the classes:

            module(lua, "objects")
            [
             class_<Holder>("Holder")
             .def(constructor<>())
             .def("addItem", &Holder::addItem)
             .def("traverse", &Holder::traverse),

             

             class_<MyItem, MyItem_wrapper>("MyItem")
             .def(constructor<const string &>())
             .def("f", &MyItem::f, &MyItem_wrapper::default_f)
             ];



Then in Lua, create a derived class and try to add several instances of it to the container class:


class 'Derived' (objects.MyItem)

function Derived:__init(str)
    objects.MyItem.__init(self, str .. "(Derived)")
    self.newParam = 1234.5
end

function Derived:f(a)
    objects.MyItem.f(self, a)
    print(a + 100, self.newParam)
end

hold = objects.Holder()
x = Derived("hello")
x:f(3)
-- everything works, up to here

hold:addItem(x)   -- ka-blooey
x = Derived("there")
hold:addItem(x)
hold:traverse()

On the first addItem(), I get the following error:


got an error: Runtime error: No matching overload found, candidates:
void addItem(Holder&,custom [5ofPtrI6MyItemE])

Any tips on how to do what I'm trying to do?  Do I have to make a new wrapper class that's a combination of luabind::wrap_base and shared_ptr?  I can skip using smart pointers for the container, if someone can explain how I should manage object lifetime, when the "Holder" container may have a mixture of Lua-created and C++-created objects.

Thanks,
Glen.


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Derived Lua objects in C++ containers (with smart pointers)

Christian N.
On Monday, July 08, 2013 1:08 PM, Glen Fraser [mailto:[hidden email]] wrote:
> The complicating factor (maybe) is that I'd like to use smart pointers in the containing
> STL vector, and I don't see how to use both luabind::wrap_base and a smart pointer at the
> same time, in the class_ binding.

I think you identified the problem correctly. Have you read
http://www.rasterbar.com/products/luabind/docs.html#smart-pointers ?
You need to specify ofPtr as an template argument when registering your class and make sure
that a get_pointer() function is available in the same namespace as ofPtr (global is only
sufficient if ofPtr is itself global).

> (in the below code, assume [...] ofPtr is just shared_ptr)

boost::shared_ptr? Then just specify ofPtr as template argument, as said above, and you
should be done.
If not, you additionally need to supply an appropriate get_pointer() function. For
std::shared_ptr, you can use a header I made for this purpose (just include it):
http://github.com/Oberon00/luabind/blob/master/luabind/std_shared_ptr_converter.hpp

I hope I could help,
Christian


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Derived Lua objects in C++ containers (with smart pointers)

Glen F

On Jul 8, 2013, at 2:04 PM, "Christian" <[hidden email]> wrote:

>> The complicating factor (maybe) is that I'd like to use smart pointers in the containing
>> STL vector, and I don't see how to use both luabind::wrap_base and a smart pointer at the
>> same time, in the class_ binding.
>
> I think you identified the problem correctly. Have you read
> http://www.rasterbar.com/products/luabind/docs.html#smart-pointers ?
> You need to specify ofPtr as an template argument when registering your class and make sure
> that a get_pointer() function is available in the same namespace as ofPtr (global is only
> sufficient if ofPtr is itself global).

Yes, I had indeed read it -- but where I went wrong was assuming ofPtr supported get_pointer().  It doesn't.  It's not based on boost::shared_ptr but rather std::shared_ptr, which doesn't include a get_pointer() method.  Changing my code to use boost::shared_ptr, it all works fine.  Otherwise, I could add a get_pointer() function, as in your code.

Thanks!
Glen.

>
>> (in the below code, assume [...] ofPtr is just shared_ptr)
>
> boost::shared_ptr? Then just specify ofPtr as template argument, as said above, and you
> should be done.
> If not, you additionally need to supply an appropriate get_pointer() function. For
> std::shared_ptr, you can use a header I made for this purpose (just include it):
> http://github.com/Oberon00/luabind/blob/master/luabind/std_shared_ptr_converter.hpp
>
> I hope I could help,
> Christian


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user