浏览代码

changed event_queue to use heapq methods

Simon Van Mierlo 9 年之前
父节点
当前提交
30b8dc0157

+ 6 - 4
src/python_sccd/python_sccd_runtime/event_queue.py

@@ -1,8 +1,10 @@
 from sccd.runtime.infinity import INFINITY
+from heapq import heappush, heappop
 
 class EventQueue(object):
     def __init__(self):
         self.event_list = []
+        self.event_time_numbers = {}
     
     def __str__(self):
         return str(self.event_list)
@@ -13,13 +15,13 @@ class EventQueue(object):
     def getEarliestTime(self):
         return INFINITY if self.isEmpty() else self.event_list[0][0]
     
-    def add(self, event):
-        self.event_list.append(event)
-        self.event_list.sort(key=lambda i: i[0])
+    def add(self, event_time, event):
+        self.event_time_numbers[event_time] = self.event_time_numbers.setdefault(event_time, 0) + 1
+        heappush(self.event_list, (event_time + self.event_time_numbers[event_time], event))
         return id(event)
     
     def remove(self, event_id):
         self.event_list = sorted([e for e in self.event_list if id(e) != event_id])
     
     def pop(self):
-        return self.event_list.pop(0)[1]
+        return heappop(self.event_list)[1]

+ 11 - 16
src/python_sccd/python_sccd_runtime/statecharts_core.py

@@ -81,9 +81,15 @@ class ObjectManagerBase(object):
         self.instance_times = []
         self.eventless = set()
         self.regex_pattern = re.compile("^([a-zA-Z_]\w*)(?:\[(\d+)\])?$")
+        self.handlers = {"narrow_cast": self.handleNarrowCastEvent,
+                         "broad_cast": self.handleBroadCastEvent,
+                         "create_instance": self.handleCreateEvent,
+                         "associate_instance": self.handleAssociateEvent,
+                         "start_instance": self.handleStartInstanceEvent,
+                         "delete_instance": self.handleDeleteInstanceEvent}
         
     def addEvent(self, event, time_offset = 0):
-        self.events.add((self.controller.simulated_time + time_offset, event))
+        self.events.add(self.controller.simulated_time + time_offset, event)
         
     # broadcast an event to all instances
     def broadcast(self, new_event, time_offset = 0):
@@ -113,18 +119,7 @@ class ObjectManagerBase(object):
             i.start()          
                
     def handleEvent(self, e):
-        if e.getName() == "narrow_cast" :
-            self.handleNarrowCastEvent(e.getParameters())            
-        elif e.getName() == "broad_cast" :
-            self.handleBroadCastEvent(e.getParameters())            
-        elif e.getName() == "create_instance" :
-            self.handleCreateEvent(e.getParameters())            
-        elif e.getName() == "associate_instance" :
-            self.handleAssociateEvent(e.getParameters())            
-        elif e.getName() == "start_instance" :
-            self.handleStartInstanceEvent(e.getParameters())            
-        elif e.getName() == "delete_instance" :
-            self.handleDeleteInstanceEvent(e.getParameters())
+        self.handlers[e.getName()](e.getParameters())
             
     def processAssociationReference(self, input_string):
         if len(input_string) == 0 :
@@ -380,7 +375,7 @@ class ControllerBase(object):
             if e.getPort() not in self.input_ports :
                 raise InputException("Input port mismatch, no such port: " + e.getPort() + ".")
             
-            self.input_queue.add(((0 if self.simulated_time is None else accurate_time.time()) + time_offset, e))
+            self.input_queue.add((0 if self.simulated_time is None else accurate_time.time()) + time_offset, e)
 
     def getEarliestEventTime(self):
         return min(self.object_manager.getEarliestEventTime(), self.input_queue.getEarliestTime())
@@ -869,7 +864,7 @@ class RuntimeClassBase(object):
         if not isinstance(event_list, list):
             event_list = [event_list]
         for e in event_list:
-            self.events.add((event_time, e))
+            self.events.add(event_time, e)
 
     def processBigStepOutput(self):
         for e in self.big_step.output_events_port:
@@ -897,7 +892,7 @@ class RuntimeClassBase(object):
             is_stable = not self.bigStep(due)
             self.processBigStepOutput()
         for index, entry in self.timers_to_add.iteritems():
-            self.timers[index] = self.events.add(entry)
+            self.timers[index] = self.events.add(*entry)
         self.timers_to_add = {}
         self.__set_stable(True)
 

+ 2 - 2
test/src/original_semantics/after_0.xml

@@ -50,11 +50,12 @@
 
         <scxml initial="z">
             <state id="z">
-                <transition after="0" target=".">
+                <transition after="0" target="../closed">
                     <raise scope="broad" event="close"/>
                     <raise event="after_0" port="test_output" />
                 </transition>
             </state>
+            <state id="closed" />
         </scxml>
     </class>
     <test>
@@ -70,7 +71,6 @@
            </slot>
            <slot>
                <event name="deleting_instance" port="test_output"/>
-               <event name="after_0" port="test_output"/>
            </slot>
         </expected>
     </test>