Skip to content

Commit

Permalink
Refactor event transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
Shatur committed Oct 19, 2024
1 parent 508c181 commit 0c70ac0
Showing 1 changed file with 54 additions and 103 deletions.
157 changes: 54 additions & 103 deletions src/input_context/input_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,114 +110,65 @@ impl ActionData {
state: ActionState,
value: ActionValue,
) {
trace!(
"changing state from `{:?}` to `{state:?}` with `{value:?}`",
self.state
);

// Trigger an event for each entity separately
// since it's cheaper to copy the event than to clone the entities.
for &entity in entities {
match (self.state, state) {
(ActionState::None, ActionState::None) => (),
(ActionState::None, ActionState::Ongoing) => {
commands.trigger_targets(
ActionEvent::<A>::new(ActionTransition::Started, value, state),
entity,
);
commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Ongoing { elapsed_secs: 0.0 },
value,
state,
),
entity,
);
}
(ActionState::None, ActionState::Fired) => {
commands.trigger_targets(
ActionEvent::<A>::new(ActionTransition::Started, value, state),
entity,
);
commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Fired {
fired_secs: 0.0,
elapsed_secs: 0.0,
},
value,
state,
),
entity,
);
if let Some((started, transition)) = self.transitions(state) {
// Trigger an event for each entity separately
// since it's cheaper to copy the event than to clone the entities.
for &entity in entities {
if started {
let event = ActionEvent::<A>::new(ActionTransition::Started, value, state);
debug!("triggering `{event:?}` for `{entity}`");
commands.trigger_targets(event, entity);
}
(ActionState::Ongoing, ActionState::None) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Canceled {
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),
(ActionState::Ongoing, ActionState::Ongoing) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Ongoing {
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),
(ActionState::Ongoing, ActionState::Fired) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Fired {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),
(ActionState::Fired, ActionState::None) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Completed {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),
(ActionState::Fired, ActionState::Ongoing) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Ongoing {
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),
(ActionState::Fired, ActionState::Fired) => commands.trigger_targets(
ActionEvent::<A>::new(
ActionTransition::Fired {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
value,
state,
),
entity,
),

let event = ActionEvent::<A>::new(transition, value, state);
debug!("triggering `{event:?}` for `{entity}`");
commands.trigger_targets(event, entity);
}
}
}

fn transitions(&self, state: ActionState) -> Option<(bool, ActionTransition)> {
let mut started = false; // Indicates whether `ActionTransition::Started` should also be emitted.

let transition = match (self.state, state) {
(ActionState::None, ActionState::None) => return None,
(ActionState::None, ActionState::Ongoing) => {
started = true;
ActionTransition::Ongoing { elapsed_secs: 0.0 }
}
(ActionState::None, ActionState::Fired) => {
started = true;
ActionTransition::Fired {
fired_secs: 0.0,
elapsed_secs: 0.0,
}
}
(ActionState::Ongoing, ActionState::None) => ActionTransition::Canceled {
elapsed_secs: self.elapsed_secs,
},
(ActionState::Ongoing, ActionState::Ongoing) => ActionTransition::Ongoing {
elapsed_secs: self.elapsed_secs,
},
(ActionState::Ongoing, ActionState::Fired) => ActionTransition::Fired {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
(ActionState::Fired, ActionState::None) => ActionTransition::Completed {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
(ActionState::Fired, ActionState::Ongoing) => ActionTransition::Ongoing {
elapsed_secs: self.elapsed_secs,
},
(ActionState::Fired, ActionState::Fired) => ActionTransition::Fired {
fired_secs: self.fired_secs,
elapsed_secs: self.elapsed_secs,
},
};

Some((started, transition))
}

/// Returns the current state.
pub fn state(&self) -> ActionState {
self.state
Expand Down

0 comments on commit 0c70ac0

Please sign in to comment.