Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have had a look around but I believe this to be impossible due to compile time of c++.

However is it possible to have a class registered in lua and c++ that has a overload update function which I can then overload within lua rather than c++.

If this is not possible would it be viable to just have a register function for the class and then register the lua function with.

so for example i would have:

local myclass = RegClass.new()

function update()
   io.write("Update")
end

myclass:RegisterFunction(Reg.Update, update)

Another question I have is how would I go about registering a static class or a predefined class within lua (just a link with any information will be helpful).

Thanks for any help or device Dekowta

share|improve this question
2  
This seems more a question for stackoverflow.com –  petervaz Apr 8 '13 at 20:00
2  
The term you're looking for is "over*ride*", not overload. Overloading is about different functions with the same name but different parameters. Overriding is what virtual lets you do, calling derived-class members through base classes. –  Nicol Bolas Apr 9 '13 at 6:02
add comment

closed as off topic by Byte56, Josh Petrie, bummzack, Anko, Trevor Powell Apr 9 '13 at 8:59

Questions on Game Development Stack Exchange are expected to relate to game development within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer

up vote 2 down vote accepted

The short answer is (probably) no, if you're expecting to call update() from C++ code. I'll go into some depth for you:

The C++ compiler will call an overloaded function only if the base class is declared virtual. Behind the scenes, it creates a vtable, which it uses to look up which function to call when appropriate. The vtable is created implicitly by the compiler, and you have no direct means of interfacing with it (practically speaking). Here's an example that doesn't use the keyword virtual:

// some class declarations
class Foo {
    void call() { printf( "Foo::call()" ); }
};

class Bar : public Foo {
    void call() { printf( "Bar::call()" ); }
}

// somewhere in code, perhaps main
Foo* foo = new Bar();
foo->call();

In this case, you would actually see "Foo::call()" because you're calling call() on an instance of Foo, and call() was not declared virtual.

Here's a crude way you could call Bar::call():

Bar* bar = (Bar*)foo;
bar->call();

Here you would see "Bar::call()". As you can see, the compiler is directly calling the function for the type which you are using (we changed the type to Bar by casting in this example).

Declaring Foo::call() virtual will fix this. Revise our declaration for Foo:

// some class declarations
class Foo {
    virtual void call() { printf( "Foo::call()" ); }
};

And try using our inheritance again:

// somewhere in code, perhaps main
Foo* foo = new Bar();
foo->call();

Now you would see "Bar::call()". Since we declared Foo::call() virtual, whenever the compiler sees an instance of Foo (regardless of it's real type), it will look at the vtable for the object to determine which function it should actually call.

So lets take a look at how this relates to Lua. I'm not sure how you're integrating your C++ code with Lua, but I can probably safely assume a couple things:

1) local myclass = RegClass.new() is actually creating a new instance of your class, and storing the pointer in the metatable of myclass (probably as userdata).

2) The implementation of update() in C++ of RegClass (or one of its base classes) is declared virtual.

What you want to do will work, provided one of the two conditions:

1) The concrete implementation of update() calls into Lua. To work with your code sample, it would probably need to keep up with the Lua object itself, and do some tedious stack manipulation in order to provide the 'self' object and/or the function to be called. I give a rough outline of how this could work below. If you're using a Lua binding framework, this may be handled for you.

2) You're calling from Lua, in which case none of the C++ stuff even matters.

Specifically, here is a case that won't work unless your framework does a lot of magic behind the scenes:

// in C++
class Foo {
    Foo() { ... };
    virtual void call() { ... };
};

-- in Lua
local foo = Foo:new();
foo.call = function( self )
    print( "hello from Lua" )

In order to "glue" these together, the implementation of call() that is called at runtime in C++ would need to actually call into Lua with references to the "local foo" object that's created, as well as the "foo.call" function. This can certainly be done, and there are quite a few frameworks out there that help manage some (or all?) of the gory details.

Here's an example that might get you started thinking down the right track:

// C++
class LuaFoo : public Foo /* using Foo defined directly above */ {

    LuaFoo( lua_State* L ) {
        // TODO:
        // pull a reference to the created class out of the lua state
        // store it as a member variable of our LuaFoo class
    }

    virtual void call() {
        // TODO:
        // get the lua state from somewhere, being wary of threading issues, and the state of the lua stack
        // push stuff onto the lua stack, namely the reference to the object in lua
        // call the lua function
        // handle errors and/or return values
        // be sure that the lua stack is left in the same condition (depth) that you got it in
    }
};

// somewhere else (still in C++), where we initialize our Lua environment:
// TODO:
// push a table called LuaFoo, or just Foo if you want to bury the Lua part of the name
// set it up so that calling LuaFoo:new() will invoke the constructor above

-- in Lua, create our actual object:
local foo = LuaFoo:new()
foo.call = function( self )
    printf( "hello from Lua!" )

// and finally, back in C++, the money shot:
Foo* foo = // somehow we get a reference to the object we created in Lua, perhaps it's in a big list with lots of other Foo's
foo->call(); // we'd see "hello from Lua!" here

If you don't find this particularly encouraging, take a look at some of the Lua binding frameworks out there which may help take care of some or all of these details. In any case, hopefully it gives you some idea of what's actually going on.

share|improve this answer
    
Thanks for the reply I will look into it. Kinda annoyed this question got closed since it is related to helping me implement scripting into my game engine. –  Dekowta Apr 9 '13 at 11:22
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.