
from libpandaexpressModules import *
from MessengerGlobal import *
from TaskManagerGlobal import *
from DirectNotifyGlobal import *

class EventManager:

    notify = None
    
    def __init__(self):
        """
        Create a C++ event queue and handler
        """
        # Make a notify category for this class (unless there already is one)
        if (EventManager.notify == None):
            EventManager.notify = directNotify.newCategory("EventManager")

        self.eventQueue = EventQueue.getGlobalEventQueue()
        self.eventHandler = EventHandler(self.eventQueue)

    def eventLoop(self, task):
        """
        Process all the events on the C++ event queue
        """
        while (not self.eventQueue.isQueueEmpty()):
            self.processEvent(self.eventQueue.dequeueEvent())
        return Task.cont

    def parseEventParameter(self, eventParameter):
        """
        Extract the actual data from the eventParameter
        """
        if (eventParameter.isInt()):
            return eventParameter.getIntValue()
        elif (eventParameter.isDouble()):
            return eventParameter.getDoubleValue()
        elif (eventParameter.isString()):
            return eventParameter.getStringValue()
        # Must be some user defined type, return the ptr
        # which will be downcast to that type
        else:
            return eventParameter.getPtr()
        
    def processEvent(self, event):
        """
        Process a C++ event
        """
        # Get the event name
        eventName = event.getName()
        if eventName:
            paramList = []
            for i in range(event.getNumParameters()):
                eventParameter = event.getParameter(i)
                eventParameterData = self.parseEventParameter(eventParameter)
                paramList.append(eventParameterData)
            # Do not print the new frame debug, it is too noisy!
            if (EventManager.notify.getDebug() and eventName != 'NewFrame'):
                EventManager.notify.debug('received C++ event named: ' + eventName +
                                          ' parameters: ' + `paramList`)
            # Send the event, we used to send it with the event 
            # name as a parameter, but now you can use extraArgs for that
            if paramList:
                messenger.send(eventName, paramList)
            else:
                messenger.send(eventName)
            # Also send the event down into C++ land
            self.eventHandler.dispatchEvent(event)
            
        # An unnamed event from C++ is probably a bad thing
        else:
            EventManager.notify.warning('unnamed event in processEvent')


    def restart(self):
        taskMgr.add(self.eventLoop, 'eventManager')

    def shutdown(self):
        taskMgr.remove('eventManager')

@@ -188,27 +188,46 @@
 _init__(self
+, eventQueue = None
 ):%0A
-
         %22%22%22%0A
@@ -479,16 +479,106 @@
 ager%22)%0A%0A
+        if eventQueue != None:%0A            self.eventQueue = eventQueue%0A        else:%0A    
         
@@ -624,24 +624,24 @@
 ventQueue()%0A
-
         self
@@ -699,28 +699,21 @@
 def 
-e
+doE
 vent
-Loop
+s
 (self
-, task
 ):%0A 
@@ -837,24 +837,24 @@
 ueEmpty()):%0A
-
             
@@ -902,16 +902,154 @@
 Event())
+%0A%0A    def eventLoopTask(self, task):%0A        %22%22%22%0A        Process all the events on the C++ event queue%0A        %22%22%22%0A        self.doEvents()
 %0A       
@@ -2980,16 +2980,20 @@
 ventLoop
+Task
 , 'event

generalize to allow multiple event managers in an application