Shortcommings in SWIG directors

Clay

22-10-2005 02:29:57

Bad news. It seems that swig directors (C++ callbacks) cannot handle multiple inheritance. Normally we could inherit from multiple Listeners in Ogre:
class Whatever : public Ogre::FrameListener, public Ogre::KeyListener, ...
But this fails in PyOgre:
class TutorialFrameListener(SampleFramework.FrameListener, ogre.MouseListener,
ogre.MouseMotionListener, ogre.KeyListener):
def __init__(self, renderWindow, camera, sceneManager):
ogre.MouseListener.__init__(self)
ogre.MouseMotionListener.__init__(self)
ogre.KeyListener.__init__(self)
SampleFramework.FrameListener.__init__(self, renderWindow, camera)

self.eventProcessor.addKeyListener(self) #fails

TypeError: argument number 2: a 'Ogre::KeyListener *' is expected, 'PySwigObject(_p_Ogre__FrameListener)' is received


Because the FrameListener's __init__ was called last, SWIG thinks that this is ONLY a FrameListener object. This is a problem with SWIG, and there is not much I can do about it. I have opened a bug on their tracker, but I'm not expecting it to get fixed anytime soon.

A current solution is to simply use different classes for each director you use, but for the Key/Mouse/Frame Listeners this would be a hassle. So I have created a CombinedListener class that can be used as a FrameListener, KeyListener, MouseListener, and/or MouseMotionListener. Until swig fixes the problem, this is going to be the best I can do, sorry.

dermont

22-10-2005 04:14:58

I asked this in the main forum, so I just want to check again. Consider the following code:


class GUIFrameListener(ogre.FrameListener,ogre.KeyListener,ogre.MouseListener,ogre.MouseMotionListener):


def __init__(self,renderWindow,root,sceneManager,camera,cameraAnimationState):

#create event processor
eventProcessor = ogre.EventProcessor()
eventProcessor.initialise(renderWindow)
eventProcessor.startProcessingEvents()
self.eventProcessor = eventProcessor

#Listeners
ogre.MouseListener.__init__(self)
eventProcessor.addMouseListener(self)
ogre.MouseMotionListener.__init__(self)
eventProcessor.addMouseMotionListener(self)
ogre.KeyListener.__init__(self)
eventProcessor.addKeyListener(self)
ogre.FrameListener.__init__(self)



I encountered the 'Ogre::KeyListener *' etc expected problem but resolved it by "initing" last to first. I couldn't get it to work with the SampleFramework but it appears to work with using the cegui demo. Any comments would be appreciated.

Clay

22-10-2005 05:03:36

I don't know why I didn't think to check what testcegui.py was doing. I didn't even think of doing it this way.

This works, but it leaks memory. Every time you call __init__ for each of those classes it creates a new director object for that type, which is subsequently never deleted. (Except for the very last one.) At least, that's what it looks like is happening. It's hard to tell with that generated code sometimes. =)

dermont

22-10-2005 05:51:46

Yep I think I had problems during cleanup.