Re: Crash in wrapper_base.cpp
Nigel Atkinson <[email protected]> Thu, 07 Jul 2011 09:25:16 +1000
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <1309994716.1607.21.camel@virNatty> |
> On Sun, Jul 3, 2011 at 6:25 PM, Drew McLean <[email protected]> > wrote: > Hello, > > I am using Lua 0.9.1 in a custom game engine and am using the > feature of extending C++ objects using Lua via > luabind::wrap_base. My C++ base class is called Agent and > contains a virtual function called Update(). I have created a > class called ScriptableAgent which extends Agent and > luabind::wrap_base. Lua instances of derived classes are > stored in a global table in Lua to avoid garbage collection > occurring before the object should be destroyed. Once created > in Lua they are passed to a C++ container which updates the > instances each frame. Whenever I am done with an instance it > is removed from the container in C++ and is then removed from > the global Lua table so that it can be garbage collected. I've hit this exact same problem, in a almost exact same situation - I had a vector of game entities that I was looping through calling an update function. Also I was relying on the destructor and hence the Luabind finaliser to remove entities from the list. However Update was being called between the time the Lua entity reference was set to nil, and the time the object was destructed and removed from the list. Even a explicit garbage collection (or several) did not seem to work. I never quite got to the bottom of it, however I have a hacky solution that works. This is my GameEntityWrapper: class GameEntityWrapper : public GameEntity, public luabind::wrap_base { public: virtual void update() { lua_State* L = m_self.state(); m_self.get(L); if( ! lua_isnil( L, -1 ) ) // If the Lua side is not there anymore just ignore. call<void>( "update" ); lua_pop( L, 1 ); } static void default_update( GameEntity* ptr ) { ptr->GameEntity::update(); } }; If you interested in the rest have a look at: https://github.com/merlinblack/Game-Engine-Testbed/blob/master/include/gameentity.h This required a small change in wrapper_base.hpp on line 66 from private: wrapped_self_t m_self; to protected: wrapped_self_t m_self; This allows access to m_self in your wrapper class. You might not even need to recompile the library - how hacky is THAT! :-) But there are bound to be better solutions, that probably do not require changing Luabind. However this works for me. Perhaps the change to wrapper_base.hpp might be considered for Luabind - or perhaps adding a function along the lines of isValid() to wrap_base. I really should figure out why doing an explicit garbage collection - even several iterations - still did not prevent my crash.... Nigel ------------------------------------------------------------------------------ All of the data generated in your IT infrastructure is seriously valuable. Why? It contains a definitive record of application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-d2d-c2