Author: remi
Date: 2009-06-09 14:29:13 +0200 (Tue, 09 Jun 2009)
New Revision: 4760

Added:
   
software_suite_v3/smart-core/smart-server/trunk/resources/04_robot_content_interactions/00_resourceRobotContentInteractions.py
Modified:
   
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/00_resourceAttituneManager.py
   
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/01_resourcePluginsServer.py
   
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/03_resourceUgcServer.py
Log:
* added a method to play (synchronous) an attitune
* updated plugins/gadgets/ugc servers according to the new plugin 
interpretation (by context)
* added a resource to controls the interactions between plugins/gadgets, the 
user button events and the running contexts.

Modified: 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/00_resourceAttituneManager.py
===================================================================
--- 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/00_resourceAttituneManager.py
  2009-06-09 12:26:04 UTC (rev 4759)
+++ 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/00_resourceAttituneManager.py
  2009-06-09 12:29:13 UTC (rev 4760)
@@ -253,8 +253,7 @@
             if len(macro) <= 16384:
                 resourceTuxDriver.executeMacro(macro)
                 resourceTuxOSL.executeMacro(macro)
-                duration = attitune.getDescription().getDuration() - \
-                    begin
+                duration = attitune.getDescription().getDuration() - begin
                 if duration > 0.0:
                     t = threading.Thread(target = self.__attituneStartingLoop,
                         args = (attitune, duration))
@@ -263,6 +262,39 @@
         t = threading.Thread(target = async)
         t.start()
         return True
