Advertisement

Binding free function operator with tolua++

Started by July 05, 2011 11:01 PM
0 comments, last by fcoelho 13 years, 4 months ago
I'm trying to create bindings for Box2D to use within Lua with tolua++.

Tolua++ can generate operator bindings when they're defined as members of the given class, but not when they're free functions. In order to properly use Box2D in Lua, I'd like to generate bindings for its vector (b2Vec2) operators, which are defined as free functions.

How can I create these bindings? Luabind seems to be able to handle this, but I'd rather do it with tolua++ if there's a (easy) way.
Since I couldn't find any reasonable solution, I've modified tolua++ to accept free function operators. In short, tolua++ is already able to correctly generate off-class operator bindings, but doesn't know what to do with them. If the error directive on operator.lua is supressed,

[source]
if not t:inclass() then
--error("#operator can only be defined as class member")
end
[/source]

then generated code for some operator will live in the global namespace. If one opens the generated bindings and moves the lines corresponding to those operators to inside the class module, operator overloading works nicely, i.e., if

[source lang="cpp"]
tolua_beginmodule(tolua_S,NULL);
...
tolua_beginmodule(tolua_S,"b2Vec2");
...
tolua_endmodule(tolua_S);
tolua_function(tolua_S,".mul",tolua_lancamento__mul00);
tolua_endmodule(tolua_S);
[/source]

is changed to

[source lang="cpp"]
tolua_beginmodule(tolua_S,NULL);
...
tolua_beginmodule(tolua_S,"b2Vec2");
...
tolua_function(tolua_S,".mul",tolua_lancamento__mul00);
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);
[/source]

then the custom operator works. Since I didn't want to do this every time the package file changed, I've modified the lua sources to register the function in the right place automatically, relying on the first parameter of the operator argument list to determine who to bind that operator to. So, if there's an [font="Courier New"]operator+(const b2Vec2&, const b2Vec2&)[/font], it gets added to the b2Vec2 class. Pretty lame, but gets the work done, as long as the first parameter is a custom type. It is extremely simple, so there are possibly a lot of corner cases that I didn't test, but it works for me.

Some restrictions:

  • Due to the way operator overload works in Lua, no operator+=, operator-= etc. (already considered by tolua++)
  • If the first argument of a certain type isn't a custom type, the binding generation will fail. In these cases, I had to define a "wrapper" operator just for the sake of it, like:
    [source lang="cpp"]
    inline b2Vec2 operator*(const b2Vec2 &a, float s)
    {
    return operator*(s,a);
    }
    [/source]


    To be honest, I'm not used to patching, but if anyone's interested, attached is the diff file from my mercurial repository.[attachment=4820:offclassop.zip]

This topic is closed to new replies.

Advertisement