konnektoren_core/controller/
game_controller.rs1use super::ControllerPlugin;
2use crate::commands::{Command, CommandBus, CommandTrait, CommandType};
3use crate::controller::{ControllerError, PluginManager, Result};
4use crate::events::EventBus;
5use crate::game::Game;
6use crate::game::GameState;
7use crate::persistence::GameStatePersistence;
8use std::fmt::{Debug, Formatter};
9use std::sync::{Arc, Mutex};
10
11#[cfg(test)]
12use mockall::{automock, predicate::*};
13
14#[cfg_attr(test, automock)]
15pub trait GameControllerTrait: Send + Sync {
16 fn save_game_state(&self) -> Result<()>;
17 fn load_game_state(&self) -> Result<()>;
18
19 fn handle_command(&self, command: Command) -> Result<()>;
20 fn publish_command(&self, command: Command);
21
22 fn game_state(&self) -> &Arc<Mutex<GameState>>;
24 fn event_bus(&self) -> &EventBus;
25 fn event_bus_mut(&mut self) -> &mut EventBus;
26 fn command_bus(&self) -> &CommandBus;
27 fn command_bus_mut(&mut self) -> &mut CommandBus;
28}
29
30pub struct GameController {
31 game_state: Arc<Mutex<GameState>>,
32 event_bus: EventBus,
33 command_bus: CommandBus,
34 persistence: Arc<dyn GameStatePersistence>,
35 plugin_manager: PluginManager,
36}
37
38impl PartialEq for GameController {
39 fn eq(&self, other: &Self) -> bool {
40 Arc::ptr_eq(&self.game_state, &other.game_state)
41 }
42}
43
44impl Debug for GameController {
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 f.debug_struct("GameController").finish()
47 }
48}
49
50impl GameController {
51 pub fn new(game: Game, persistence: Arc<dyn GameStatePersistence>) -> Self {
52 let game_state = Arc::new(Mutex::new(GameState::new(game)));
53 let event_bus = EventBus::new();
54 let command_bus = CommandBus::new();
55
56 Self {
57 game_state,
58 event_bus,
59 command_bus,
60 persistence,
61 plugin_manager: PluginManager::new(),
62 }
63 }
64
65 pub fn register_plugin(&mut self, plugin: Arc<dyn ControllerPlugin>) {
66 self.plugin_manager.add_plugin(plugin);
67 }
68
69 #[must_use]
70 pub fn init(mut self) -> Arc<Self> {
71 if let Err(e) = self.plugin_manager.init_plugins() {
73 log::error!("Error initializing plugins: {:?}", e);
74 }
75
76 let controller = Arc::new(self);
78
79 let controller_clone = Arc::clone(&controller);
80 controller
81 .command_bus
82 .subscribe(CommandType::Game, move |command| {
83 if let Err(e) = controller_clone.handle_command(command) {
84 log::error!("Error handling game command: {:?}", e);
85 }
86 });
87
88 let controller_clone = Arc::clone(&controller);
89 controller
90 .command_bus
91 .subscribe(CommandType::Challenge, move |command| {
92 if let Err(e) = controller_clone.handle_command(command) {
93 log::error!("Error handling challenge command: {:?}", e);
94 }
95 });
96
97 let controller_trait: Arc<dyn GameControllerTrait> = controller.clone();
99
100 if let Err(e) = controller.plugin_manager.load_plugins(&controller_trait) {
102 log::error!("Error loading plugins: {:?}", e);
103 }
104
105 controller
106 }
107}
108
109impl GameControllerTrait for GameController {
110 fn save_game_state(&self) -> Result<()> {
111 let game_state = self
112 .game_state
113 .lock()
114 .map_err(|_| ControllerError::StateLock)?;
115
116 self.persistence
117 .save_game_state(&game_state)
118 .map_err(ControllerError::Persistence)
119 }
120
121 fn load_game_state(&self) -> Result<()> {
122 let loaded_state = self
123 .persistence
124 .load_game_state()
125 .map_err(ControllerError::Persistence)?;
126
127 let mut game_state = self
128 .game_state
129 .lock()
130 .map_err(|_| ControllerError::StateLock)?;
131
132 *game_state = loaded_state;
133 Ok(())
134 }
135
136 fn handle_command(&self, command: Command) -> Result<()> {
137 let mut state = self
138 .game_state
139 .lock()
140 .map_err(|_| ControllerError::StateLock)?;
141
142 command
143 .execute(&mut state)
144 .map_err(ControllerError::CommandExecution)
145 }
146
147 fn publish_command(&self, command: Command) {
148 self.command_bus.publish(command);
149 }
150
151 fn game_state(&self) -> &Arc<Mutex<GameState>> {
153 &self.game_state
154 }
155
156 fn event_bus(&self) -> &EventBus {
158 &self.event_bus
159 }
160
161 fn event_bus_mut(&mut self) -> &mut EventBus {
163 &mut self.event_bus
164 }
165
166 fn command_bus(&self) -> &CommandBus {
168 &self.command_bus
169 }
170
171 fn command_bus_mut(&mut self) -> &mut CommandBus {
173 &mut self.command_bus
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180 use crate::commands::GameCommand;
181 use crate::persistence::MemoryPersistence;
182
183 #[test]
184 fn test_handle_command() {
185 let game = Game::default();
186 let persistence = Arc::new(MemoryPersistence::default());
187 let controller = GameController::new(game, persistence).init();
188
189 let command = Command::Game(GameCommand::NextChallenge);
190 controller.publish_command(command);
191
192 let game_state = controller.game_state.lock().unwrap();
193 assert_eq!(game_state.current_challenge_index, 1);
194 }
195
196 #[test]
197 fn test_save_and_load_game_state() {
198 let game = Game::default();
199 let persistence = Arc::new(MemoryPersistence::default());
200 let controller = GameController::new(game, persistence).init();
201
202 let command = Command::Game(GameCommand::NextChallenge);
204 controller.publish_command(command);
205
206 let save_result = controller.save_game_state();
208 assert!(save_result.is_ok());
209
210 let command = Command::Game(GameCommand::NextChallenge);
212 controller.publish_command(command);
213
214 let load_result = controller.load_game_state();
216 assert!(load_result.is_ok());
217
218 let game_state = controller.game_state.lock().unwrap();
220 assert_eq!(game_state.current_challenge_index, 1);
221 }
222
223 #[test]
224 fn test_getters() {
225 let game = Game::default();
226 let persistence = Arc::new(MemoryPersistence::default());
227 let mut controller = GameController::new(game, persistence);
228
229 let game_state = controller.game_state();
231 let event_bus = controller.event_bus();
232 let command_bus = controller.command_bus();
233
234 assert_eq!(game_state.lock().unwrap().current_challenge_index, 0);
236 assert_eq!(event_bus.listeners.lock().unwrap().len(), 0);
237 assert_eq!(command_bus.listeners.lock().unwrap().len(), 0);
238
239 {
241 let event_bus_mut = controller.event_bus_mut();
242 assert_eq!(event_bus_mut.listeners.lock().unwrap().len(), 0);
243 }
244 {
245 let command_bus_mut = controller.command_bus_mut();
246 assert_eq!(command_bus_mut.listeners.lock().unwrap().len(), 0);
247 }
248 }
249}