Browse Source

Fix history + performance improvements by caching functions

Yentl Van Tendeloo 8 years ago
parent
commit
6baec329d5
1 changed files with 19 additions and 15 deletions
  1. 19 15
      models/SCCD_execute.alc

+ 19 - 15
models/SCCD_execute.alc

@@ -5,6 +5,11 @@ include "utils.alh"
 include "random.alh"
 include "library.alh"
 
+Element function resolve_function(location : String, data : Element):
+	if (bool_not(dict_in(data["operations"], location))):
+		dict_add(data["operations"], location, get_func_AL_model(import_node(location)))
+	return data["operations"][location]!
+
 Void function print_states(model : Element, data : Element):
 	Element classes
 	Element states
@@ -84,7 +89,7 @@ Element function expand_initial_state(model : Element, state : String, class_dat
 	elif (t == "SCCD/HistoryState"):
 		// Reset the history
 		// This is not really an initial state, but it is called in exactly the same places
-		return class_data["history"][state]!
+		return class_data["history"][get_parent(model, state)]!
 	else:
 		// Probably just an atomic, so return this one only
 		Element result
@@ -162,7 +167,7 @@ Void function start_class(model : Element, data : Element, class : String, ident
 	constructor = read_attribute(model, class, "constructor_body")
 	if (element_neq(constructor, read_root())):
 		// Constructor, so execute
-		constructor = get_func_AL_model(import_node(constructor))
+		constructor = resolve_function(constructor, data)
 		constructor(attributes, parameters)
 
 	// Execute all entry actions
@@ -232,7 +237,7 @@ Element function get_enabled_transitions(model : Element, state : String, data :
 		cond = read_attribute(model, transition, "cond")
 		if (element_neq(cond, read_root())):
 			// Got a condition, so resolve
-			cond = get_func_AL_model(import_node(cond))
+			cond = resolve_function(cond, data)
 
 		if (element_neq(attr, read_root())):
 			// We have an event to take into account!
@@ -303,7 +308,7 @@ Element function execute_transition(model : Element, data : Element, class : Str
 
 	script = read_attribute(model, transition, "script")
 	if (element_neq(script, read_root())):
-		script = get_func_AL_model(import_node(script))
+		script = resolve_function(script, data)
 		script(data["classes"][class]["attributes"], event_parameter)
 
 	// Raise events (if any)
@@ -317,7 +322,7 @@ Element function execute_transition(model : Element, data : Element, class : Str
 		parameter_action = read_attribute(model, event, "parameter")
 		if (element_neq(parameter_action, read_root())):
 			// Got a parameter to evaluate
-			parameter_action = get_func_AL_model(import_node(parameter_action))
+			parameter_action = resolve_function(parameter_action, data)
 			parameter_action = parameter_action(data["classes"][class]["attributes"], event_parameter)
 
 		process_raised_event(model, event, parameter_action, data)
@@ -558,7 +563,7 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		action = read_attribute(model, state, "onExitScript")
 		if (element_neq(action, read_root())):
 			// Got a script, so execute!
-			action = get_func_AL_model(import_node(action))
+			action = resolve_function(action, data)
 			action(class_data["attributes"])
 
 		// Raise events
@@ -570,7 +575,7 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 			parameter_action = read_attribute(model, event, "parameter")
 			if (element_neq(parameter_action, read_root())):
 				// Got a parameter to evaluate
-				parameter_action = get_func_AL_model(import_node(parameter_action))
+				parameter_action = resolve_function(parameter_action, data)
 				parameter_action = parameter_action(class_data["attributes"])
 
 			process_raised_event(model, event, parameter_action, data)
@@ -589,7 +594,7 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		action = read_attribute(model, state, "onEntryScript")
 		if (element_neq(action, read_root())):
 			// Got a script, so execute!
-			action = get_func_AL_model(import_node(action))
+			action = resolve_function(action, data)
 			action(class_data["attributes"])
 
 		// Raise events
@@ -601,7 +606,7 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 			parameter_action = read_attribute(model, event, "parameter")
 			if (element_neq(parameter_action, read_root())):
 				// Got a parameter to evaluate
-				parameter_action = get_func_AL_model(import_node(parameter_action))
+				parameter_action = resolve_function(parameter_action, data)
 				parameter_action = parameter_action(class_data["attributes"])
 
 			process_raised_event(model, event, parameter_action, data)
@@ -613,7 +618,7 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		timed_transitions = filter_exists(model, allOutgoingAssociationInstances(model, state, "SCCD/transition"), "after")
 		while (read_nr_out(timed_transitions) > 0):
 			transition = set_pop(timed_transitions)
-			after = get_func_AL_model(import_node(read_attribute(model, transition, "after")))
+			after = resolve_function(read_attribute(model, transition, "after"), data)
 			dict_add(class_data["timers"], transition, float_addition(data["time_sim"], after(class_data["attributes"])))
 
 	return !
@@ -657,6 +662,7 @@ Boolean function main(model : Element):
 	Element data
 	data = create_node()
 	dict_add(data, "classes", create_node())
+	dict_add(data, "operations", create_node())
 	
 	Float time_0
 	Float time_sim
@@ -679,10 +685,7 @@ Boolean function main(model : Element):
 	Element interrupt
 	timeout = 0.0
 	while (True):
-		print_states(model, data)
-		log("Request pause until " + cast_v2s(time() + timeout))
 		interrupt = input_timeout(timeout)
-		log("Got awakened at " + cast_v2s(time()))
 
 		if (value_eq(interrupt, "#EXIT#")):
 			// Stop execution
@@ -691,7 +694,6 @@ Boolean function main(model : Element):
 		dict_overwrite(data, "events", create_node())
 		if (element_neq(interrupt, read_root())):
 			// Got interrupt
-			log("Got event: " + cast_v2s(interrupt))
 			set_add(data["events"], create_tuple(interrupt, read_root()))
 			output("Processed event, ready for more!")
 
@@ -703,6 +705,9 @@ Boolean function main(model : Element):
 
 		time_sim = step(model, data)
 
+		if (float_gt(time_sim, data["time_sim"])):
+			print_states(model, data)
+
 		if (read_nr_out(data["classes"]) == 0):
 			// No more active classes left: terminate!
 			log("Finished SCCD execution")
@@ -710,7 +715,6 @@ Boolean function main(model : Element):
 
 		time_wallclock = time() - time_0
 		timeout = time_sim - time_wallclock
-		log("Pausing for " + cast_v2s(timeout))
 
 	// We should never get here!
 	return False!