|
@@ -125,6 +125,9 @@ class MvKState(object):
|
|
|
def __init__(self):
|
|
|
self.mvk = None
|
|
|
self.waiting = False
|
|
|
+ self.inputs = []
|
|
|
+ self.outputs = []
|
|
|
+ self.users = []
|
|
|
|
|
|
class ModelverseKernel(AtomicDEVS):
|
|
|
def __init__(self):
|
|
@@ -139,25 +142,74 @@ class ModelverseKernel(AtomicDEVS):
|
|
|
def extTransition(self, inputs):
|
|
|
if self.from_mvi in inputs:
|
|
|
# Got input from MvI, so we queue it
|
|
|
- pass
|
|
|
- elif self.from_mvs in inputs:
|
|
|
+ for inp in inputs[self.from_mvi]:
|
|
|
+ if inp is not None:
|
|
|
+ self.state.inputs.append(inp)
|
|
|
+ else:
|
|
|
+ self.state.outputs.append(None)
|
|
|
+
|
|
|
+ if self.from_mvs in inputs:
|
|
|
# Got input from MvS, so we can continue processing
|
|
|
if self.state.mvk is None:
|
|
|
# No MvK, so set it with the root we have just received (or should have received)
|
|
|
self.state.mvk = MvK(inputs[self.from_mvs][0])
|
|
|
+ else:
|
|
|
+ self.state.reply = inputs[self.from_mvs][0]
|
|
|
+ self.state.waiting = False
|
|
|
|
|
|
return self.state
|
|
|
|
|
|
def intTransition(self):
|
|
|
if self.state.mvk is None:
|
|
|
+ # Initializing
|
|
|
self.state.waiting = True
|
|
|
+ else:
|
|
|
+ # Are initialized and have work to do
|
|
|
+ if len(self.state.users) == 0:
|
|
|
+ # Read out new set of users first
|
|
|
+ if self.state.reply is None:
|
|
|
+ commands = [("RDK", [])]
|
|
|
+ else:
|
|
|
+ self.users = self.state.reply
|
|
|
+ print("Got users: " + str(self.users))
|
|
|
+ commands = None
|
|
|
+ elif self.state.phase == "input":
|
|
|
+ # Process inputs
|
|
|
+ commands = self.state.mvk.execute_yields(self.state.users[0], "set_input", [self.state.inputs[0]], self.state.reply)
|
|
|
+ elif self.state.phase == "computation":
|
|
|
+ commands = self.state.mvk.execute_yields(self.state.users[0], "execute_rule", [], self.state.reply)
|
|
|
+ elif self.state.phase == "output":
|
|
|
+ commands = self.state.mvk.execute_yields(self.state.users[0], "get_output", [], self.state.reply)
|
|
|
+
|
|
|
+ # Advance phase
|
|
|
+ if commands is None:
|
|
|
+ if len(self.state.users) == 0:
|
|
|
+ self.state.phase = "input"
|
|
|
+ elif self.state.phase == "input":
|
|
|
+ self.state.inputs.pop(0)
|
|
|
+ self.state.phase = "computation"
|
|
|
+ elif self.state.phase == "computation":
|
|
|
+ self.state.phase = "output"
|
|
|
+ elif self.state.phase == "output":
|
|
|
+ self.state.users.pop(0)
|
|
|
+ self.state.phase = "input"
|
|
|
+ self.state.waiting = False
|
|
|
+ self.state.reply = None
|
|
|
+ else:
|
|
|
+ self.state.waiting = True
|
|
|
|
|
|
+ # Send the commands to the MvS
|
|
|
+ self.state.commands = commands
|
|
|
return self.state
|
|
|
|
|
|
def outputFnc(self):
|
|
|
if self.state.mvk is None:
|
|
|
# Ask the root first
|
|
|
return {self.to_mvs: [[("RR", [])]]}
|
|
|
+ elif self.state.waiting:
|
|
|
+ return {self.to_mvs: [self.state.commands]}
|
|
|
+
|
|
|
+ return {}
|
|
|
|
|
|
def timeAdvance(self):
|
|
|
if self.state.waiting:
|
|
@@ -173,6 +225,7 @@ class MvIState():
|
|
|
self.output = []
|
|
|
self.processing = []
|
|
|
self.memory = {}
|
|
|
+ self.init = True
|
|
|
|
|
|
class ModelverseInterface(AtomicDEVS):
|
|
|
def __init__(self, operations):
|
|
@@ -184,6 +237,7 @@ class ModelverseInterface(AtomicDEVS):
|
|
|
self.from_mvk = self.addInPort("from_MvK")
|
|
|
|
|
|
def intTransition(self):
|
|
|
+ self.state.init = False
|
|
|
while self.state.operations:
|
|
|
i = self.state.operations[0]
|
|
|
if isinstance(i, int) and i not in self.memory:
|
|
@@ -212,7 +266,9 @@ class ModelverseInterface(AtomicDEVS):
|
|
|
return {self.to_mvk: [send]}
|
|
|
|
|
|
def timeAdvance(self):
|
|
|
- if self.state.processing and (not isinstance(self.state.processing[0], int) or self.state.processing[0] in self.memory):
|
|
|
+ if self.state.init:
|
|
|
+ return 0
|
|
|
+ elif self.state.processing and (not isinstance(self.state.processing[0], int) or self.state.processing[0] in self.memory):
|
|
|
return 0
|
|
|
else:
|
|
|
return float("inf")
|