Skip to content

Commit 9913929

Browse files
committed
Avoid creating unnecessary channels
- avoid creating channels as side effects of an `or_insert` call - also small code cleanup Signed-off-by: Enrico Ghiorzi <enrico.ghiorzi@edu.unige.it>
1 parent ef019b0 commit 9913929

1 file changed

Lines changed: 33 additions & 29 deletions

File tree

scan_scxml/src/builder.rs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -426,14 +426,16 @@ impl ModelBuilder {
426426
// Conventionally, the entry-point for a state is a location associated to the id of the state.
427427
states.insert(scxml.initial.to_owned(), initial_loc);
428428
// Var representing the current event
429+
// (use Integer::MAX as no-event flag)
429430
let current_event_var = self
430431
.cs
431-
.new_var(pg_id, CsExpression::from(0))
432+
.new_var(pg_id, CsExpression::from(Integer::MAX))
432433
.expect("program graph exists!");
433434
// Variable that will store origin of last processed event.
435+
// (use Integer::MAX as no-origin flag)
434436
let origin_var = self
435437
.cs
436-
.new_var(pg_id, CsExpression::from(0))
438+
.new_var(pg_id, CsExpression::from(Integer::MAX))
437439
.expect("program graph exists!");
438440
// Implement internal queue
439441
let int_queue = self.cs.new_channel(vec![Type::Integer], None);
@@ -507,7 +509,7 @@ impl ModelBuilder {
507509
let params_channel = *self
508510
.parameter_channels
509511
.entry((sender_id, pg_id, event_index))
510-
.or_insert(self.cs.new_channel(param_types_vec.clone(), None));
512+
.or_insert_with(|| self.cs.new_channel(param_types_vec.clone(), None));
511513
let read = self
512514
.cs
513515
.new_receive(pg_id, params_channel, param_vars_vec.clone())
@@ -688,9 +690,8 @@ impl ModelBuilder {
688690
target: "build",
689691
"build {} transition to {}",
690692
transition
691-
.event
692-
.as_ref()
693-
.unwrap_or(&"eventless".to_string()),
693+
.event.as_deref()
694+
.unwrap_or("eventless"),
694695
transition.target
695696
);
696697
// Get or create the location corresponding to the target state.
@@ -727,18 +728,21 @@ impl ModelBuilder {
727728
])),
728729
),
729730
]);
731+
let mut event_vars = self.events[event_index]
732+
.params
733+
.keys()
734+
.flat_map(|param_name| {
735+
&param_vars
736+
.get(&(event_index, param_name.clone()))
737+
.expect("param")
738+
.1
739+
})
740+
.cloned()
741+
.collect::<Vec<_>>();
742+
event_vars.push((origin_var, Type::Integer));
730743
vars.insert(
731744
String::from("_event"),
732-
(
733-
OmgType::Custom(String::from("_EventType")),
734-
param_vars
735-
.iter()
736-
.filter(|((ev_ix, _), _)| *ev_ix == event_index)
737-
.flat_map(|(_, (_, vars))| vars)
738-
.cloned()
739-
.chain([(origin_var, Type::Integer)])
740-
.collect(),
741-
),
745+
(OmgType::Custom(String::from("_EventType")), event_vars),
742746
);
743747
}
744748
// Condition activating the transition.
@@ -857,18 +861,18 @@ impl ModelBuilder {
857861
// If the current transition is not active, move on to check the next one.
858862
// NOTE: an autonomous transition without cond is always active so there is no point processing further transitions.
859863
// This happens in State Charts already, so we model it faithfully without optimizations.
860-
let not_guard = guard
861-
.map(CsExpression::not)
862-
.transpose()?
863-
.unwrap_or(CsExpression::from(false));
864-
self.cs
865-
.add_autonomous_transition(
866-
pg_id,
867-
check_trans_loc,
868-
next_trans_loc,
869-
Some(not_guard),
870-
)
871-
.expect("cannot fail because guard was already checked");
864+
if let Some(guard) = guard {
865+
let not_guard =
866+
CsExpression::not(guard).expect("guard is a boolean expression");
867+
self.cs
868+
.add_autonomous_transition(
869+
pg_id,
870+
check_trans_loc,
871+
next_trans_loc,
872+
Some(not_guard),
873+
)
874+
.expect("cannot fail because guard was already checked");
875+
}
872876
}
873877

874878
// Connect NULL events with named events
@@ -1212,7 +1216,7 @@ impl ModelBuilder {
12121216
let param_chn = *self
12131217
.parameter_channels
12141218
.entry((pg_id, target_id, event_idx))
1215-
.or_insert(self.cs.new_channel(scan_types, None));
1219+
.or_insert_with(|| self.cs.new_channel(scan_types, None));
12161220
// Can return error if expr is badly typed
12171221
let pass_param = self.cs.new_send(pg_id, param_chn, exprs)?;
12181222
let next_loc = self.cs.new_location(pg_id).expect("PG exists");

0 commit comments

Comments
 (0)