micro_games_kit/
character.rs1use crate::{context::GameContext, game::GameObject};
2use emergent::task::Task;
3use raui_core::{Managed, ManagedRefMut};
4use spitfire_input::{InputMapping, InputMappingRef};
5use typid::ID;
6
7pub struct CharacterMemory<State> {
8 pub delta_time: f32,
9 pub state: ManagedRefMut<State>,
10}
11
12#[derive(Default)]
13pub enum CharacterController<State> {
14 #[default]
15 None,
16 Input {
17 mapping: InputMappingRef,
18 id: Option<ID<InputMapping>>,
19 },
20 Ai(Box<dyn Task<CharacterMemory<State>>>),
21}
22
23impl<State> CharacterController<State> {
24 pub fn input(mapping: impl Into<InputMappingRef>) -> Self {
25 Self::Input {
26 mapping: mapping.into(),
27 id: None,
28 }
29 }
30
31 pub fn ai(task: impl Task<CharacterMemory<State>> + 'static) -> Self {
32 Self::Ai(Box::new(task))
33 }
34}
35
36pub struct Character<State: GameObject> {
37 pub state: Managed<State>,
38 task: Box<dyn Task<CharacterMemory<State>>>,
39 controller: CharacterController<State>,
40}
41
42impl<State: GameObject> Character<State> {
43 pub fn new(
44 state: State,
45 task: impl Task<CharacterMemory<State>> + 'static,
46 controller: CharacterController<State>,
47 ) -> Self {
48 Self {
49 state: Managed::new(state),
50 task: Box::new(task),
51 controller,
52 }
53 }
54
55 pub fn activated(mut self, context: &mut GameContext) -> Self {
56 self.activate(context);
57 self
58 }
59}
60
61impl<State: GameObject> GameObject for Character<State> {
62 fn activate(&mut self, context: &mut GameContext) {
63 match &mut self.controller {
64 CharacterController::None => {}
65 CharacterController::Input { mapping, id } => {
66 if id.is_none() {
67 *id = Some(context.input.push_mapping(mapping.to_owned()));
68 }
69 }
70 CharacterController::Ai(task) => {
71 task.on_enter(&mut CharacterMemory {
72 delta_time: 0.0,
73 state: self.state.borrow_mut().unwrap(),
74 });
75 }
76 }
77 let mut memory = CharacterMemory {
78 delta_time: 0.0,
79 state: self.state.borrow_mut().unwrap(),
80 };
81 self.state.write().unwrap().activate(context);
82 self.task.on_enter(&mut memory);
83 }
84
85 fn deactivate(&mut self, context: &mut GameContext) {
86 match &mut self.controller {
87 CharacterController::None => {}
88 CharacterController::Input { id, .. } => {
89 if let Some(id) = id {
90 context.input.remove_mapping(*id);
91 }
92 *id = None;
93 }
94 CharacterController::Ai(task) => {
95 task.on_exit(&mut CharacterMemory {
96 delta_time: 0.0,
97 state: self.state.borrow_mut().unwrap(),
98 });
99 }
100 }
101 let mut memory = CharacterMemory {
102 delta_time: 0.0,
103 state: self.state.borrow_mut().unwrap(),
104 };
105 self.task.on_exit(&mut memory);
106 self.state.write().unwrap().deactivate(context);
107 }
108
109 fn process(&mut self, context: &mut GameContext, delta_time: f32) {
110 if let CharacterController::Ai(task) = &mut self.controller {
111 let mut memory = CharacterMemory {
112 delta_time,
113 state: self.state.borrow_mut().unwrap(),
114 };
115 task.on_process(&mut memory);
116 task.on_update(&mut memory);
117 }
118 let mut memory = CharacterMemory {
119 delta_time,
120 state: self.state.borrow_mut().unwrap(),
121 };
122 self.task.on_process(&mut memory);
123 self.task.on_update(&mut memory);
124 self.state.write().unwrap().process(context, delta_time);
125 }
126
127 fn draw(&mut self, context: &mut GameContext) {
128 self.state.write().unwrap().draw(context);
129 }
130}