Browse Source

Allow raise with parameters

Yentl Van Tendeloo 8 years ago
parent
commit
2492bab45f
3 changed files with 68 additions and 14 deletions
  1. 2 2
      integration/code/minimal_SCCD.mvc
  2. 1 0
      models/SCCD.mvc
  3. 65 12
      models/SCCD_execute.alc

+ 2 - 2
integration/code/minimal_SCCD.mvc

@@ -104,7 +104,7 @@ transition (x_a, x_b) {
     name = "X"
     event = "X"
     script = $
-            Void function script(attributes : Element):
+            Void function script(attributes : Element, evt_param : Element):
                 log("In script")
                 dict_overwrite(attributes, "a", 1)
                 dict_overwrite(attributes, "b", 2)
@@ -124,7 +124,7 @@ transition (x_a, x_d) {
 transition (x_b, x_c) {
     name = "Z"
     cond = $
-            Boolean function cond(attributes : Element):
+            Boolean function cond(attributes : Element, evt_param : Element):
                 log("In condition")
                 return integer_lt(attributes["a"], attributes["b"])!
         $

+ 1 - 0
models/SCCD.mvc

@@ -65,6 +65,7 @@ Class Raise{
     event : String
     scope? : String
     target? : String
+    parameter? : Action
 }
 Association state_onentry_raises(BasicState, Raise){
     order : Natural

+ 65 - 12
models/SCCD_execute.alc

@@ -155,16 +155,38 @@ Element function get_enabled_transitions(model : Element, state : String, data :
 	String attr
 	String transition
 	Element cond
+	String evt_name
+	Element evt
+	Element events
+	Element event_names
+	Element event_parameters
 
 	result = create_node()
 	to_filter = allOutgoingAssociationInstances(model, state, "SCCD/transition")
 
+	event_names = create_node()
+	event_parameters = create_node()
+	events = set_copy(data["events"])
+	while (read_nr_out(events) > 0):
+		evt = set_pop(events)
+		evt_name = list_read(evt, 0)
+
+		if (bool_not(set_in(event_names, evt_name))):
+			// Not yet registered the event
+			set_add(event_names, evt_name)
+			dict_add(event_parameters, evt_name, create_node())
+		// Add event parameters
+		set_add(event_parameters[evt_name], list_read(evt, 1))
+
+		log("Got enabled events: " + set_to_string(event_names))
+
 	while (read_nr_out(to_filter) > 0):
 		transition = set_pop(to_filter)
 
 		// Check event
 		attr = read_attribute(model, transition, "event")
-		if (bool_not(bool_or(element_eq(attr, read_root()), set_in(data["events"], attr)))):
+		if (bool_not(bool_or(element_eq(attr, read_root()), set_in(event_names, attr)))):
+			// At least one enabled event is found
 			continue!
 
 		// Check after
@@ -179,17 +201,35 @@ Element function get_enabled_transitions(model : Element, state : String, data :
 				// Not registered even, so not enabled either
 				continue!
 
-		// Check condition
+		// Check condition, but depends on whether there was an event or not
 		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))
-			// Execute condition
-			if (bool_not(cond(data["classes"][class]["attributes"]))):
-				// Condition false, so skip
-				continue!
 
-		// All is OK for this transition
-		set_add(result, transition)
+		if (element_neq(attr, read_root())):
+			// We have an event to take into account!
+			Element params
+			Element param
+			params = set_copy(event_parameters[attr])
+			while (read_nr_out(params) > 0):
+				param = set_pop(params)
+				if (element_neq(cond, read_root())):
+					// Got a condition to check first
+					if (bool_not(cond(data["classes"][class]["attributes"], param))):
+						// Condition failed, so skip
+						continue!
+				// Fine to add this one with the specified parameters
+				set_add(result, create_tuple(transition, param))
+		else:
+			// No event to think about, just add the transition
+			if (element_neq(cond, read_root())):
+				// Check the condition first
+				if (bool_not(cond(data["classes"][class]["attributes"], read_root()))):
+					// Condition false, so skip
+					continue!
+			// Fine to add this one without event parameters (no event)
+			set_add(result, create_tuple(transition, read_root()))
 
 	return result!
 
@@ -202,13 +242,18 @@ Void function execute_actions(model : Element, source_states : Element, target_s
 		action(attributes)
 	return!
 
-Element function execute_transition(model : Element, data : Element, class : String, transition : String):
+Element function execute_transition(model : Element, data : Element, class : String, transition_tuple : Element):
 	// Execute the script (if any)
 	Element script
+	String transition
+	Element event_parameter
+	transition = list_read(transition_tuple, 0)
+	event_parameter = list_read(transition_tuple, 1)
+
 	script = read_attribute(model, transition, "script")
 	if (element_neq(script, read_root())):
 		script = get_func_AL_model(import_node(script))
-		script(data["classes"][class]["attributes"])
+		script(data["classes"][class]["attributes"], event_parameter)
 
 	// Raise events (if any)
 	Element events
@@ -216,7 +261,15 @@ Element function execute_transition(model : Element, data : Element, class : Str
 	events = allAssociationDestinations(model, transition, "SCCD/transition_raises")
 	while (read_nr_out(events) > 0):
 		event = set_pop(events)
-		set_add(data["events"], read_attribute(model, event, "event"))
+
+		Element parameter_action
+		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 = parameter_action(data["classes"][class]["attributes"], event_parameter)
+
+		set_add(data["events"], create_tuple(read_attribute(model, event, "event"), parameter_action))
 
 	// Find new set of states
 	Element target_states
@@ -538,7 +591,7 @@ Boolean function main(model : Element):
 		if (element_neq(interrupt, read_root())):
 			// Got interrupt
 			log("Got event: " + cast_v2s(interrupt))
-			set_add(data["events"], interrupt)
+			set_add(data["events"], create_tuple(interrupt, read_root()))
 			output("Processed event, ready for more!")
 
 		timeout = step(model, data)