From 93045ba1eef6e4e3074c1c24e2110bc336da53ea Mon Sep 17 00:00:00 2001 From: Thomas Kosel Date: Thu, 29 Jul 2021 20:09:31 +0200 Subject: [PATCH] reducing complexity of character_behavior's run method by extracting logical pieces. --- common/systems/src/character_behavior.rs | 246 ++++++++++++----------- 1 file changed, 132 insertions(+), 114 deletions(-) diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index 80d3586d2f..c1da0b563d 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -5,9 +5,9 @@ use specs::{ use common::{ comp::{ - self, inventory::item::MaterialStatManifest, Beam, Body, CharacterState, Combo, Controller, - Density, Energy, Health, Inventory, InventoryManip, Mass, Melee, Mounting, Ori, - PhysicsState, Poise, PoiseState, Pos, SkillSet, StateUpdate, Stats, Vel, + self, inventory::item::MaterialStatManifest, Beam, Body, CharacterState, Combo, + ControlAction, Controller, Density, Energy, Health, Inventory, InventoryManip, Mass, Melee, + Mounting, Ori, PhysicsState, Poise, PoiseState, Pos, SkillSet, StateUpdate, Stats, Vel, }, event::{Emitter, EventBus, LocalEvent, ServerEvent}, outcome::Outcome, @@ -22,37 +22,6 @@ use common::{ use common_ecs::{Job, Origin, Phase, System}; use std::time::Duration; -fn incorporate_update( - join: &mut JoinStruct, - mut state_update: StateUpdate, - server_emitter: &mut Emitter, -) { - // TODO: if checking equality is expensive use optional field in StateUpdate - if *join.char_state != state_update.character { - *join.char_state = state_update.character - }; - *join.pos = state_update.pos; - *join.vel = state_update.vel; - *join.ori = state_update.ori; - *join.density = state_update.density; - // Note: might be changed every tick by timer anyway - if *join.energy != state_update.energy { - *join.energy = state_update.energy - }; - join.controller - .queued_inputs - .append(&mut state_update.queued_inputs); - for input in state_update.removed_inputs { - join.controller.queued_inputs.remove(&input); - } - if state_update.swap_equipped_weapons { - server_emitter.emit(ServerEvent::InventoryManip( - join.entity, - InventoryManip::SwapEquippedWeapons, - )); - } -} - #[derive(SystemData)] pub struct ReadData<'a> { entities: Entities<'a>, @@ -303,50 +272,14 @@ impl<'a> System<'a> for Sys { &read_data.dt, &read_data.msm, ); - let mut state_update = match j.character { - CharacterState::Idle => states::idle::Data.handle_event(&j, action), - CharacterState::Talk => states::talk::Data.handle_event(&j, action), - CharacterState::Climb(data) => data.handle_event(&j, action), - CharacterState::Glide(data) => data.handle_event(&j, action), - CharacterState::GlideWield => { - states::glide_wield::Data.handle_event(&j, action) - }, - CharacterState::Stunned(data) => data.handle_event(&j, action), - CharacterState::Sit => { - states::sit::Data::handle_event(&states::sit::Data, &j, action) - }, - CharacterState::Dance => { - states::dance::Data::handle_event(&states::dance::Data, &j, action) - }, - CharacterState::Sneak => { - states::sneak::Data::handle_event(&states::sneak::Data, &j, action) - }, - CharacterState::BasicBlock(data) => data.handle_event(&j, action), - CharacterState::Roll(data) => data.handle_event(&j, action), - CharacterState::Wielding => states::wielding::Data.handle_event(&j, action), - CharacterState::Equipping(data) => data.handle_event(&j, action), - CharacterState::ComboMelee(data) => data.handle_event(&j, action), - CharacterState::BasicMelee(data) => data.handle_event(&j, action), - CharacterState::BasicRanged(data) => data.handle_event(&j, action), - CharacterState::Boost(data) => data.handle_event(&j, action), - CharacterState::DashMelee(data) => data.handle_event(&j, action), - CharacterState::LeapMelee(data) => data.handle_event(&j, action), - CharacterState::SpinMelee(data) => data.handle_event(&j, action), - CharacterState::ChargedMelee(data) => data.handle_event(&j, action), - CharacterState::ChargedRanged(data) => data.handle_event(&j, action), - CharacterState::RepeaterRanged(data) => data.handle_event(&j, action), - CharacterState::Shockwave(data) => data.handle_event(&j, action), - CharacterState::BasicBeam(data) => data.handle_event(&j, action), - CharacterState::BasicAura(data) => data.handle_event(&j, action), - CharacterState::Blink(data) => data.handle_event(&j, action), - CharacterState::BasicSummon(data) => data.handle_event(&j, action), - CharacterState::SelfBuff(data) => data.handle_event(&j, action), - CharacterState::SpriteSummon(data) => data.handle_event(&j, action), - CharacterState::UseItem(data) => data.handle_event(&j, action), - }; - local_emitter.append(&mut state_update.local_events); - server_emitter.append(&mut state_update.server_events); - incorporate_update(&mut join_struct, state_update, &mut server_emitter); + let mut state_update = ::handle_action_of_current_state(action, &j); + + ::emit_state_updates( + &mut server_emitter, + &mut local_emitter, + &mut state_update, + ); + ::incorporate_update(&mut join_struct, state_update, &mut server_emitter); } // Mounted occurs after control actions have been handled @@ -366,43 +299,128 @@ impl<'a> System<'a> for Sys { &read_data.msm, ); - let mut state_update = match j.character { - CharacterState::Idle => states::idle::Data.behavior(&j), - CharacterState::Talk => states::talk::Data.behavior(&j), - CharacterState::Climb(data) => data.behavior(&j), - CharacterState::Glide(data) => data.behavior(&j), - CharacterState::GlideWield => states::glide_wield::Data.behavior(&j), - CharacterState::Stunned(data) => data.behavior(&j), - CharacterState::Sit => states::sit::Data::behavior(&states::sit::Data, &j), - CharacterState::Dance => states::dance::Data::behavior(&states::dance::Data, &j), - CharacterState::Sneak => states::sneak::Data::behavior(&states::sneak::Data, &j), - CharacterState::BasicBlock(data) => data.behavior(&j), - CharacterState::Roll(data) => data.behavior(&j), - CharacterState::Wielding => states::wielding::Data.behavior(&j), - CharacterState::Equipping(data) => data.behavior(&j), - CharacterState::ComboMelee(data) => data.behavior(&j), - CharacterState::BasicMelee(data) => data.behavior(&j), - CharacterState::BasicRanged(data) => data.behavior(&j), - CharacterState::Boost(data) => data.behavior(&j), - CharacterState::DashMelee(data) => data.behavior(&j), - CharacterState::LeapMelee(data) => data.behavior(&j), - CharacterState::SpinMelee(data) => data.behavior(&j), - CharacterState::ChargedMelee(data) => data.behavior(&j), - CharacterState::ChargedRanged(data) => data.behavior(&j), - CharacterState::RepeaterRanged(data) => data.behavior(&j), - CharacterState::Shockwave(data) => data.behavior(&j), - CharacterState::BasicBeam(data) => data.behavior(&j), - CharacterState::BasicAura(data) => data.behavior(&j), - CharacterState::Blink(data) => data.behavior(&j), - CharacterState::BasicSummon(data) => data.behavior(&j), - CharacterState::SelfBuff(data) => data.behavior(&j), - CharacterState::SpriteSummon(data) => data.behavior(&j), - CharacterState::UseItem(data) => data.behavior(&j), - }; + let mut state_update = ::execute_behavior_of_current_state(&j); - local_emitter.append(&mut state_update.local_events); - server_emitter.append(&mut state_update.server_events); - incorporate_update(&mut join_struct, state_update, &mut server_emitter); + ::emit_state_updates(&mut server_emitter, &mut local_emitter, &mut state_update); + ::incorporate_update(&mut join_struct, state_update, &mut server_emitter); + } + } +} + +impl Sys { + fn execute_behavior_of_current_state(j: &JoinData) -> StateUpdate { + match j.character { + CharacterState::Idle => states::idle::Data.behavior(&j), + CharacterState::Talk => states::talk::Data.behavior(&j), + CharacterState::Climb(data) => data.behavior(&j), + CharacterState::Glide(data) => data.behavior(&j), + CharacterState::GlideWield => states::glide_wield::Data.behavior(&j), + CharacterState::Stunned(data) => data.behavior(&j), + CharacterState::Sit => states::sit::Data::behavior(&states::sit::Data, &j), + CharacterState::Dance => states::dance::Data::behavior(&states::dance::Data, &j), + CharacterState::Sneak => states::sneak::Data::behavior(&states::sneak::Data, &j), + CharacterState::BasicBlock(data) => data.behavior(&j), + CharacterState::Roll(data) => data.behavior(&j), + CharacterState::Wielding => states::wielding::Data.behavior(&j), + CharacterState::Equipping(data) => data.behavior(&j), + CharacterState::ComboMelee(data) => data.behavior(&j), + CharacterState::BasicMelee(data) => data.behavior(&j), + CharacterState::BasicRanged(data) => data.behavior(&j), + CharacterState::Boost(data) => data.behavior(&j), + CharacterState::DashMelee(data) => data.behavior(&j), + CharacterState::LeapMelee(data) => data.behavior(&j), + CharacterState::SpinMelee(data) => data.behavior(&j), + CharacterState::ChargedMelee(data) => data.behavior(&j), + CharacterState::ChargedRanged(data) => data.behavior(&j), + CharacterState::RepeaterRanged(data) => data.behavior(&j), + CharacterState::Shockwave(data) => data.behavior(&j), + CharacterState::BasicBeam(data) => data.behavior(&j), + CharacterState::BasicAura(data) => data.behavior(&j), + CharacterState::Blink(data) => data.behavior(&j), + CharacterState::BasicSummon(data) => data.behavior(&j), + CharacterState::SelfBuff(data) => data.behavior(&j), + CharacterState::SpriteSummon(data) => data.behavior(&j), + CharacterState::UseItem(data) => data.behavior(&j), + } + } + + fn handle_action_of_current_state(action: ControlAction, j: &JoinData) -> StateUpdate { + match j.character { + CharacterState::Idle => states::idle::Data.handle_event(&j, action), + CharacterState::Talk => states::talk::Data.handle_event(&j, action), + CharacterState::Climb(data) => data.handle_event(&j, action), + CharacterState::Glide(data) => data.handle_event(&j, action), + CharacterState::GlideWield => states::glide_wield::Data.handle_event(&j, action), + CharacterState::Stunned(data) => data.handle_event(&j, action), + CharacterState::Sit => states::sit::Data::handle_event(&states::sit::Data, &j, action), + CharacterState::Dance => { + states::dance::Data::handle_event(&states::dance::Data, &j, action) + }, + CharacterState::Sneak => { + states::sneak::Data::handle_event(&states::sneak::Data, &j, action) + }, + CharacterState::BasicBlock(data) => data.handle_event(&j, action), + CharacterState::Roll(data) => data.handle_event(&j, action), + CharacterState::Wielding => states::wielding::Data.handle_event(&j, action), + CharacterState::Equipping(data) => data.handle_event(&j, action), + CharacterState::ComboMelee(data) => data.handle_event(&j, action), + CharacterState::BasicMelee(data) => data.handle_event(&j, action), + CharacterState::BasicRanged(data) => data.handle_event(&j, action), + CharacterState::Boost(data) => data.handle_event(&j, action), + CharacterState::DashMelee(data) => data.handle_event(&j, action), + CharacterState::LeapMelee(data) => data.handle_event(&j, action), + CharacterState::SpinMelee(data) => data.handle_event(&j, action), + CharacterState::ChargedMelee(data) => data.handle_event(&j, action), + CharacterState::ChargedRanged(data) => data.handle_event(&j, action), + CharacterState::RepeaterRanged(data) => data.handle_event(&j, action), + CharacterState::Shockwave(data) => data.handle_event(&j, action), + CharacterState::BasicBeam(data) => data.handle_event(&j, action), + CharacterState::BasicAura(data) => data.handle_event(&j, action), + CharacterState::Blink(data) => data.handle_event(&j, action), + CharacterState::BasicSummon(data) => data.handle_event(&j, action), + CharacterState::SelfBuff(data) => data.handle_event(&j, action), + CharacterState::SpriteSummon(data) => data.handle_event(&j, action), + CharacterState::UseItem(data) => data.handle_event(&j, action), + } + } + + fn emit_state_updates( + server_emitter: &mut Emitter, + local_emitter: &mut Emitter, + state_update: &mut StateUpdate, + ) { + local_emitter.append(&mut state_update.local_events); + server_emitter.append(&mut state_update.server_events); + } + + fn incorporate_update( + join: &mut JoinStruct, + mut state_update: StateUpdate, + server_emitter: &mut Emitter, + ) { + // TODO: if checking equality is expensive use optional field in StateUpdate + if *join.char_state != state_update.character { + *join.char_state = state_update.character + }; + *join.pos = state_update.pos; + *join.vel = state_update.vel; + *join.ori = state_update.ori; + *join.density = state_update.density; + // Note: might be changed every tick by timer anyway + if *join.energy != state_update.energy { + *join.energy = state_update.energy + }; + join.controller + .queued_inputs + .append(&mut state_update.queued_inputs); + for input in state_update.removed_inputs { + join.controller.queued_inputs.remove(&input); + } + if state_update.swap_equipped_weapons { + server_emitter.emit(ServerEvent::InventoryManip( + join.entity, + InventoryManip::SwapEquippedWeapons, + )); } } }