|
@@ -135,19 +135,35 @@ Element function get_enabled_transitions(model : Element, state : String, data :
|
|
|
|
|
|
while (read_nr_out(to_filter) > 0):
|
|
while (read_nr_out(to_filter) > 0):
|
|
transition = set_pop(to_filter)
|
|
transition = set_pop(to_filter)
|
|
|
|
+
|
|
|
|
+ // Check event
|
|
attr = read_attribute(model, transition, "event")
|
|
attr = read_attribute(model, transition, "event")
|
|
- if (bool_or(element_eq(attr, read_root()), set_in(data["events"], attr))):
|
|
|
|
- // Event is OK
|
|
|
|
- cond = read_attribute(model, transition, "cond")
|
|
|
|
- if (element_neq(cond, read_root())):
|
|
|
|
- cond = get_func_AL_model(import_node(cond))
|
|
|
|
- // Execute condition
|
|
|
|
- if (bool_not(cond(data["classes"][class]["attributes"]))):
|
|
|
|
- // Condition false, so skip
|
|
|
|
|
|
+ if (bool_not(bool_or(element_eq(attr, read_root()), set_in(data["events"], attr)))):
|
|
|
|
+ continue!
|
|
|
|
+
|
|
|
|
+ // Check after
|
|
|
|
+ // Only an after if there was no event!
|
|
|
|
+ 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())):
|
|
|
|
+ // Not enabled yet
|
|
continue!
|
|
continue!
|
|
-
|
|
|
|
- // Condition is OK
|
|
|
|
- set_add(result, transition)
|
|
|
|
|
|
+ else:
|
|
|
|
+ // Not registered even, so not enabled either
|
|
|
|
+ continue!
|
|
|
|
+
|
|
|
|
+ // Check condition
|
|
|
|
+ cond = read_attribute(model, transition, "cond")
|
|
|
|
+ if (element_neq(cond, read_root())):
|
|
|
|
+ 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)
|
|
|
|
|
|
return result!
|
|
return result!
|
|
|
|
|
|
@@ -218,39 +234,39 @@ Void function reschedule_timeouts(model : Element, data : Element, class : Strin
|
|
String state
|
|
String state
|
|
|
|
|
|
timed_transitions = create_node()
|
|
timed_transitions = create_node()
|
|
- states = dict_keys(data["classes"][class]["states"])
|
|
|
|
|
|
+ states = set_copy(data["classes"][class]["states"])
|
|
|
|
+
|
|
|
|
+ // Collect all timed transitions that are currently active
|
|
while (read_nr_out(states) > 0):
|
|
while (read_nr_out(states) > 0):
|
|
state = set_pop(states)
|
|
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)
|
|
// 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"))
|
|
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)
|
|
|
|
|
|
+ // 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)
|
|
|
|
|
|
- // Schedule timers that are not already scheduled
|
|
|
|
- while (read_nr_out(timed_transitions) > 0):
|
|
|
|
- transition = set_pop(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)
|
|
|
|
|
|
- // 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
|
|
|
|
|
|
+ // Schedule timers that are not already scheduled
|
|
|
|
+ while (read_nr_out(timed_transitions) > 0):
|
|
|
|
+ transition = set_pop(timed_transitions)
|
|
|
|
|
|
- after = read_attribute(model, transition, "after")
|
|
|
|
- after = get_func_AL_model(import_node(after))
|
|
|
|
- after_duration = after(data["classes"][class]["attributes"])
|
|
|
|
|
|
+ // 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
|
|
|
|
|
|
- log("Schedule transition after " + cast_v2s(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))
|
|
|
|
|
|
+ dict_add(data["classes"][class]["timers"], transition, float_addition(data["start_time"], after_duration))
|
|
|
|
|
|
return !
|
|
return !
|
|
|
|
|