From: William S F. <ws...@fu...> - 2014-04-22 18:26:21
|
On 15/04/14 22:31, Eric Wing wrote: > I am trying to get == to work as one might intuitively/naturally expect in Lua. > > Here is a real example: > local a, b = chipmunk.cpArbiterGetShapes(arbiter) > if (b == s_playerFeet) or (a == s_playerFeet) then > s_playerData.canJump = true; > end > > In C, cpArbiterGetShapes returns pointers to cpShape* instances. They > are equal if the pointers are equal. It is unfortunate that the SWIG > implementation always creates a new userdata wrapper instead of > keeping a map of existing userdata's in the system and reusing them. > This has unfortunate side effects of breaking the == operator as well > as creating extra garbage that needs to be collected. But the fix for > that is a discussion I'll save for another day. > > The easy fix for == is to simply define a default __eq metamethod that > compares the underlying pointers. I think this is always the correct > default behavior because the == is pretty much useless otherwise > because whether you get distinct userdata wrappers for a pointer is a > SWIG implementation in my opinion. > > I propose that the __eq metamethod be added to the default userdata > setup. I noticed there is already a function called SWIG_Lua_equal > that has the correct implementation, so essentially, we need a forward > declaration (because it is declared too far down) and in > SWIG_Lua_class_register_instance, add the line: > > SWIG_Lua_add_function(L,"__eq",SWIG_Lua_equal); > > (And while I'm here, I'll also propose modifying the __tostring > implementation to also print the underlying userdata->ptr address > because this information was really useful for debugging the above > problem.) > > > The one caveat is that the documentation claims this is supposed to work: > %extend Complex { > const char *__str__() { > static char tmp[1024]; > sprintf(tmp,"Complex(%g,%g)", $self->re(),$self->im()); > return tmp; > } > bool operator==(const Complex& c) > { return ($self->re()==c.re() && $self->im()==c.im();} > }; > > However I tried it and on the operator== part, SWIG errors out with: > Error: Syntax error in input(3). > > (I changed Complex to cpShape for my case.) > I have successfully been using %extend like so up until this point so > I know the basic %extend works: > %extend cpShape { > ~cpShape() { > cpShapeFree($self); > } > } > > So I claim operator== is broken and may have never worked. I could not > find any test cases of this. > > Ideally, a user could supply this and override the default __eq > behavior as the documentation suggests. But currently I'm focused on > the 80% case. And right now I think not providing the pointer > comparison default is wrong. And since the %extend case doesn't work, > we don't even have a 20% case right. > Can you look at https://github.com/swig/swig/pull/159. I think this should fix your problems. Please advise whether or not it does. William |