|
|
@@ -1,3 +1,4 @@
|
|
|
+import sys
|
|
|
import time
|
|
|
import threading
|
|
|
from . import naivelog
|
|
|
@@ -99,6 +100,8 @@ class Simulator:
|
|
|
|
|
|
self.__lasttime = None
|
|
|
|
|
|
+ self.__event_bus = []
|
|
|
+ # self.__event_thread = threading.Thread(target=self.__event_thread_loop)
|
|
|
self.__events = {
|
|
|
"started": [],
|
|
|
"finished": [],
|
|
|
@@ -144,6 +147,11 @@ class Simulator:
|
|
|
self.__realtime_start_time = time.time()
|
|
|
self.__lasttime = 0.0
|
|
|
|
|
|
+ # self.__event_thread.start()
|
|
|
+ # self.__threading_backend.wait(0, self.__event_thread_loop)
|
|
|
+ # self.__event_thread_loop()
|
|
|
+ self.__threading_backend_args[0].after(3000, lambda: print("hey"))
|
|
|
+ self.__threading_backend.wait(2, lambda: print("ho"))
|
|
|
self.signal("started")
|
|
|
if self.__realtime:
|
|
|
# Force execute the first iteration now. This way iteration n (n > 0) is
|
|
|
@@ -161,12 +169,13 @@ class Simulator:
|
|
|
"""
|
|
|
Terminate the simulation.
|
|
|
"""
|
|
|
- self.__finished = True
|
|
|
if not self.__progress:
|
|
|
# Whenever the progress bar is initialized, wait until it ends
|
|
|
self.__progress_finished = True
|
|
|
self.__tracer.stopTracers()
|
|
|
self.signal("finished")
|
|
|
+ self.__finished = True
|
|
|
+ # self.__event_thread.join()
|
|
|
|
|
|
def __check(self):
|
|
|
"""
|
|
|
@@ -179,7 +188,7 @@ class Simulator:
|
|
|
"""
|
|
|
ret = self.__stop_requested
|
|
|
if self.__termination_condition is not None:
|
|
|
- ret = self.__termination_condition(self.model, self.__sim_data[2])
|
|
|
+ ret = ret or self.__termination_condition(self.model, self.__sim_data[2])
|
|
|
return ret or self.__termination_time <= self.getTime()
|
|
|
|
|
|
def stop(self):
|
|
|
@@ -398,6 +407,13 @@ class Simulator:
|
|
|
self.__threading_backend_subsystem = subsystem
|
|
|
self.__threading_backend_args = args
|
|
|
|
|
|
+ # TODO: allow the user to also do things here?
|
|
|
+ # if subsystem == Platform.TKINTER:
|
|
|
+ # def cls(s, t):
|
|
|
+ # s.__finish()
|
|
|
+ # t.destroy()
|
|
|
+ # args[0].protocol("WM_DELETE_WINDOW", lambda a=self, b=args[0]: cls(a, b))
|
|
|
+
|
|
|
def setRealTimePlatformThreading(self):
|
|
|
"""
|
|
|
Wrapper around the :func:`setRealTimePlatform` call to automatically
|
|
|
@@ -480,7 +496,8 @@ class Simulator:
|
|
|
"""
|
|
|
self.signal("prestep")
|
|
|
curIt = self.__sim_data[2]
|
|
|
- self.__tracer.traceNewIteration(curIt, self.getTime())
|
|
|
+ # self.__threading_backend.wait(10, lambda: self.__tracer.traceNewIteration(curIt, self.getTime()))
|
|
|
+
|
|
|
# Efficiency reasons: dep graph only changes at these times
|
|
|
# in the given set of library blocks.
|
|
|
# TODO: Must be set to "every time" instead.
|
|
|
@@ -563,7 +580,7 @@ class Simulator:
|
|
|
block = component[0] # the strongly connected component has a single element
|
|
|
if curIteration == 0 or self.__scheduler.mustCompute(block, self.getTime()):
|
|
|
block.compute(curIteration)
|
|
|
- self.__tracer.traceCompute(curIteration, block)
|
|
|
+ # self.__threading_backend.wait(10, lambda: self.__tracer.traceCompute(curIteration, block))
|
|
|
else:
|
|
|
# Detected a strongly connected component
|
|
|
self.__solver.checkValidity(self.model.getPath(), component)
|
|
|
@@ -573,7 +590,7 @@ class Simulator:
|
|
|
if curIteration == 0 or self.__scheduler.mustCompute(block, self.getTime()):
|
|
|
blockIndex = component.index(block)
|
|
|
block.appendToSignal(solutionVector[blockIndex])
|
|
|
- self.__tracer.traceCompute(curIteration, block)
|
|
|
+ # self.__threading_backend.wait(10, lambda: self.__tracer.traceCompute(curIteration, block))
|
|
|
|
|
|
def __hasCycle(self, component, depGraph):
|
|
|
"""
|
|
|
@@ -635,9 +652,8 @@ class Simulator:
|
|
|
whenever the event is raised.
|
|
|
|
|
|
Warning:
|
|
|
- The more computationally expensive the set of connected signals is, the less
|
|
|
- precise real-time simulation will be. A signal is meant to have a little hook
|
|
|
- on when certain events happen. It is **not** meant for complex data analysis.
|
|
|
+ While these functions will be handled on a different thread, it heavy
|
|
|
+ computations will eventually result in a delay of all events.
|
|
|
"""
|
|
|
if name not in self.__events:
|
|
|
raise ValueError("Invalid signal '%s' in Simulator." % name)
|
|
|
@@ -670,8 +686,18 @@ class Simulator:
|
|
|
"""
|
|
|
if name not in self.__events:
|
|
|
raise ValueError("Invalid signal '%s' in Simulator." % name)
|
|
|
- for evt in self.__events[name]:
|
|
|
- evt(*args)
|
|
|
+ self.__event_bus.append((name, args))
|
|
|
+
|
|
|
+ def __event_thread_loop(self):
|
|
|
+ print("looping")
|
|
|
+ if not self.__finished:
|
|
|
+ while len(self.__event_bus) > 0:
|
|
|
+ name, args = self.__event_bus.pop()
|
|
|
+ for evt in self.__events[name]:
|
|
|
+ evt(*args)
|
|
|
+ # time.sleep(0.05)
|
|
|
+ print("hello there")
|
|
|
+ self.__threading_backend.wait(0.05, self.__event_thread_loop)
|
|
|
|
|
|
def setCustomTracer(self, *tracer):
|
|
|
"""
|