浏览代码

First code for after events

Yentl Van Tendeloo 8 年之前
父节点
当前提交
347d9d8292
共有 1 个文件被更改,包括 82 次插入6 次删除
  1. 82 6
      models/SCCD_execute.alc

+ 82 - 6
models/SCCD_execute.alc

@@ -39,6 +39,19 @@ Element function filter(model : Element, set : Element, attribute_name : String,
 
 	return result!
 
+Element function filter_exists(model : Element, set : Element, attribute_name : String):
+	Element keys
+	String key
+	Element result
+
+	result = create_node()
+	while (read_nr_out(set) > 0):
+		key = set_pop(set)
+		if (element_neq(read_attribute(model, key, attribute_name), read_root())):
+			set_add(result, key)
+
+	return result!
+
 Element function expand_state(model : Element, state : String):
 	String t
 	t = read_type(model, state)
@@ -87,6 +100,7 @@ Void function start_class(model : Element, data : Element, class : String):
 	class_handle = create_node()
 	dict_add(class_handle, "type", class)
 	dict_add(class_handle, "ID", cast_id2s(create_node()))
+	dict_add(class_handle, "timers", create_node())
 
 	// Add the current state of the class
 	String initial_state
@@ -147,6 +161,7 @@ Element function execute_transition(model : Element, data : Element, class : Str
 
 	// Raise events (if any)
 	Element events
+	String event
 	events = allAssociationDestinations(model, transition, "SCCD/transition_raises")
 	while (read_nr_out(events) > 0):
 		event = set_pop(events)
@@ -164,8 +179,6 @@ Float function step_class(model : Element, data : Element, class : String):
 	String state
 	Element transitions
 	String transition
-	Float t_min
-	Float t_current
 
 	states = set_copy(data["classes"][class]["states"])
 	new_states = create_node()
@@ -187,11 +200,70 @@ Float function step_class(model : Element, data : Element, class : String):
 
 			// Nothing found, so stay in the current state
 			set_add(new_states, state)
-
+			
 	// Update states
 	dict_overwrite(data["classes"][class], "states", new_states)
+	reschedule_timeouts(model, data, class)
+
+	// Find minimum timer for this class, and return that
+	Float t_min
+	Float t_current
+	Element keys
+	String key
 
-	return 1.0!
+	t_min = time() + 99999.0
+	keys = dict_keys(data["classes"][class]["timers"])
+	while (read_nr_out(keys) > 0):
+		key = set_pop(keys)
+		t_current = data["classes"][class]["timers"][key]
+		if (t_current < t_min):
+			t_min = t_current
+
+	return t_min!
+
+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 = dict_keys(data["classes"][class]["states"])
+	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)
+		timed_transitions = 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"])
+		while (read_nr_out(old_timed_transitions) > 0):
+			transition = set_pop(old_timed_transitions)
+
+			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)
+
+		// Schedule timers that are not already scheduled
+		while (read_nr_out(timed_transitions) > 0):
+			transition = set_pop(timed_transitions)
+
+			// 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"])
+
+				log("Schedule transition after " + cast_v2s(after_duration))
+
+				dict_add(data["classes"][class]["timers"], transition, float_addition(data["start_time"], after_duration))
+
+	return !
 
 Float function step(model : Element, data : Element):
 	// Step through all classes
@@ -200,16 +272,19 @@ Float function step(model : Element, data : Element):
 	Float t_min
 	Float t_class
 
-	t_min = 1.0
+	t_min = time() + 99999.0
 	classes = dict_keys(data["classes"])
 
+	// TODO this should use simulated time or something
+	dict_overwrite(data, "start_time", time())
+
 	while (read_nr_out(classes) > 0):
 		class = set_pop(classes)
 		t_class = step_class(model, data, class)
 		if (t_class < t_min):
 			t_min = t_class
 
-	return t_min!
+	return float_subtraction(t_min, data["start_time"])!
 
 Boolean function main(model : Element):
 	// Executes the provided SCCD model
@@ -246,6 +321,7 @@ Boolean function main(model : Element):
 			output("Processed event, ready for more!")
 
 		timeout = step(model, data)
+		log("Pausing for " + cast_v2s(timeout))
 
 	// We should never get here!
 	return False!