Browse Source

Implement class attributes

Yentl Van Tendeloo 8 years ago
parent
commit
8bb1d07df0
2 changed files with 64 additions and 28 deletions
  1. 20 2
      integration/code/minimal_SCCD.mvc
  2. 44 26
      models/SCCD_execute.alc

+ 20 - 2
integration/code/minimal_SCCD.mvc

@@ -10,6 +10,17 @@ Class main {
     default = True
 }
 
+Attribute attr_a {
+    name = "a"
+}
+
+Attribute attr_b {
+    name = "b"
+}
+
+class_attributes (main, attr_a) {}
+class_attributes (main, attr_b) {}
+
 CompositeState main_statechart {
     name = "root"
     isInitial = True
@@ -54,14 +65,21 @@ CompositeState main_statechart {
 transition (x_a, x_b) {
     name = "X"
     event = "X"
+    script = $
+            Void function script(attributes : Element):
+                log("In script")
+                dict_overwrite(attributes, "a", 1)
+                dict_overwrite(attributes, "b", 2)
+                return!
+        $
 }
 
 transition (x_b, x_c) {
     name = "Z"
     cond = $
             Boolean function cond(attributes : Element):
-                log("in condition")
-                return (1 > 0)!
+                log("In condition")
+                return integer_lt(attributes["a"], attributes["b"])!
         $
 }
 

+ 44 - 26
models/SCCD_execute.alc

@@ -3,6 +3,7 @@ include "modelling.alh"
 include "object_operations.alh"
 include "utils.alh"
 include "random.alh"
+include "library.alh"
 
 Void function print_states(model : Element, data : Element):
 	Element classes
@@ -15,11 +16,13 @@ Void function print_states(model : Element, data : Element):
 	while (read_nr_out(classes) > 0):
 		class = set_pop(classes)
 		log(string_join(string_join(string_join("  ", class["ID"]), " : "), read_attribute(model, class["type"], "name")))
+		log("    Attributes: " + dict_to_string(class["attributes"]))
 
 		states = set_copy(class["states"])
+		log("    States:")
 		while (read_nr_out(states) > 0):
 			state = set_pop(states)
-			log(string_join("    ", read_attribute(model, state, "name")))
+			log(string_join("        ", read_attribute(model, state, "name")))
 
 	return!
 
@@ -97,14 +100,14 @@ Void function start_class(model : Element, data : Element, class : String):
 	Element attrs
 	attrs = allAssociationDestinations(model, class, "SCCD/class_attributes")
 	while (read_nr_out(attrs) > 0):
-		dict_add(attributes, read_attribute(model, set_pop(attrs), "name"), create_node())
+		dict_add(attributes, read_attribute(model, set_pop(attrs), "name"), read_root())
 	dict_add(class_handle, "attributes", attributes)
 
-	set_add(data["classes"], class_handle)
+	dict_add(data["classes"], class_handle["ID"], class_handle)
 
 	return!
 
-Element function get_enabled_transitions(model : Element, state : String, interrupt : Element):
+Element function get_enabled_transitions(model : Element, state : String, data : Element, class : String):
 	// Returns all enabled transitions
 	// TODO ignore conditions and afters
 	Element result
@@ -119,30 +122,39 @@ Element function get_enabled_transitions(model : Element, state : String, interr
 	while (read_nr_out(to_filter) > 0):
 		transition = set_pop(to_filter)
 		attr = read_attribute(model, transition, "event")
-		if (bool_or(element_eq(attr, read_root()), value_eq(attr, interrupt))):
+		log("Check attr in event list: " + set_to_string(data["events"]))
+		if (bool_or(element_eq(attr, read_root()), set_in(data["events"], attr))):
 			// Event is OK
 			cond = read_attribute(model, transition, "cond")
-			log("Resolved condition")
 			if (element_neq(cond, read_root())):
-				log("Result = " + cast_e2s(cond))
-				cond = get_func_AL_model(cond)
-				log("Resolved = " + cast_e2s(cond))
+				cond = get_func_AL_model(import_node(cond))
 				// Execute condition
-				if (bool_not(cond(create_node()))):
-					log("Evaluated to True")
+				if (bool_not(cond(data["classes"][class]["attributes"]))):
 					// Condition false, so skip
 					continue!
-				else:
-					log("Evaluated to False")
-			else:
-				log("NO condition")
-			// Condition is OK
 
+			// Condition is OK
 			set_add(result, transition)
 
 	return result!
 
-Float function step_class(model : Element, data : Element, class : Element, interrupt : Element):
+Element function execute_transition(model : Element, data : Element, class : String, transition : String):
+	// Execute the script (if any)
+	Element script
+	script = read_attribute(model, transition, "script")
+	if (element_neq(script, read_root())):
+		script = get_func_AL_model(import_node(script))
+		log("Calling script with attributes: " + dict_to_string(data["classes"][class]["attributes"]))
+		script(data["classes"][class]["attributes"])
+		log("Called script with attributes: " + dict_to_string(data["classes"][class]["attributes"]))
+
+	// Raise events
+	// TODO
+
+	// Return new set of states
+	return expand_state(model, readAssociationDestination(model, transition))!
+
+Float function step_class(model : Element, data : Element, class : String):
 	// Find enabled transitions in a class and execute it, updating the state
 	// Iterate over all current states, searching for enabled transitions
 	// Search for enabled transitions in higher levels as well!
@@ -154,18 +166,21 @@ Float function step_class(model : Element, data : Element, class : Element, inte
 	Float t_min
 	Float t_current
 
-	states = set_copy(class["states"])
+	log("Step class " + class)
+	states = set_copy(data["classes"][class]["states"])
 	new_states = create_node()
 
 	while (read_nr_out(states) > 0):
 		state = set_pop(states)
 
 		// Fetch transitions in this state specifically (NO parent)
-		transitions = get_enabled_transitions(model, state, interrupt)
+		transitions = get_enabled_transitions(model, state, data, class)
 		if (read_nr_out(transitions) != 0):
 			// Found an enabled transition, so store that one
 			transition = random_choice(transitions)
-			set_merge(new_states, expand_state(model, readAssociationDestination(model, transition)))
+			
+			// Execute transition
+			set_merge(new_states, execute_transition(model, data, class, transition))
 		else:
 			// Try going to the parent
 			// TODO
@@ -174,23 +189,24 @@ Float function step_class(model : Element, data : Element, class : Element, inte
 			set_add(new_states, state)
 
 	// Update states
-	dict_overwrite(class, "states", new_states)
+	dict_overwrite(data["classes"][class], "states", new_states)
 
 	return 1.0!
 
-Float function step(model : Element, data : Element, interrupt : Element):
+Float function step(model : Element, data : Element):
 	// Step through all classes
 	Element classes
 	Element class
 	Float t_min
 	Float t_class
 
-	t_min = 99999.0
-	classes = set_copy(data["classes"])
+	t_min = 1.0
+	classes = dict_keys(data["classes"])
+	log("Got classes: " + set_to_string(classes))
 
 	while (read_nr_out(classes) > 0):
 		class = set_pop(classes)
-		t_class = step_class(model, data, class, interrupt)
+		t_class = step_class(model, data, class)
 		if (t_class < t_min):
 			t_min = t_class
 
@@ -223,12 +239,14 @@ Boolean function main(model : Element):
 			// Stop execution
 			return True!
 
+		dict_overwrite(data, "events", create_node())
 		if (element_neq(interrupt, read_root())):
 			// Got interrupt
 			log("Got event: " + cast_v2s(interrupt))
+			set_add(data["events"], interrupt)
 			output("Processed event, ready for more!")
 
-		timeout = step(model, data, interrupt)
+		timeout = step(model, data)
 
 	// We should never get here!
 	return False!