konnektoren_core/controller/
game_controller.rs

1use 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    // Getters for internal components
23    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        // Initialize plugins before creating Arc
72        if let Err(e) = self.plugin_manager.init_plugins() {
73            log::error!("Error initializing plugins: {:?}", e);
74        }
75
76        // Create Arc after initialization
77        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        // Cast Arc<GameController> to Arc<dyn GameControllerTrait>
98        let controller_trait: Arc<dyn GameControllerTrait> = controller.clone();
99
100        // Load plugins with the trait object
101        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    // Getter for game_state
152    fn game_state(&self) -> &Arc<Mutex<GameState>> {
153        &self.game_state
154    }
155
156    // Getter for event_bus
157    fn event_bus(&self) -> &EventBus {
158        &self.event_bus
159    }
160
161    // Mutable getter for event_bus
162    fn event_bus_mut(&mut self) -> &mut EventBus {
163        &mut self.event_bus
164    }
165
166    // Getter for command_bus
167    fn command_bus(&self) -> &CommandBus {
168        &self.command_bus
169    }
170
171    // Mutable getter for command_bus
172    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        // Modify the game state
203        let command = Command::Game(GameCommand::NextChallenge);
204        controller.publish_command(command);
205
206        // Save the game state
207        let save_result = controller.save_game_state();
208        assert!(save_result.is_ok());
209
210        // Modify the game state again
211        let command = Command::Game(GameCommand::NextChallenge);
212        controller.publish_command(command);
213
214        // Load the saved game state
215        let load_result = controller.load_game_state();
216        assert!(load_result.is_ok());
217
218        // Check if the loaded state matches the saved state
219        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        // Using immutable getters
230        let game_state = controller.game_state();
231        let event_bus = controller.event_bus();
232        let command_bus = controller.command_bus();
233
234        // Check immutable getters
235        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        // Using mutable getters
240        {
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}