+        
+    def playAttituneSync(self, name, begin):
+        """Play an attitune.
+        @param name: Attitune name.
+        @param begin: Begining position.
+        @return: True or False.
+        """
+        if not resourceTuxDriver.getDonglePlugged():
+            return False
+        attituneExists = False
+        attitunes = self.getAttitunesContainer().getAttitunes()
+        for attitune in attitunes:
+            if attitune.getDescription().getName() == name:
+                attituneExists = True
+                break
+        if not attituneExists:
+            return False
+        self.__attituneMutex.acquire()
+        if self.__isAttituneRun():
+            self.__setAttituneRun(False)
+            resourceTuxOSL.clearAll()
+            resourceTuxDriver.clearAll()
+            time.sleep(0.2)
+        macro = attitune.getMacro(begin)
+        macro = resourceTuxOSL.reencodeTTSTextInMacro(macro)
+        if len(macro) <= 16384:
+            resourceTuxDriver.executeMacro(macro)
+            resourceTuxOSL.executeMacro(macro)
+            duration = attitune.getDescription().getDuration() - begin
+            if duration > 0.0:
+                self.__attituneStartingLoop(attitune, duration)
+        self.__attituneMutex.release()
+        return True
 
     def stopAttitune(self):
         """Stop the current played attitune.

Modified: 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/01_resourcePluginsServer.py
===================================================================
--- 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/01_resourcePluginsServer.py
    2009-06-09 12:26:04 UTC (rev 4759)
+++ 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/01_resourcePluginsServer.py
    2009-06-09 12:29:13 UTC (rev 4760)
@@ -137,96 +137,82 @@
     # Plugin events
     # 
--------------------------------------------------------------------------
 
-    def __onPluginNotification(self, plugin, instanceParameters, messageId,
-        *args):
+    def __onPluginNotification(self, pluginInterpreterContext, messageId, 
*args):
         messageStr = ""
         for message in args:
             messageStr += message
-        uuid = plugin.getDescription().getUuid()
-        locutor = instanceParameters['locutor']
-        pitch = instanceParameters['pitch']
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logDebug("Plugin NOTIFICATION [%s] (%s : %s)" % (
             plugin.getDescription().getName(), messageId, messageStr))
 
-    def __onPluginMessage(self, plugin, instanceParameters, message):
-        uuid = plugin.getDescription().getUuid()
-        locutor = instanceParameters['locutor']
-        pitch = instanceParameters['pitch']
+    def __onPluginMessage(self, pluginInterpreterContext, message):
+        locutor = pluginInterpreterContext.getInstanceParameters()['locutor']
+        pitch = pluginInterpreterContext.getInstanceParameters()['pitch']
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logDebug("Plugin MESSAGE [%s] (%s)" % (
             plugin.getDescription().getName(), message))
-        self.__pushPluginMessageInTtsStack(uuid, message, locutor, int(pitch))
+        resourceRobotContentInteractions.getPguContextsManager().insertMessage(
+            pluginInterpreterContext,
+            message,
+            locutor,
+            int(pitch)
+        )
 
-    def __onPluginError(self, plugin, instanceParameters, *messagesList):
+    def __onPluginError(self, pluginInterpreterContext, *messagesList):
         messageStr = ""
         for message in messagesList:
             messageStr += message
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logError("Plugin ERROR [%s] (%s)" % (
             plugin.getDescription().getName(), messageStr))
 
-    def __onPluginTrace(self, plugin, instanceParameters, *messagesList):
+    def __onPluginTrace(self, pluginInterpreterContext, *messagesList):
         messageStr = ""
         for message in messagesList:
             messageStr += message
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logDebug("Plugin TRACE [%s] (%s)" % (
             plugin.getDescription().getName(), messageStr))
 
-    def __onPluginResult(self, plugin, instanceParameters, pluginResult):
+    def __onPluginResult(self, pluginInterpreterContext, pluginResult):
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logDebug("Plugin RESULT [%s] (%s)" % (
             plugin.getDescription().getName(), str(pluginResult)))
 
-    def __onPluginActuation(self, plugin, instanceParameters, *messagesList):
+    def __onPluginActuation(self, pluginInterpreterContext, *messagesList):
         messageStr = ""
         for message in messagesList:
             messageStr += " " + message
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logDebug("Plugin ACTUATION [%s] (%s)" % (
             plugin.getDescription().getName(), messageStr))
+        actuationName = messagesList[0]
+        arguments = messagesList[1:]
+        
resourceRobotContentInteractions.getPguContextsManager().insertActuation(
+            pluginInterpreterContext,
+            actuationName,
+            arguments
+        )
 
-    def __onPluginStarting(self, plugin, instanceParameters, instanceCommand,
-        instanceIsDaemon):
-        uuid = plugin.getDescription().getUuid()
+    def __onPluginStarting(self, pluginInterpreterContext):
+        plugin = pluginInterpreterContext.getParentPlugin()
         self.logger.logInfo("Plugin starting [%s] (%s)" % (
-            plugin.getDescription().getName(), str(instanceParameters)))
-        self.__pluginStopEventFromStartEvent(uuid)
+            plugin.getDescription().getName(),
+            str(pluginInterpreterContext.getInstanceParameters())))
+        
resourceRobotContentInteractions.getPguContextsManager().createPguContext(
+            pluginInterpreterContext)
 
-    def __onPluginStopped(self, plugin, instanceParameters, instanceCommand,
-        instanceIsDaemon):
-        uuid = plugin.getDescription().getUuid()
-        if instanceIsDaemon:
-            self.logger.logInfo("Plugin stopped [%s]" % (
+    def __onPluginStopped(self, pluginInterpreterContext):
+        
resourceRobotContentInteractions.getPguContextsManager().setContextIsComplete(
+            pluginInterpreterContext)
+        plugin = pluginInterpreterContext.getParentPlugin()
+        self.logger.logInfo("Plugin stopped [%s]" % (
                 plugin.getDescription().getName()))
-        else:
-            pass
 
     # 
--------------------------------------------------------------------------
     # Private methods
     # 
--------------------------------------------------------------------------
 
-    def __pushPluginMessageInTtsStack(self, uuid, message, locutor, pitch):
-        resourceTTS.stackPush(message, locutor, pitch, uuid)
-
-    def __pluginStopEventFromStartEvent(self, uuid):
-        plugin = self.__pluginsContainer.getPluginByUuid(uuid)
-        if plugin == None:
-            return
-        if plugin.instanceIsDaemon():
-            return
-        def async():
-            pluginName = plugin.getDescription().getName()
-            if not resourceTTS.stackIsFilled(uuid):
-                time.sleep(0.5)
-                if not resourceTTS.stackIsFilled(uuid):
-                    if not 
eventsHandler.waitCondition(ST_NAME_TTS_STACK_FILLING,
-                        (uuid, None), 10.0):
-                        self.logger.logInfo("Plugin stopped [%s]" % pluginName)
-                        # Event plugin stop
-                        return
-            eventsHandler.waitCondition(ST_NAME_TTS_STACK_EMPTY, (uuid, None),
-                600.0)
-            self.logger.logInfo("Plugin stopped [%s]" % pluginName)
-            # Event plugin stop
-        t = threading.Thread(target = async)
-        t.start()
-
     def __publishEvents(self, sendToClients, eventName, eventValues = []):
         def async():
             values = ""

Modified: 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/03_resourceUgcServer.py
===================================================================
--- 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/03_resourceUgcServer.py
        2009-06-09 12:26:04 UTC (rev 4759)
+++ 
software_suite_v3/smart-core/smart-server/trunk/resources/03_content_servers/03_resourceUgcServer.py
        2009-06-09 12:29:13 UTC (rev 4760)
@@ -74,6 +74,8 @@
             ugc.getDescription().getName(), ugcFile))
         self.__publishEvents(False, ST_NAME_US_UGC_LOADED, [uuid,])
         self.insertAlertsInScheduler(ugc)
+        if ugc.getDescription().onDemandIsActivated() == "true":
+            
resourceRobotContentInteractions.getPguContextsManager().insertOnDemand(ugc)
 
     def __onUgcDeploymentError(self, observerName, ugcFile, message):
         messagesList = [
@@ -94,6 +96,7 @@
             ugc.getDescription().getName(), ugcFile))
         self.__publishEvents(False, ST_NAME_US_UGC_UNLOADED, [uuid,])
         self.deleteAlertsFromScheduler(ugc)
+        
resourceRobotContentInteractions.getPguContextsManager().removeOnDemand(ugc)
 
     # 
--------------------------------------------------------------------------
     # Private methods

Added: 
software_suite_v3/smart-core/smart-server/trunk/resources/04_robot_content_interactions/00_resourceRobotContentInteractions.py
===================================================================
--- 
software_suite_v3/smart-core/smart-server/trunk/resources/04_robot_content_interactions/00_resourceRobotContentInteractions.py
                              (rev 0)
+++ 
software_suite_v3/smart-core/smart-server/trunk/resources/04_robot_content_interactions/00_resourceRobotContentInteractions.py
      2009-06-09 12:29:13 UTC (rev 4760)
@@ -0,0 +1,775 @@
+#    Copyright (C) 2009 C2ME Sa
+#    Remi Jocaille <[email protected]>
+#    Distributed under the terms of the GNU General Public License
+#    http://www.gnu.org/copyleft/gpl.html
+
+import time
+
+PGU_CONTEXT_LAYER_USER = 0
+PGU_CONTEXT_LAYER_SCHEDULER = 1
+
+PGU_EVENT_TYPE_MESSAGE = 0
+PGU_EVENT_TYPE_ACTUATION = 1
+PGU_EVENT_TYPE_ATTITUNE = 2
+
+class PguContext(object):
+    """
+    """
+
+    def __init__(self, pluginInterpreterContext):
+        """
+        """
+        self.__createTime = time.time()
+        self.__pluginInterpreterContext = pluginInterpreterContext
+        uuid = pluginInterpreterContext.getHostUuid()
+        # Get pguObject
+        self.__pguObject = 
resourcePluginsServer.getPluginsContainer().getPluginByUuid(uuid)
+        if self.__pguObject == None:
+            self.__pguObject = 
resourceGadgetsServer.getGadgetsContainer().getGadgetByUuid(uuid)
+        if self.__pguObject == None:
+            self.__pguObject = 
resourceUgcServer.getUgcContainer().getUgcByUuid(uuid)
+        # Get context layer
+        self.__contextLayer = PGU_CONTEXT_LAYER_USER
+        if 
self.__pluginInterpreterContext.getInstanceParameters().has_key("startedBy"):
+            if 
self.__pluginInterpreterContext.getInstanceParameters()['startedBy'] == 
'scheduler':
+                self.__contextLayer = PGU_CONTEXT_LAYER_SCHEDULER
+        self.__eventStack = []
+        self.__eventStackMutex = threading.Lock()
+        self.__contextComplete = False
+        self.__contextCompleteMutex = threading.Lock()
+        self.__startStopPauseMutex = threading.Lock()
+        self.__execStarted = False
+        self.__execPaused = False
+
+    def getPluginInterpreterContext(self):
+        """
+        """
+        return self.__pluginInterpreterContext
+
+    def getPguUuid(self):
+        """
+        """
+        return self.__pluginInterpreterContext.getHostUuid()
+
+    def getPguName(self):
+        """
+        """
+        return self.__pguObject.getDescription().getName()
+
+    def getContextLayer(self):
+        """
+        """
+        return self.__contextLayer
+
+    def getPguObject(self):
+        """
+        """
+        return self.__pguObject
+
+    def isDaemon(self):
+        """
+        """
+        return self.__pluginInterpreterContext.instanceIsDaemon()
+
+    def getPluginCommand(self):
+        """
+        """
+        return self.__pguObject.getCommand(
+            self.__pluginInterpreterContext.getInstanceCommandName())
+
+    def setContextIsComplete(self):
+        """
+        """
+        if not self.contextIsComplete():
+            print "PGU Context [%s] content is complete" % self.getPguName()
+            self.__contextCompleteMutex.acquire()
+            self.__contextComplete = True
+            self.__contextCompleteMutex.release()
+
+    def contextIsComplete(self):
+        """
+        """
+        self.__contextCompleteMutex.acquire()
+        result = self.__contextComplete
+        self.__contextCompleteMutex.release()
+        return result
+
+    def __insertEvent(self, eventType, arguments = {}):
+        """
+        """
+        if self.contextIsComplete():
+            return
+        self.__eventStackMutex.acquire()
+        self.__eventStack.append({
+            'type' : eventType,
+            'arguments' : arguments,
+        })
+        self.__eventStackMutex.release()
+        print "Inserted event in PGU context [%s] :" % self.getPguName()
+        print "   ", eventType
+        print "   ", arguments
+
+    def __getEvent(self):
+        """
+        """
+        self.__eventStackMutex.acquire()
+        result = None
+        if len(self.__eventStack) > 0:
+            result = self.__eventStack.pop(0)
+        self.__eventStackMutex.release()
+        return result
+
+    def insertMessage(self, message, locutor, pitch):
+        """
+        """
+        self.__insertEvent(PGU_EVENT_TYPE_MESSAGE, {
+            'message' : message,
+            'locutor' : locutor,
+            'pitch' : pitch,
+        })
+
+    def insertActuation(self, actuationName, arguments = []):
+        """
+        """
+        self.__insertEvent(PGU_EVENT_TYPE_ACTUATION, {
+            'actuationName' : actuationName,
+            'actuationArguments' : arguments,
+        })
+
+    def insertAttitune(self, attituneName):
+        """
+        """
+        self.__insertEvent(PGU_EVENT_TYPE_ATTITUNE, {
+            'attituneName' : attituneName,
+        })
+
+    def startExecution(self):
+        """
+        """
+        if self.executionIsStarted():
+            return
+        expirationDelay = self.getPluginCommand().getExpirationDelay()
+        if expirationDelay > 0:
+            if (time.time() - self.__createTime) > expirationDelay:
+                return
+        self.__startStopPauseMutex.acquire()
+        self.__execStarted = True
+        self.__execPaused = False
+        self.__startStopPauseMutex.release()
+        print "Start execution of PGU context [%s]" % self.getPguName()
+        self.__executionLoop()
+
+    def executionIsStarted(self):
+        """
+        """
+        self.__startStopPauseMutex.acquire()
+        result = self.__execStarted
+        self.__startStopPauseMutex.release()
+        return result
+
+    def stopExecution(self):
+        """
+        """
+        self.__pluginInterpreterContext.abort()
+        if not self.executionIsStarted():
+            return
+        print "Stop execution of PGU context [%s]" % self.getPguName()
+        self.__startStopPauseMutex.acquire()
+        self.__execStarted = False
+        self.__execPaused = False
+        self.__startStopPauseMutex.release()
+        self.__breakAttitune()
+        self.__breakMessage()
+        self.__breakActuation()
+        print "Execution of PGU context [%s] stopped" % self.getPguName()
+        if self.getContextLayer() == PGU_CONTEXT_LAYER_SCHEDULER:
+            resourceTuxDriver.playSound(15, 100.0)
+        else:
+            resourceTuxDriver.playSound(16, 100.0)
+        time.sleep(0.5)
+
+    def pauseExecution(self):
+        """
+        """
+        if not self.executionIsStarted():
+            return
+        if self.executionIsPaused():
+            return
+        print "Pause execution of PGU context [%s]" % self.getPguName()
+        self.__startStopPauseMutex.acquire()
+        self.__execPaused = True
+        self.__startStopPauseMutex.release()
+        self.__breakAttitune()
+        self.__breakMessage()
+        self.__breakActuation()
+
+    def unpauseExecution(self):
+        """
+        """
+        if not self.executionIsStarted():
+            return
+        if not self.executionIsPaused():
+            return
+        print "Unpause execution of PGU context [%s]" % self.getPguName()
+        self.__startStopPauseMutex.acquire()
+        self.__execPaused = False
+        self.__startStopPauseMutex.release()
+
+    def executionIsPaused(self):
+        """
+        """
+        self.__startStopPauseMutex.acquire()
+        result = self.__execPaused
+        self.__startStopPauseMutex.release()
+        return result
+
+
+    def __executeAttitune(self, attituneName):
+        """
+        """
+        resourceAttituneManager.playAttituneSync(attituneName, 0.0)
+
+    def __breakAttitune(self):
+        """
+        """
+        resourceAttituneManager.stopAttitune()
+
+    def __executeMessage(self, text, locutor, pitch):
+        """
+        """
+        resourceTuxDriver.openMouth()
+        resourceTuxOSL.ttsSpeak(text, locutor, pitch)
+        if not eventsHandler.waitCondition(ST_NAME_TTS_SOUND_STATE, ("ON",
+            None), 3.0):
+            return
+        eventsHandler.waitCondition(ST_NAME_TTS_SOUND_STATE, ("OFF", None),
+            600.0)
+        resourceTuxDriver.closeMouth()
+
+    def __breakMessage(self):
+        """
+        """
+        resourceTuxOSL.ttsStop()
+
+    def __executeActuation(self, actuationName, arguments):
+        """
+        """
+        argsString = ""
+        for argument in arguments:
+            if len(argsString) > 0:
+                argsString += ","
+            try:
+                argument = int(argument)
+                argsString += str(argument)
+            except:
+                try:
+                    argument = float(argument)
+                    argsString += str(argument)
+                except:
+                    argsString += '"' + str(argument) + '"'
+        cmdString = "resourceTuxDriver.%s(%s)" % (actuationName, argsString)
+        try:
+            exec(cmdString) in globals()
+        except:
+            print "!!! Error in command :", cmdString
+
+    def __breakActuation(self):
+        """
+        """
+        resourceTuxDriver.clearAll()
+
+    def __executionLoop(self):
+        """
+        """
+        if self.getContextLayer() == PGU_CONTEXT_LAYER_SCHEDULER:
+            resourceTuxDriver.playSound(14, 100.0)
+        else:
+            resourceTuxDriver.playSound(13, 100.0)
+        time.sleep(0.5)
+        while self.executionIsStarted():
+            while self.executionIsPaused():
+                time.sleep(0.1)
+            nextEvent = self.__getEvent()
+            if nextEvent == None:
+                if self.contextIsComplete():
+                    self.__startStopPauseMutex.acquire()
+                    self.__execStarted = False
+                    self.__execPaused = False
+                    self.__startStopPauseMutex.release()
+                    print "Execution of PGU context [%s] stopped" % 
self.getPguName()
+                    if self.getContextLayer() == PGU_CONTEXT_LAYER_SCHEDULER:
+                        resourceTuxDriver.playSound(15, 100.0)
+                    else:
+                        resourceTuxDriver.playSound(16, 100.0)
+                    time.sleep(0.5)
+                    return
+            else:
+                print "Execute event from PGU context [%s] :" % 
self.getPguName()
+                print "   ", nextEvent['type']
+                print "   ", nextEvent['arguments']
+                arguments = nextEvent['arguments']
+                if nextEvent['type'] == PGU_EVENT_TYPE_MESSAGE:
+                    self.__executeMessage(arguments['message'],
+                        arguments['locutor'], arguments['pitch'])
+                elif nextEvent['type'] == PGU_EVENT_TYPE_ACTUATION:
+                    self.__executeActuation(arguments['actuationName'],
+                        arguments['actuationArguments'])
+                elif nextEvent['type'] == PGU_EVENT_TYPE_ATTITUNE:
+                    self.__executeAttitune(arguments['attituneName'])
+                print "Event finished"
+            time.sleep(0.1)
+
+class PguContextsManager(object):
+    """
+    """
+
+    def __init__(self):
+        """
+        """
+        self.__pguContexts = []
+        self.__pguContextsMutex = threading.Lock()
+        self.__backgroundPguContext = None
+        self.__foregroundPguContext = None
+        self.__backgroundPguThread = None
+        self.__bfPguContextMutex = threading.Lock()
+        self.__isStarted = False
+        self.__startedMutex = threading.Lock()
+        self.__loopThread = None
+        self.__onDemandList = []
+        self.__onDemandIndex = 0
+
+    def insertOnDemand(self, ugc):
+        """
+        """
+        self.__onDemandList.append(ugc)
+
+    def removeOnDemand(self, ugc):
+        """
+        """
+        for odUgc in self.__onDemandList:
+            if odUgc == ugc:
+                self.__onDemandList.remove(ugc)
+                return
+
+    def __speakOnDemand(self):
+        """
+        """
+        if len(self.__onDemandList) > 0:
+            resourceTuxOSL.ttsStop()
+            ugc = self.__onDemandList[self.__onDemandIndex]
+            ugcTtsName = ugc.getDescription().getName()
+            locutor = resourcePluginsServer.getPluginsContainer().getLocutor()
+            pitch = resourcePluginsServer.getPluginsContainer().getPitch()
+            resourceTuxDriver.openMouth()
+            resourceTuxOSL.ttsSpeak(ugcTtsName, locutor, pitch)
+            if not eventsHandler.waitCondition(ST_NAME_TTS_SOUND_STATE, ("ON",
+                None), 3.0):
+                return
+            eventsHandler.waitCondition(ST_NAME_TTS_SOUND_STATE, ("OFF", None),
+                600.0)
+            resourceTuxDriver.closeMouth()
+
+    def __onDemandNext(self):
+        """
+        """
+        self.__onDemandIndex += 1
+        if self.__onDemandIndex >= len(self.__onDemandList):
+            self.__onDemandIndex = 0
+        resourceTuxDriver.playSound(11, 100.0)
+        self.__speakOnDemand()
+
+    def __onDemandPrevious(self):
+        """
+        """
+        self.__onDemandIndex -= 1
+        if self.__onDemandIndex < 0:
+            self.__onDemandIndex = len(self.__onDemandList) - 1
+        resourceTuxDriver.playSound(11, 100.0)
+        self.__speakOnDemand()
+
+    def __setStarted(self, value):
+        """
+        """
+        self.__startedMutex.acquire()
+        self.__isStarted = value
+        self.__startedMutex.release()
+
+    def isStarted(self):
+        """
+        """
+        self.__startedMutex.acquire()
+        result = self.__isStarted
+        self.__startedMutex.release()
+        return result
+
+    def start(self):
+        """
+        """
+        self.__loopThread = threading.Thread(target = self.__executionLoop)
+        self.__loopThread.start()
+
+    def stop(self):
+        """
+        """
+        self.__setStarted(False)
+        if self.getForegroundPguContext() != None:
+            self.getForegroundPguContext().stopExecution()
+        if self.__loopThread != None:
+            if self.__loopThread.isAlive():
+                self.__loopThread.join()
+
+    def mute(self):
+        """
+        """
+        pass
+
+    def unmute(self):
+        """
+        """
+        pass
+
+    def __executionLoop(self):
+        """
+        """
+        self.__setStarted(True)
+        while self.isStarted():
+            # Get the next pguContext which must be in foreground
+            pguContext = None
+            self.__pguContextsMutex.acquire()
+            if len(self.__pguContexts) > 0:
+                pguContext = self.__pguContexts.pop(0)
+            if pguContext != None:
+                self.__setForegroundPguContext(pguContext)
+                self.__pguContextsMutex.release()
+                if self.getBackgroundPguContext() != None:
+                    # If the context is exclusive then stop the background 
context
+                    if 
self.getForegroundPguContext().getPluginCommand().isExclusive():
+                        self.getBackgroundPguContext().stopExecution()
+                    # Else only pause-it
+                    else:
+                        self.getBackgroundPguContext().pauseExecution()
+                self.getForegroundPguContext().startExecution()
+                if self.getBackgroundPguContext() != None:
+                    # Unpause background context
+                    if not 
self.getForegroundPguContext().getPluginCommand().isExclusive():
+                        self.getBackgroundPguContext().unpauseExecution()
+                self.__setForegroundPguContext(None)
+            else:
+                self.__pguContextsMutex.release()
+            time.sleep(0.5)
+
+    def createPguContext(self, pluginInterpreterContext):
+        """
+        """
+        # Create new pguContext
+        pguContext = PguContext(pluginInterpreterContext)
+        # Add the new pguContext in the system
+        self.__insertPguContext(pguContext)
+
+    def __startBackgroundPguContext(self):
+        """
+        """
+        if self.getBackgroundPguContext().getPluginCommand().isCritical():
+            self.stop()
+        self.getBackgroundPguContext().startExecution()
+        if self.getBackgroundPguContext().getPluginCommand().isCritical():
+            self.start()
+
+    def __insertPguContext(self, pguContext):
+        """
+        """
+        # Alerts and no daemon user calls must be inserted in the stack
+        # as foreground.
+        if (pguContext.getContextLayer() == PGU_CONTEXT_LAYER_SCHEDULER) or\
+            (not pguContext.isDaemon()):
+            self.__pguContextsMutex.acquire()
+            for i, regPguContext in enumerate(self.__pguContexts):
+                if regPguContext.getPluginCommand() == 
pguContext.getPluginCommand():
+                    # Replace the context with the same plugin command.
+                    self.__pguContexts[i] = pguContext
+                    self.__pguContextsMutex.release()
+                    return
+            # If the context command is critical and the context is run by the
+            # scheduler then stop the current context and add the context on 
top
+            # of the stack
+            if (pguContext.getPluginCommand().isCritical()) and \
+                (pguContext.getContextLayer() == PGU_CONTEXT_LAYER_SCHEDULER):
+                self.__pguContexts.insert(0, pguContext)
+                if self.getForegroundPguContext() != None:
+                    self.getForegroundPguContext().stopExecution()
+            # Add the new context at the bottom of the stack.
+            else:
+                self.__pguContexts.append(pguContext)
+            self.__pguContextsMutex.release()
+        # Daemon user calls must be referenced as background.
+        else:
+            currentBackgroundPguContext = self.getBackgroundPguContext()
+            if currentBackgroundPguContext != None:
+                # Stop old background context if exists
+                currentBackgroundPguContext.stopExecution()
+                if self.__backgroundPguThread != None:
+                    if self.__backgroundPguThread.isAlive():
+                        self.__backgroundPguThread.join()
+            self.__setBackgroundPguContext(pguContext)
+            self.__backgroundPguThread = threading.Thread(target = 
self.__startBackgroundPguContext)
+            self.__backgroundPguThread.start()
+
+    def getForegroundPguContext(self):
+        """
+        """
+        self.__bfPguContextMutex.acquire()
+        result = self.__foregroundPguContext
+        self.__bfPguContextMutex.release()
+        return result
+
+    def getBackgroundPguContext(self):
+        """
+        """
+        self.__bfPguContextMutex.acquire()
+        result = self.__backgroundPguContext
+        self.__bfPguContextMutex.release()
+        return result
+
+    def __setForegroundPguContext(self, pguContext):
+        """
+        """
+        self.__bfPguContextMutex.acquire()
+        self.__foregroundPguContext = pguContext
+        self.__bfPguContextMutex.release()
+
+    def __setBackgroundPguContext(self, pguContext):
+        """
+        """
+        self.__bfPguContextMutex.acquire()
+        self.__backgroundPguContext = pguContext
+        self.__bfPguContextMutex.release()
+
+    def getPguContext(self, pluginInterpreterContext):
+        """
+        """
+        result = None
+        self.__pguContextsMutex.acquire()
+        for pguContext in self.__pguContexts:
+            if pguContext.getPluginInterpreterContext() == 
pluginInterpreterContext:
+                result = pguContext
+                break
+        if result == None:
+            if self.getForegroundPguContext() != None:
+                if 
self.getForegroundPguContext().getPluginInterpreterContext() == 
pluginInterpreterContext:
+                    result = self.getForegroundPguContext()
+        if result == None:
+            if self.getBackgroundPguContext() != None:
+                if 
self.getBackgroundPguContext().getPluginInterpreterContext() == 
pluginInterpreterContext:
+                    result = self.getBackgroundPguContext()
+        self.__pguContextsMutex.release()
+        return result
+
+    # 
==========================================================================
+    # Events from plugins execution.
+    # 
==========================================================================
+
+    def insertMessage(self, pluginInterpreterContext, message, locutor, pitch):
+        """
+        """
+        pguContext = self.getPguContext(pluginInterpreterContext)
+        if pguContext != None:
+            pguContext.insertMessage(message, locutor, pitch)
+
+    def insertActuation(self, pluginInterpreterContext, actuationName,
+        arguments = []):
+        """
+        """
+        pguContext = self.getPguContext(pluginInterpreterContext)
+        if pguContext != None:
+            pguContext.insertActuation(actuationName, arguments)
+
+    def insertAttitune(self, pluginInterpreterContext, attituneName):
+        """
+        """
+        pguContext = self.getPguContext(pluginInterpreterContext)
+        if pguContext != None:
+            pguContext.insertAttitune(attituneName)
+
+    def setContextIsComplete(self, pluginInterpreterContext):
+        """
+        """
+        pguContext = self.getPguContext(pluginInterpreterContext)
+        if pguContext != None:
+            pguContext.setContextIsComplete()
+
+    # 
==========================================================================
+    # Remote and robot button events
+    # 
==========================================================================
+
+    def __contextBtRunAbort(self):
+        """
+        """
+        # Abort foreground context if exists
+        if self.getForegroundPguContext() != None:
+            if self.getForegroundPguContext().executionIsStarted():
+                self.getForegroundPguContext().stopExecution()
+                return
+        # Else abort background context if exists
+        if self.getBackgroundPguContext() != None:
+            if self.getBackgroundPguContext().executionIsStarted():
+                self.getBackgroundPguContext().stopExecution()
+                return
+        # Else load current selected on demand gadget
+        if len(self.__onDemandList) > 0:
+            ugc = self.__onDemandList[self.__onDemandIndex]
+            ugc.start(ugc.getDefaultRunCommandName())
+
+    def __contextLTPrevious(self, eventName, *args):
+        """
+        """
+        if self.getForegroundPguContext() != None:
+            return
+        if self.getBackgroundPguContext() != None:
+            if self.getBackgroundPguContext().executionIsStarted():
+                self.__contextBtOther(eventName, *args)
+                return
+        self.__onDemandPrevious()
+
+    def __contextRBNext(self, eventName, *args):
+        """
+        """
+        if self.getForegroundPguContext() != None:
+            return
+        if self.getBackgroundPguContext() != None:
+            if self.getBackgroundPguContext().executionIsStarted():
+                self.__contextBtOther(eventName, *args)
+                return
+        self.__onDemandNext()
+
+    def __contextBtMute(self):
+        """
+        """
+        pass
+
+    def __contextBtOther(self, eventName, *args):
+        """
+        """
+        if self.getForegroundPguContext() == None:
+            bgPguContext = self.getBackgroundPguContext()
+            if bgPguContext != None:
+                bgPguContext.getPluginInterpreterContext().sendEvent(eventName,
+                    args)
+
+    def sendEvent(self, eventName, *args):
+        """
+        """
+        def async():
+            if eventName == "head":
+                if args[0] == True:
+                    self.__contextBtRunAbort()
+            elif eventName == "left":
+                if args[0] == True:
+                    self.__contextLTPrevious(eventName, *args)
+            elif eventName == "right":
+                if args[0] == True:
+                    self.__contextRBNext(eventName, *args)
+            elif eventName == "remote":
+                if args[0] == "K_OK":
+                    self.__contextBtRunAbort()
+                elif args[0] == "K_LEFT":
+                    self.__contextLTPrevious(eventName, *args)
+                elif args[0] == "K_TOP":
+                    self.__contextLTPrevious(eventName, *args)
+                elif args[0] == "K_RIGHT":
+                    self.__contextRBNext(eventName, *args)
+                elif args[0] == "K_BOTTOM":
+                    self.__contextRBNext(eventName, *args)
+                else:
+                    self.__contextBtOther(eventName, *args)
+            print eventName, args
+        t = threading.Thread(target = async)
+        t.start()
+
+# 
==============================================================================
+# 
******************************************************************************
+# RESOURCE DECLARATION
+# 
******************************************************************************
+# 
==============================================================================
+
+# 
==============================================================================
+# Declaration of the resource "robot_content_interactions".
+# 
==============================================================================
+class TDSResourceRobotContentInteractions(TDSResource):
+    """Resource robot_content_interactions class.
+    """
+
+    # 
==========================================================================
+    # Inherited methods from TDSResource
+    # 
==========================================================================
+
+    # 
--------------------------------------------------------------------------
+    # Configure the resource.
+    # 
--------------------------------------------------------------------------
+    def configure(self):
+        """Configure the resource.
+        """
+        # General configuration (inherited from ancestor)
+        self.name = "robot_content_interactions"
+        self.comment = "Resource to handling the robot/content interactions."
+        self.fileName = RESOURCE_FILENAME
+        self.__pguContextsManager = PguContextsManager()
+        # Register callback on RC and robot buttons events
+        eventsHandler.getEventHandler(ST_NAME_HEAD_BUTTON).register(
+            self.__onHeadBtEvent)
+        eventsHandler.getEventHandler(ST_NAME_LEFT_BUTTON).register(
+            self.__onLeftBtEvent)
+        eventsHandler.getEventHandler(ST_NAME_RIGHT_BUTTON).register(
+            self.__onRightBtEvent)
+        eventsHandler.getEventHandler(ST_NAME_REMOTE_BUTTON).register(
+            self.__onRCBtEvent)
+
+    # 
--------------------------------------------------------------------------
+    # Start the resource.
+    # 
--------------------------------------------------------------------------
+    def start(self):
+        """Start the resource.
+        """
+        self.__pguContextsManager.start()
+
+    # 
--------------------------------------------------------------------------
+    # Stop the resource.
+    # 
--------------------------------------------------------------------------
+    def stop(self):
+        """Stop the resource.
+        """
+        self.__pguContextsManager.stop()
+
+    def __onHeadBtEvent(self, *args):
+        """
+        """
+        self.__pguContextsManager.sendEvent("head", *args)
+
+    def __onLeftBtEvent(self, *args):
+        """
+        """
+        self.__pguContextsManager.sendEvent("left", *args)
+
+    def __onRightBtEvent(self, *args):
+        """
+        """
+        self.__pguContextsManager.sendEvent("right", *args)
+
+    def __onRCBtEvent(self, *args):
+        """
+        """
+        self.__pguContextsManager.sendEvent("remote", *args)
+
+    # 
==========================================================================
+    # Public methods
+    # 
==========================================================================
+
+    def getPguContextsManager(self):
+        """
+        """
+        return self.__pguContextsManager
+
+# Create an instance of the resource
+resourceRobotContentInteractions = TDSResourceRobotContentInteractions(
+    "resourceRobotContentInteractions")
+# Register the resource into the resources manager
+resourcesManager.addResource(resourceRobotContentInteractions)


------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Tux-droid-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tux-droid-svn

Reply via email to