[Sofaswitch-svn] [commit] r88 - sofaswitch/trunk/callflow/src
Author: derek Date: Wed Sep 13 01:22:35 2006 New Revision: 88 Modified: sofaswitch/trunk/callflow/src/endhere.cpp sofaswitch/trunk/callflow/src/eventer.cpp sofaswitch/trunk/callflow/src/shapelist.cpp sofaswitch/trunk/callflow/src/stoptimer.cpp sofaswitch/trunk/callflow/src/timer.cpp Log: Work on event handling, and get very close to working. Modified: sofaswitch/trunk/callflow/src/endhere.cpp ============================================================================== --- sofaswitch/trunk/callflow/src/endhere.cpp (original) +++ sofaswitch/trunk/callflow/src/endhere.cpp Wed Sep 13 01:22:35 2006 @@ -50,11 +50,14 @@ bool DndShapeEndHere::WriteSystemCode(wxTextFile & file) { file.AddLine(" def End_Processing(self, sTuple): "); - file.AddLine(" self.keepGoing = False"); - file.AddLine(" a,b,c = sTuple"); - file.AddLine(" print \"end of processing at \", a "); - file.AddLine(" return (1,2,3)"); - file.AddLine(""); + file.AddLine(" \"\"\"Terminate processing of this flow chart, by returning a None structure "); + file.AddLine(" Processing on this flow chart may continue if there is an outstanding signal"); + file.AddLine(" handle. "); + file.AddLine(" \"\"\" "); + file.AddLine(" a,b,c = sTuple "); + file.AddLine(" #print \"end of processing at \", a "); + file.AddLine(" return None "); + file.AddLine(" "); return true; } Modified: sofaswitch/trunk/callflow/src/eventer.cpp ============================================================================== --- sofaswitch/trunk/callflow/src/eventer.cpp (original) +++ sofaswitch/trunk/callflow/src/eventer.cpp Wed Sep 13 01:22:35 2006 @@ -83,9 +83,13 @@ bool DndShapeEventer::WriteSystemCode(wxTextFile & file) { file.AddLine(" def Eventer(self, sTuple): "); - file.AddLine(" a,b,c = sTuple"); - file.AddLine(" self.currentHandlers[self.data[a][\"Event\"] = self.data[a][\"Event Handler\"] "); - file.AddLine(" return self.data[a][\"OutputKeepGoing\"] "); + file.AddLine(" \"\"\"Register the left down output as being available to handle a particular event "); + file.AddLine(" After registration, continue execution to right horizontal output. Should this "); + file.AddLine(" link not be connected, a None value will be returned. "); + file.AddLine(" \"\"\" "); + file.AddLine(" a,b,c = sTuple "); + file.AddLine(" self.currentHandlers[self.data[a][\"Event\"]] = a "); + file.AddLine(" return self.data[a][\"OutputKeepGoing\"] "); file.AddLine(""); return true; Modified: sofaswitch/trunk/callflow/src/shapelist.cpp ============================================================================== --- sofaswitch/trunk/callflow/src/shapelist.cpp (original) +++ sofaswitch/trunk/callflow/src/shapelist.cpp Wed Sep 13 01:22:35 2006 @@ -278,22 +278,23 @@ file.AddLine(" "); file.AddLine("import sys "); file.AddLine("import os "); + file.AddLine("import time "); file.AddLine("import socket "); file.AddLine("import distutils "); - file.AddLine("import random "); file.AddLine("from twisted.internet import reactor, protocol "); - file.AddLine(" "); - file.AddLine("class MyEvent(): "); - file.AddLine(" self.name = None "); - file.AddLine(" self.onEvent = None "); /*Go here on receiving event*/ file.AddLine(" "); file.AddLine("class Controller(protocol.Protocol): "); + file.AddLine(" \"\"\" The class which holds all the information on how to manage each entity"); + file.AddLine(" on the flow chart, how to connect, and does the requisite calls to twisted "); + file.AddLine(" "); + file.AddLine(" There are two types of events. A) name,data or B)name,handler "); + file.AddLine(" \"\"\" "); file.AddLine(" def __init__(self): "); file.AddLine(" self.graphSet = False "); file.AddLine(" self.connectionIsMade = False "); file.AddLine(" self.endProgramNow = False "); - file.AddLine(" self.generatedEvents = [] "); - file.AddLine(" self.pendingEvents = [] "); + file.AddLine(" self.generatedEvents = {} "); + file.AddLine(" self.pendingEvents = {} "); file.AddLine(" self.currentHandlers= {} "); char c= 34; wxString tString = wxString::Format(" self.quote = \"\\%c\"", c); @@ -301,68 +302,115 @@ file.AddLine(" "); file.AddLine(" def setGraphData(self, graphFile): "); + file.AddLine(" \"\"\"Read in the file which describes where the flow "); + file.AddLine(" of execution goes, and variables associated with "); + file.AddLine(" associated with each block on the flow chart. "); + file.AddLine(" \"\"\" "); file.AddLine(" self.gd=open(graphFile, \"r\"); "); file.AddLine(" self.gdc=self.gd.read() "); file.AddLine(" self.data = eval(self.gdc) "); file.AddLine(" self.gd.close() "); file.AddLine(" "); file.AddLine(" self.firstNode = None "); + file.AddLine(" self.nextNode = None "); file.AddLine(" for k,v in self.data.iteritems(): "); file.AddLine(" if k[:16] == \"Start_Processing\": "); file.AddLine(" self.firstNode = k "); file.AddLine(" self.nextNode = k "); - file.AddLine(" print \"first node is \", k "); file.AddLine(" break "); file.AddLine(" self.timeout = reactor.callLater(0, self.startTimerExpired, \"graph\")"); + file.AddLine(" "); + file.AddLine(" def startTimerExpired(self, data): "); + file.AddLine(" \"\"\"Called during program initialisation. This provies a "); + file.AddLine(" way of ensuring execution only happens after two asynchronous"); + file.AddLine(" events (connected to server, flow chart initialised) "); + file.AddLine(" \"\"\" "); + file.AddLine(" if data == \"graph\": "); + file.AddLine(" self.graphSet = True "); + file.AddLine(" if data == \"connected\": "); + file.AddLine(" self.connectionIsMade = True "); + file.AddLine(" if self.graphSet and self.connectionIsMade: "); + file.AddLine(" #print \"start processing now \" "); + file.AddLine(" reactor.callLater(0, self.startWorkNow,\"\");"); + file.AddLine(" "); + file.AddLine(" def DeleteThisEvent(self, killEvent): "); + file.AddLine(" \"\"\" Remove a particular event from the pending and generated queue "); + file.AddLine(" This is required when we (for example) have to to stop a timer "); + file.AddLine(" \"\"\" "); + file.AddLine(" if self.pendingEvents.has_key(killEvent): "); + file.AddLine(" self.pendingEvents.pop(killEvent) "); + file.AddLine(" if self.generatedEvents.has_key(killEvent): "); + file.AddLine(" self.generatedEvents.pop(killEvent) "); + file.AddLine(" "); + file.AddLine(" def processQueue(self, data): "); + file.AddLine(" \"\"\"This method is called after an event has been detected"); + file.AddLine(" as happening. It compares the generated events queue with the registered"); + file.AddLine(" handlers, and dispatches execution to the relevant handler "); + file.AddLine(" \"\"\" "); + file.AddLine(" #print \"processQueue\" "); + file.AddLine(" #print \"current handlers \", self.currentHandlers "); + file.AddLine(" #print \"current events \", self.generatedEvents "); + file.AddLine(" #print \"pending events \", self.pendingEvents "); + file.AddLine(" keys = self.generatedEvents.keys() "); + file.AddLine(" for k in range(len(keys)): "); + file.AddLine(" if self.currentHandlers.has_key(keys[k]): "); + file.AddLine(" eventerNode = self.currentHandlers[keys[k]] "); + file.AddLine(" #print \"eventer node is \", eventerNode "); + file.AddLine(" self.DoWork(self.data[eventerNode][\"Event Handler\"])"); + file.AddLine(" self.generatedEvents.pop(keys[k]) "); file.AddLine(" "); - file.AddLine(" def startTimerExpired(self, data): "); - file.AddLine(" if data == \"graph\": "); - file.AddLine(" self.graphSet = True "); - file.AddLine(" if data == \"connected\": "); - file.AddLine(" self.connectionIsMade = True "); - file.AddLine(" if self.graphSet and self.connectionIsMade:"); - file.AddLine(" print \"start processing now \" "); + file.AddLine(" def transferEventToGenerated(self, data): "); + file.AddLine(" \"\"\"An event has happened, and now we need to act on it. Consequently, "); + file.AddLine(" we take it out of the pending list and put it in the process now list"); + file.AddLine(" \"\"\" "); + file.AddLine(" if self.pendingEvents.has_key(data): "); + file.AddLine(" self.generatedEvents[data] = self.pendingEvents.pop(data)"); file.AddLine(" "); - file.AddLine(" def DeleteThisEvent(self, killEvent): "); - file.AddLine(" for i in range(len(self.pendingEvents)): "); - file.AddLine(" if self.pendingEvents[i].name == killEvent: "); - file.AddLine(" self.pendingEvents.pop(i) "); - file.AddLine(" break "); - file.AddLine(" for i in range(len(self.generatedEvents)): "); - file.AddLine(" if self.generatedEvents[i].name == killEvent:"); - file.AddLine(" self.generatedEvents.pop(i) "); - file.AddLine(" break "); - file.AddLine(" "); - - file.AddLine(" def transferEventToGenerated(self, data) "); - file.AddLine(" for i in range(len(self.pendingEvents)) "); - file.AddLine(" if self.pendingEvents[i].name == data:"); - file.AddLine(" self.generatedEvents.append(self.pendingEvents.pop(i)) "); - file.AddLine(" break; "); - file.AddLine(" "); file.AddLine(" def timerObjectExpired(self, data): "); - file.AddLine(" eName= data[0 : (len(data)-8)] "); - file.AddLine(" self.transferEventToGenerated(eName) "); + file.AddLine(" \"\"\"Some timer has expired. Move it from the pending list and place "); + file.AddLine(" it in the active list. Then activate processing so that things move along"); + file.AddLine(" \"\"\" "); + file.AddLine(" #print \"timer object has expired \", data "); + file.AddLine(" self.transferEventToGenerated(data) "); + file.AddLine(" reactor.callLater(0, self.processQueue, 0) "); file.AddLine(" "); - file.AddLine(" def startWorkNow(): "); + file.AddLine(" def startWorkNow(self, notUsed): "); + file.AddLine(" \"\"\" Initiate processing on the flow chart"); + file.AddLine(" \"\"\" "); file.AddLine(" sTuple = \"(\" + self.quote + self.firstNode + self.quote + \", 0, \" +self.quote + \"Start_Processing\" + self.quote + \")\""); file.AddLine(" self.DoWork(eval(sTuple)) "); file.AddLine(" "); file.AddLine(" def DoWork(self, sTuple): "); + file.AddLine(" \"\"\" Call one node in the flow chart, and do the "); + file.AddLine(" work of this node (in a separate method. This "); + file.AddLine(" is called when a)on startup or b)after an event "); + file.AddLine(" \"\"\" "); file.AddLine(" a,b,c = sTuple "); file.AddLine(" "); file.AddLine(" self.keepGoing = True "); file.AddLine(" "); file.AddLine(" while self.keepGoing: "); file.AddLine(" command = \"self.\" + str(c) + \"(\" + str(sTuple) + \")\""); - file.AddLine(" a,b,c = sTuple = eval(command) "); + file.AddLine(" sTuple = eval(command) "); + file.AddLine(" if sTuple == None: "); + file.AddLine(" self.keepGoing = False "); + file.AddLine(" else: "); + file.AddLine(" a,b,c = sTuple "); file.AddLine(" "); file.AddLine(" def makeConnection(self, transport): "); - file.AddLine(" self.connected = 1 "); - file.AddLine(" self.transport = transport "); - file.AddLine(" self.connectionMade() "); + file.AddLine(" \"\"\" A twisted callback that connects to the remote server "); + file.AddLine(" The parameters of the connection (port & address) are set"); + file.AddLine(" elsewhere "); + file.AddLine(" \"\"\" "); + file.AddLine(" self.connected = 1 "); + file.AddLine(" self.transport = transport "); + file.AddLine(" self.connectionMade() "); file.AddLine(" "); file.AddLine(" def connectionMade(self): "); + file.AddLine(" \"\"\"A twisted callback that occurs after we have connected to the remote"); + file.AddLine(" sofa swerver. After connection, we send a qury to the sofa server to obtain"); + file.AddLine(" our sofa identity. "); + file.AddLine(" \"\"\" "); file.AddLine(" self.myId = \"\" "); file.AddLine(" self.countReceived = 0 "); file.AddLine(" self.transport.write(\"?\\0\") "); @@ -370,9 +418,18 @@ file.AddLine(" self.colonChar = \':\' "); file.AddLine(" "); file.AddLine(" def connectionLost(self, reason): "); + file.AddLine(" \"\"\"A twisted callback to tell us the connection to the remote sofa server"); + file.AddLine(" has been lost. Currently, we do nothing with this information. It could be "); + file.AddLine(" used though to connect elsewhere. "); + file.AddLine(" \"\"\" "); file.AddLine(" print \"connection lost\" "); file.AddLine(" "); file.AddLine(" def dataReceived(self, data): "); + file.AddLine(" \"\"\"A twisted callback which happens each time we receive a message from the sofa "); + file.AddLine(" server. This message could be part of the initialisation process. In which case, "); + file.AddLine(" initialise, and activate the next step of initialise. Or, it is an ordinary "); + file.AddLine(" message that has to be processed "); + file.AddLine(" \"\"\" "); file.AddLine(" ssdata = str(data).split(\'\\0\') "); file.AddLine(" for oneMessage in ssdata: "); file.AddLine(" self.countReceived += 1 "); @@ -382,11 +439,18 @@ file.AddLine(" else: "); file.AddLine(" self.processReceivedMessage(oneMessage)"); file.AddLine(" "); - file.AddLine(" def replyNow(self, data):"); - file.AddLine(" self.transport.write(self.tstring) "); + file.AddLine(" def replyNow(self, data): "); + file.AddLine(" \"\"\" Send a premade message to the remote sofa server. This method has to "); + file.AddLine(" send the message only - and not manipulate it in any way "); + file.AddLine(" \"\"\" "); + file.AddLine(" self.transport.write(self.tstring) "); file.AddLine(" "); file.AddLine(" def processReceivedMessage(self, thisMessage): "); - file.AddLine(" print \"Received \", thisMessage "); + file.AddLine(" \"\"\"Handle an ordinary message from the remote sofa server. Break the message up"); + file.AddLine(" turn it into a MyEvent message, and added to the right "); + file.AddLine(" queue. On doing this, spark an event to drive queue processing. "); + file.AddLine(" \"\"\" "); + file.AddLine(" #print \"Received \", thisMessage "); file.AddLine(" "); file.AddLine(" "); @@ -422,7 +486,6 @@ file.AddLine(" p.factory = self "); file.AddLine(" self.myController = p "); file.AddLine(" self.myController.setGraphData(self.myGraphName) "); - file.AddLine(" print 'finished building Protocol' "); file.AddLine(" return p "); file.AddLine(" for key in dir(p): "); file.AddLine(" if '__' not in key: "); Modified: sofaswitch/trunk/callflow/src/stoptimer.cpp ============================================================================== --- sofaswitch/trunk/callflow/src/stoptimer.cpp (original) +++ sofaswitch/trunk/callflow/src/stoptimer.cpp Wed Sep 13 01:22:35 2006 @@ -53,10 +53,10 @@ bool DndShapeStopTimer::WriteSystemCode(wxTextFile & file) { - file.AddLine(" def Timer(self, sTuple): "); - file.AddLine(" killTimer = \"Timer\" + self.data[a][\"Timer label\"]"); - file.AddLine(" self.DeleteThisEvent(killTimer) "); + file.AddLine(" def Stop_Timer(self, sTuple): "); file.AddLine(" a,b,c = sTuple"); + file.AddLine(" killTimer = self.data[a][\"Timer label\"]"); + file.AddLine(" self.DeleteThisEvent(killTimer) "); file.AddLine(" return self.data[a][\"Output\"]"); file.AddLine(""); Modified: sofaswitch/trunk/callflow/src/timer.cpp ============================================================================== --- sofaswitch/trunk/callflow/src/timer.cpp (original) +++ sofaswitch/trunk/callflow/src/timer.cpp Wed Sep 13 01:22:35 2006 @@ -76,12 +76,10 @@ bool DndShapeTimer::WriteSystemCode(wxTextFile & file) { file.AddLine(" def Timer(self, sTuple): "); - file.AddLine(" event = MyEvent "); - file.AddLine(" self.r = repr(random.random())[2:10] "); //Last 8 chars of name are "random" - file.AddLine(" event.name = \"Timer\" + self.data[a][\"Timer label\"] + self.r"); - file.AddLine(" self.pendingEvents.append(event) "); - file.AddLine(" reactor.callLater(self.data[a][\"Timer period\"], self.timerEventExpired, event.name)"); file.AddLine(" a,b,c = sTuple"); + file.AddLine(" eName = self.data[a][\"Timer label\"] "); + file.AddLine(" self.pendingEvents[eName] = a "); + file.AddLine(" reactor.callLater(self.data[a][\"Timer period\"], self.timerObjectExpired, eName)"); file.AddLine(" return self.data[a][\"Output\"]"); file.AddLine("");
participants (1)
-
SofaSWITCH SVN