From: klaas.holwerda <ng...@kl...> - 2008-10-30 19:27:37
|
John Labenski wrote: >> obj = iter3:op_mul() > > This should error out since op_mul() expects an argument. No it really works. And operator*() generates things different compared too operator*( const a2dAffineMatrix& m ) Which is what i need, only the naming i don't like. > >> If possible adding an extra op_deref or something like that would be >> nice. > > Can you explain why you need to dereference an object pushed into Lua? > wxLua uses pointers to all class objects, gets them as pointers in the > bindings and simply puts a * in front if necessary. Unless I'm > misunderstanding, the operator will convert the pointer to the object, > but then immediately convert it back to a pointer to push it into Lua. First of all a2dCanvasObjectListIter is internal in my code a: typedef a2dCanvasObjectList::iterator a2dCanvasObjectListIter; and a2dCanvasObjectList is derived from a template instantiation of a smart pointer list called a2dSmrtPtrList<a2dCanvasObject>, which contain a2dCanvasObjectPtr, this last is a typedef a2dSmrtPtr<a2dCanvasObject> a2dCanvasObjectPtr; a2dSmrtPtrList is on it turn a normal STL list containing Smart Pointers. Now STL lists only work properly/best with complete objects in the list, so not pointers. STL makes copies of the objects you put in the list, and deletes them itself. And that is why the STL list works very well with Smart Pointer, since they are objects, which internal uses a pointer to the actual object, which has a refcounter. Here that is a a2dCanvasObject. So copies are cheap, just increment the refcounter. (Very similar to the typical wxWidgest refcounting, but not copy on write here). And deletion by STL, is calling a delete on the SmartPointer, which means only decrementing the refcount of the a2dCanvasObject, unless 0. Anyway, the STL list has an internal nested iterator class. So my a2dCanvasObjectList above, has a a2dCanvasObjectList::iterator, which i need to use to iterate the list. I can't derive that iterator, and nor redefine its methods. So in order to use it in wxLua, i need to use its methods as is. And to bad that is mostly operatorXXX. The iterator in STL always delivers references to the object it points too. And it does that with operator*(). I need to write: a2dCanvasObjectList::value_type obj = *iter; So in my case i get a a2dCanvasObjectPtr from it. And to get to the real object, i need to use the Get() method of my Smart Pointer a2dCanvasObjectPtr, which delivers me a a2dCanvasObject*. Here is what i have in the binding file. %class %delete %encapsulate %noclassinfo a2dCanvasObjectPtr a2dCanvasObject* Get() const %endclass %class %encapsulate %noclassinfo a2dCanvasObjectListIter a2dCanvasObjectListIter() %operator a2dCanvasObjectPtr operator*() const ....rest... %endclass %class %noclassinfo a2dCanvasObjectList, a2dSmrtPtrList a2dCanvasObjectList() a2dCanvasObjectListIter lbegin() a2dCanvasObjectListIter lend() ....rest... %endclass And here is how it is use it inside a lua script. iter3 = childs:lbegin() for i=1,childs:size() do obj = iter3:op_mul() nameOfobj = obj:Get():GetName() iter3:op_inc() end As you can see, op_mul() gives me a a2dCanvasObjectPtr, and i can even call the Get() method on it. Now if you say that is in fact not a a2dCanvasObjectPtr, but a a2dCanvasObjectPtr*, i believe you, and i see it in the C++ binding code :-) But that does not change the fact that in C++ the operator*() is really use to get to the STL iterator. Which is the only way possible. So some way or the other, currently op_mul() is correctly resulting in the operator*(), which i need to get to the STL iterator its objects. The a2dCanvasObjectPtr* returns = new a2dCanvasObjectPtr(*(*self)) is also interesting. First the iterator (*self) delivers a "a2dCanvasObjectPtr&" using *(*self). I can write it like this also: a2dCanvasObjectPtr* returns = new a2dCanvasObjectPtr(self->operator *()); That lua wants a a2dCanvasObjectPtr* is fine with me, it deletes it himself, and its just an extra refcount behind the scenes inside the a2dCanvasObject. Therefore it makes no differnce who deletes it first (Lua or the list). Down here the code that is generated for operator*(), which is different compared to what is generated for // %operator a2dAffineMatrix operator*( const a2dAffineMatrix& m ) const There is contains: a2dAffineMatrix* returns = new a2dAffineMatrix((*self)*(*m)); // %operator a2dCanvasObjectPtr operator*() const static int LUACALL wxLua_a2dCanvasObjectListIter_op_mul(lua_State *L) { // get this a2dCanvasObjectListIter * self = (a2dCanvasObjectListIter *)wxluaT_getuserdatatype(L, 1, wxluatype_a2dCanvasObjectListIter); // call op_mul // allocate a new object using the copy constructor a2dCanvasObjectPtr* returns = new a2dCanvasObjectPtr(*(*self)); // add the new object to the tracked memory list wxluaO_addgcobject(L, (void*)returns, new wxLua_wxObject_a2dCanvasObjectPtr((a2dCanvasObjectPtr*)returns)); // push the result datatype wxluaT_pushuserdatatype(L, returns, wxluatype_a2dCanvasObjectPtr); return 1; } So after all it looks this is really implemented, still i would like it to be called not op_mul but op_deref :-) Hope this helps to understand what is happening here, Regards, Klaas > |