Maybe I'm just dense right now (it's almost 4:30 am here) but I just can't understand what it is your asking in this question. My best guess right now is that your asking how to create an instance of a class in script and pass ownership of that instance out to C++. If that's the case try reading this
http://luabind.sourceforge.net/docs.html#policies_adopt
That's not exactly the problem (the real problem is probably my english

)
I'll look at your post again when I get up tomorrow to see if I can understand it any better. In the mean time if you want to try describing it another way or ask a different question feel free.
Ok I'll try again:
let's consider a Singleton class, Game for example:
Code: Select all
class Game : public Ogre::Singleton <Game>
{
public:
Game()
{
// Initialize the lua context
m_script = lua_open();
luabind::open(m_script);
// Tells lua that there is a global variable called "game"
luabind::get_globals(m_script)["game"] = this;
// Saves the reference to the global variable "game" so that
// we can refer to it from c++
m_self = luabind::get_globals(m_script)["game"];
}
void onStart()
{
// Calls a method of the global variable "game" called onStart in the script
luabind::call_member<void>(m_self, "onStart");
}
void onStop()
{
// Calls a method of the global variable "game" called onStop in the script
luabind::call_member<void>(m_self, "onStop");
}
public:
lua_State *m_script;
protected:
luabind::object m_self;
};
in the lua script I can write
Code: Select all
function game:onStart()
-- my game initialization here
end
function game:onStop()
-- my game cleanup here
end
No problems here but the point is that the variable game is "created" from C++ because the Game instance is allocated in C++
Consider instead a GameEntity class ("allocated" only from lua):
Code: Select all
class GameEntity
{
public:
GameEntity(string mesh)
{
// Takes the lua context from the game class
lua_State *script = Game::getSingleton().m_script;
// m_self = ?
}
virtual void onEvent(string name)
{
// Calls a member function of this instance in the script
// called "onEvent" passing the event name to it
luabind::call_member<void>(m_self, "onEvent", name);
}
protected:
Ogre::Entity *m_pEntity;
luabind::object m_self;
};
and from lua
Code: Select all
function game:onStart()
-- creates a ninja GameEntity
ninja = GameEntity('ninja.mesh')
-- creates an ogre GameEntity
ogrehead = GameEntity('ogrehead.mesh')
end
-- handles events for the ninja instance
function ninja:onEvent(name)
-- stuffs for ninja
end
-- handles events for the ogrehead instance
function ogrehead:onEvent(name)
-- stuffs for ogrehead
end
My problem is how to manage events of instances allocated from lua
because from c++ I haven't the back reference to the luabind::object class so I can't call luabind::call_member as before for the Game class
CEGui uses an
alternative approach to manage events
It creates a global function handler that takes as argument the object (or a param that allows to extract it) that receives the event:
Code: Select all
-- the CloseClicked event handler
function fwCloseClicked(eventArgs)
local we = CEGUI.toWindowEventArgs(eventArgs)
CEGUI.WindowManager:getSingleton():destroyWindow(we.window) -- destroy the frame window
end
Following this approach my example could be converted into this:
Code: Select all
class GameEntity
{
public:
GameEntity(string mesh)
{
}
virtual void onEvent(string name)
{
// Calls a global function in the script passing the instance and the function name
luabind::call_function<void>(Game::getSingleton().m_script, "eventsHandler", this, name);
}
protected:
Ogre::Entity *m_pEntity;
};
Code: Select all
function game:onStart()
-- creates a ninja GameEntity
ninja = GameEntity('ninja.mesh')
-- creates an ogre GameEntity
ogrehead = GameEntity('ogrehead.mesh')
end
-- handles events for all GameEntity instances
function eventsHandler(inst, name)
end
This works but I'd like to call a member function, not a global one...
Very thanks for the interest!