Clay
18-10-2005 03:34:39
(Please note that in this post I refer to EventSet, don't forget that all Window classes also inherit from EventSet. IE everything I say below about EventSets apply to Window, PushButton, etc.)
After a lot of start and stop work I finally got CEGUI to bind events. This is how I am currently doing it:
You can see this works in sandbox/testcegui.py. As you can see I have passed in "Clicked" instead of cegui.PushButton.EventClicked, but this will change shortly after I have properly wrapped the static strings for all EventSet subclasses (should be in the next revision).
The subscribeEvent currently returns an EventConnection object. This object has two methods, connected and disconnect. The connected method tells you whether the event is active and being called when events are triggered. The disconnect method removes the event from the EventSet it is registered to and frees the memory associated with the event. If you do not call EventConnection.disconnect() on every event you registered, or you do not call EventSet.removeAllEvents before you delete the EventSet you will create a memory leak.
It's rare that someone actually completely removes a GUI element from a program entirely. Usually it is simply hidden (or a different sheet is shown) until it is needed again. When the program ends, memory is cleaned up on its own and there shouldn't be anything to worry about. So to reiterate, unless you are trying to completely remove a widget from the program you do not need to worry about EventConnection disconnecting events, or calling removeAllEvents. You only need to do this if you are trying to completely delete a widget, not hide it.
You may be wondering why all of the issues with memory management. I think this is about the best I can do without reimplementing parts of CEGUI, which violates a major goal for us switching from Boost.Python to SWIG. The old Boost based pyogre did this much much worse. It passed a local variable as a reference to a class which held the reference. I'm shocked we didn't see massive crashes and access violations. I'm tempted to build a copy of the old pyogre just to see how this worked.
Anyway, it's not 100% finnished. There's still some cleanup to do, but I'm working on it. There may be a segfault or two if you really really push it with this, but I promise it'll be cleaned up in a day or two.
After a lot of start and stop work I finally got CEGUI to bind events. This is how I am currently doing it:
quitButton = # create the control here
# events
def onQuit(args):
print "onQuit!"
ec = quitButton.subscribeEvent("Clicked", onQuit)
You can see this works in sandbox/testcegui.py. As you can see I have passed in "Clicked" instead of cegui.PushButton.EventClicked, but this will change shortly after I have properly wrapped the static strings for all EventSet subclasses (should be in the next revision).
The subscribeEvent currently returns an EventConnection object. This object has two methods, connected and disconnect. The connected method tells you whether the event is active and being called when events are triggered. The disconnect method removes the event from the EventSet it is registered to and frees the memory associated with the event. If you do not call EventConnection.disconnect() on every event you registered, or you do not call EventSet.removeAllEvents before you delete the EventSet you will create a memory leak.
It's rare that someone actually completely removes a GUI element from a program entirely. Usually it is simply hidden (or a different sheet is shown) until it is needed again. When the program ends, memory is cleaned up on its own and there shouldn't be anything to worry about. So to reiterate, unless you are trying to completely remove a widget from the program you do not need to worry about EventConnection disconnecting events, or calling removeAllEvents. You only need to do this if you are trying to completely delete a widget, not hide it.
You may be wondering why all of the issues with memory management. I think this is about the best I can do without reimplementing parts of CEGUI, which violates a major goal for us switching from Boost.Python to SWIG. The old Boost based pyogre did this much much worse. It passed a local variable as a reference to a class which held the reference. I'm shocked we didn't see massive crashes and access violations. I'm tempted to build a copy of the old pyogre just to see how this worked.
Anyway, it's not 100% finnished. There's still some cleanup to do, but I'm working on it. There may be a segfault or two if you really really push it with this, but I promise it'll be cleaned up in a day or two.