浏览代码

Working SCCD

Yentl Van Tendeloo 8 年之前
父节点
当前提交
4074ae27b3
共有 2 个文件被更改,包括 28 次插入73 次删除
  1. 4 0
      bootstrap/utils.alc
  2. 24 73
      models/SCCD_execute.alc

+ 4 - 0
bootstrap/utils.alc

@@ -56,6 +56,10 @@ String function JSON_print(model : Element):
 
 Void function sleep(timeout : Float):
 	// TODO Placeholder function for a real sleep operation
+	Float start
+	start = time()
+	while (time() < (start + timeout)):
+		continue!
 	return!
 
 Element function input_timeout(timeout : Float):

+ 24 - 73
models/SCCD_execute.alc

@@ -221,7 +221,7 @@ Element function get_enabled_transitions(model : Element, state : String, data :
 		if (bool_and(element_eq(attr, read_root()), read_attribute(model, transition, "after"))):
 			if (dict_in(data["classes"][class]["timers"], transition)):
 				// Registered timer already, let's check if it has expired
-				if (float_gt(data["classes"][class]["timers"][transition], time())):
+				if (float_gt(data["classes"][class]["timers"][transition], data["time_sim"])):
 					// Not enabled yet
 					continue!
 			else:
@@ -363,7 +363,6 @@ Boolean function step_class(model : Element, data : Element, class : String):
 			if (read_nr_out(transitions) > 0):
 				// Found an enabled transition, so store that one
 				transition = random_choice(transitions)
-				log("Execute enabled transition: " + cast_v2s(read_attribute(model, list_read(transition, 0), "name")))
 				
 				// Execute transition
 				set_merge(new_states, execute_transition(model, data, class, transition))
@@ -383,64 +382,9 @@ Boolean function step_class(model : Element, data : Element, class : String):
 			
 	// Update states
 	dict_overwrite(data["classes"][class], "states", new_states)
-	//reschedule_timeouts(model, data, class)
 
 	return transitioned!
 
-Void function reschedule_timeouts(model : Element, data : Element, class : String):
-	Element timed_transitions
-	Element old_timed_transitions
-	String transition
-	Element states
-	String state
-
-	timed_transitions = create_node()
-	states = set_copy(data["classes"][class]["states"])
-	log("Rescheduling timeouts")
-
-	// Collect all timed transitions that are currently active
-	while (read_nr_out(states) > 0):
-		state = set_pop(states)
-
-		// NOTE this set_merge does not eliminate duplicates, though this should happen later on when adding the timer (see other NOTE)
-		set_merge(timed_transitions, filter_exists(model, allOutgoingAssociationInstances(model, state, "SCCD/transition"), "after"))
-
-	// Remove timers that no longer exist
-	old_timed_transitions = dict_keys(data["classes"][class]["timers"])
-
-	log("Got timed transitions: " + set_to_string(timed_transitions))
-	log("Got currently scheduled transitions: " + set_to_string(old_timed_transitions))
-
-	while (read_nr_out(old_timed_transitions) > 0):
-		transition = set_pop(old_timed_transitions)
-		log("Check remove " + cast_v2s(transition))
-
-		if (bool_not(set_in(timed_transitions, transition))):
-			// Transition is no longer scheduled for any state, so remove
-			dict_delete(data["classes"][class]["timers"], transition)
-			log("Remove timer for transition " + cast_v2s(read_attribute(model, transition, "name")))
-
-	// Schedule timers that are not already scheduled
-	while (read_nr_out(timed_transitions) > 0):
-		transition = set_pop(timed_transitions)
-		log("Check add " + cast_v2s(transition))
-
-		// NOTE Normally, a timer will not be added twice here, as the previous occurence will already find it
-		if (bool_not(dict_in(data["classes"][class]["timers"], transition))):
-			// Not yet scheduled this transition: do so now
-			Element after
-			Float after_duration
-
-			after = read_attribute(model, transition, "after")
-			after = get_func_AL_model(import_node(after))
-			after_duration = after(data["classes"][class]["attributes"])
-
-			dict_add(data["classes"][class]["timers"], transition, float_addition(data["start_time"], after_duration))
-			log("Add timer for transition " + cast_v2s(read_attribute(model, transition, "name")))
-	log("All done!")
-
-	return !
-
 String function get_parent(model : Element, state : String):
 	Element tmp_set
 	tmp_set = allAssociationOrigins(model, state, "SCCD/composite_children")
@@ -605,7 +549,6 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 	// First do exit actions
 	while (read_nr_out(exit) > 0):
 		state = list_pop(exit, 0)
-		log("EXIT " + cast_v2s(read_attribute(model, state, "name")))
 
 		// Set history when leaving
 		if (read_type(model, state) == "SCCD/CompositeState"):
@@ -635,15 +578,12 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		// Unschedule after events
 		Element timed_transitions
 		timed_transitions = filter_exists(model, allOutgoingAssociationInstances(model, state, "SCCD/transition"), "after")
-		log("Checking for unschedule of timed transitions: " + set_to_string(timed_transitions))
 		while (read_nr_out(timed_transitions) > 0):
-			log("Unschedule timer")
 			dict_delete(class_data["timers"], set_pop(timed_transitions))
 
 	// Then do entry actions
 	while (read_nr_out(entry) > 0):
 		state = list_pop(entry, 0)
-		log("ENTRY " + cast_v2s(read_attribute(model, state, "name")))
 
 		// Do entry actions
 		action = read_attribute(model, state, "onEntryScript")
@@ -671,12 +611,10 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		String transition
 		Element after
 		timed_transitions = filter_exists(model, allOutgoingAssociationInstances(model, state, "SCCD/transition"), "after")
-		log("Checking for schedule of timed transitions: " + set_to_string(timed_transitions))
 		while (read_nr_out(timed_transitions) > 0):
-			log("Schedule timer")
 			transition = set_pop(timed_transitions)
 			after = get_func_AL_model(import_node(read_attribute(model, transition, "after")))
-			dict_add(class_data["timers"], transition, float_addition(data["start_time"], after(class_data["attributes"])))
+			dict_add(class_data["timers"], transition, float_addition(data["time_sim"], after(class_data["attributes"])))
 
 	return !
 
@@ -690,12 +628,9 @@ Float function step(model : Element, data : Element):
 	Element keys
 	String key
 
-	t_min = time() + 99999.0
+	t_min = 999999.0
 	classes = dict_keys(data["classes"])
 
-	// TODO this should use simulated time or something
-	dict_overwrite(data, "start_time", time())
-
 	transitioned = False
 	while (read_nr_out(classes) > 0):
 		class = set_pop(classes)
@@ -713,17 +648,22 @@ Float function step(model : Element, data : Element):
 
 	if (transitioned):
 		// Do another step, as we can transition
-		log("Transitioned, do another step!")
-		return 0.0!
+		return data["time_sim"]!
 	else:
-		log("Idle!")
-		return float_subtraction(t_min, data["start_time"])!
+		return t_min!
 
 Boolean function main(model : Element):
 	// Executes the provided SCCD model
 	Element data
 	data = create_node()
 	dict_add(data, "classes", create_node())
+	
+	Float time_0
+	Float time_sim
+	Float time_wallclock
+	time_0 = time()
+	time_sim = 0.0
+	dict_add(data, "time_sim", 0.0)
 
 	// Prepare for input
 	output("Ready for input!")
@@ -740,7 +680,9 @@ Boolean function main(model : Element):
 	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
@@ -753,12 +695,21 @@ Boolean function main(model : Element):
 			set_add(data["events"], create_tuple(interrupt, read_root()))
 			output("Processed event, ready for more!")
 
-		timeout = step(model, data)
+			// Update the simulated time to the time of interrupt
+			time_sim = time() - time_0
+
+		// Else we timeout, and thus keep the time_sim
+		dict_overwrite(data, "time_sim", time_sim)
+
+		time_sim = step(model, data)
 
 		if (read_nr_out(data["classes"]) == 0):
 			// No more active classes left: terminate!
 			log("Finished SCCD execution")
 			break!
+
+		time_wallclock = time() - time_0
+		timeout = time_sim - time_wallclock
 		log("Pausing for " + cast_v2s(timeout))
 
 	// We should never get here!