@@ -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