@People using python as their scripting language in their C++ apps - beware of reference counts!
So I
thought I had reliable callback functionality implemented for my python bindings... I wanted a python function/method to register itself to C++, like so:
(python)
Test(object):
def __init__(self, game_obj):
self.__game_obj = game_obj
self.__game_obj.register_callback(self.__on_callback)
def __on_callback(self):
print 'called back, yo!'
if __name__ == '__main__':
game = Game()
test = Test(game)
Where the "register_callback" function in C++ looks like this:
void Game::registerCallback(boost::python::object callable)
{
m_CallbackList.push_back(callable)
}
And the actual call of the callback looks like this:
void Game::dispatchCallbacks()
{
for(auto it : m_CallbackList)
it();
}
You'd think that looks pretty clean, right?
Wrong!
The "Game" class never destructs,
ever. The reason being that m_CallbackList is holding a python object containing an instance of "Game" - a reference to itself you could say. So even when you shut down the python interpreter and try to clean up everything, boost.python will refuse to destroy the "Game" class because there are still references pointing to it.
Well damn.
The solution is obviously to use weak references, but I haven't quite figured out how those work yet.