diff --git a/pong/src/collision.rs b/pong/src/collision.rs index 77909a9..228a1fa 100644 --- a/pong/src/collision.rs +++ b/pong/src/collision.rs @@ -6,14 +6,15 @@ pub mod collision { use std::collections::HashMap; use std::fmt::Debug; use std::rc::Rc; - use crate::utils::utils::Logger; + use crate::utils::utils::{Logger, LoggerFactory}; pub struct CollisionDetector { logger: Box } impl CollisionDetector { - pub fn new(logger: Box) -> CollisionDetector { + pub fn new(logger_factory: &Box) -> CollisionDetector { + let logger = logger_factory.get("collision_detector"); CollisionDetector { logger } @@ -81,14 +82,16 @@ pub mod collision { #[derive(Debug, Eq, PartialEq)] pub struct Collision(pub u16, pub u16); - #[derive(Clone)] pub struct CollisionHandler { + logger: Box, handlers: HashMap<(String, String), fn(Rc>>, Rc>>)> } impl CollisionHandler { - pub fn new() -> CollisionHandler { + pub fn new(logger_factory: &Box) -> CollisionHandler { + let logger = logger_factory.get("collision_handler"); CollisionHandler { + logger, handlers: HashMap::new(), } } @@ -114,6 +117,7 @@ pub mod collision { ) -> bool { let key = (RefCell::borrow(&obj_a).obj_type().to_string(), RefCell::borrow(&obj_b).obj_type().to_string()); if !self.handlers.contains_key(&key) { + self.logger.log(&*format!("Found no matching collision handler: {:?}", key)); return false; } self.logger.log(&*format!("Handling collision between {:?} and {:?}", obj_a, obj_b)); diff --git a/pong/src/game_field.rs b/pong/src/game_field.rs index 7847176..3404d44 100644 --- a/pong/src/game_field.rs +++ b/pong/src/game_field.rs @@ -6,7 +6,7 @@ use crate::game_object::game_object::{DefaultGameObject, GameObject}; use crate::geom::geom::Vector; use crate::geom::shape::{Shape, ShapeType}; use crate::pong::pong_collisions::{handle_ball_bounds_collision, handle_player_ball_collision}; -use crate::utils::utils::{Logger, NoopLogger}; +use crate::utils::utils::{DefaultLoggerFactory, Logger, LoggerFactory, NoopLogger}; use std::borrow::{Borrow, BorrowMut}; use std::cell::{Cell, Ref, RefCell, RefMut}; use std::collections::HashMap; @@ -26,6 +26,7 @@ pub struct Input { } pub struct Field { + pub logger_factory: Box, pub logger: Box, pub width: u16, pub height: u16, @@ -35,12 +36,12 @@ pub struct Field { } impl Field { - pub fn new(logger: Box) -> Field { + pub fn new(logger_factory: Box) -> Field { let width = 800; let height = 600; let mut field = Field { - logger, + logger: logger_factory.get("game_field"), width, height, objs: DefaultGameObject::bounds(width, height) @@ -48,7 +49,8 @@ impl Field { .map(|b| Rc::new(RefCell::new(b.inner()))) .collect(), collisions: Box::new(Collisions::new(vec![])), - collision_handler: CollisionHandler::new(), + collision_handler: CollisionHandler::new(&logger_factory), + logger_factory }; field.add_player(0, 0 + width / 20, height / 2); @@ -74,8 +76,9 @@ impl Field { } pub fn mock(width: u16, height: u16) -> Field { + let logger_factory = DefaultLoggerFactory::new(Box::new(NoopLogger{})); Field { - logger: Box::new(NoopLogger {}), + logger: logger_factory.get("game_field"), width, height, objs: DefaultGameObject::bounds(width, height) @@ -83,7 +86,8 @@ impl Field { .map(|b| Rc::new(RefCell::new(b.inner()))) .collect(), collisions: Box::new(Collisions::new(vec![])), - collision_handler: CollisionHandler::new(), + collision_handler: CollisionHandler::new(&logger_factory), + logger_factory, } } @@ -142,8 +146,10 @@ impl Field { let collisions = self.get_collisions(); - let collision_handler = self.collision_handler.clone(); - for collision in collisions.get_collisions().iter() { + let collision_handler = &self.collision_handler; + let registered_collisions = collisions.get_collisions(); + self.logger.log(&*format!("Found {} collisions: {:?}", registered_collisions.len(), registered_collisions)); + for collision in registered_collisions.iter() { let objs = &self.objs; let obj_a = objs.iter().find(|o| RefCell::borrow(o).id() == collision.0).unwrap().clone(); let obj_b = objs.iter().find(|o| RefCell::borrow(o).id() == collision.1).unwrap().clone(); @@ -153,7 +159,7 @@ impl Field { fn get_collisions(&self) -> Box { let objs = self.objs.iter().map(|o| o.clone()).collect(); - let collision_detector = CollisionDetector::new(self.logger.clone()); + let collision_detector = CollisionDetector::new(&self.logger_factory); collision_detector.detect_collisions(objs) } diff --git a/pong/src/utils.rs b/pong/src/utils.rs index af07ceb..c1f3b9a 100644 --- a/pong/src/utils.rs +++ b/pong/src/utils.rs @@ -1,11 +1,51 @@ pub mod utils { - pub trait Logger : Clone { + pub trait LoggerFactory { + fn get(&self, name: &str) -> Box; + } + + pub struct DefaultLoggerFactory { + proto: Box + } + + impl LoggerFactory for DefaultLoggerFactory { + fn get(&self, name: &str) -> Box { + let mut clone = self.proto.box_clone(); + clone.set_name(name); + clone + } + } + + impl DefaultLoggerFactory { + pub fn new(proto: Box) -> Box { + Box::new(DefaultLoggerFactory {proto}) + } + pub fn noop() -> Box { + Box::new(DefaultLoggerFactory {proto: Box::new(NoopLogger {})}) + } + } + + pub trait Logger { + fn box_clone(&self) -> Box; + fn set_name(&mut self, name: &str); fn log(&self, msg: &str); } #[derive(Clone)] pub struct NoopLogger {} + impl Logger for NoopLogger { + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } + + fn set_name(&mut self, name: &str) {} + fn log(&self, msg: &str) {} } + + impl NoopLogger { + fn new() -> Box { + Box::new(NoopLogger {}) + } + } } diff --git a/pong/tests/collision_handler_test.rs b/pong/tests/collision_handler_test.rs index dc83f58..22c5d71 100644 --- a/pong/tests/collision_handler_test.rs +++ b/pong/tests/collision_handler_test.rs @@ -7,6 +7,7 @@ use rstest::rstest; use std::borrow::{Borrow, BorrowMut}; use std::cell::RefCell; use std::rc::Rc; +use pong::utils::utils::DefaultLoggerFactory; #[rstest] #[case( @@ -71,7 +72,8 @@ pub fn should_handle_collision( #[case] expected_a: Rc>>, #[case] expected_b: Rc>>, ) { - let mut handler = CollisionHandler::new(); + let logger = DefaultLoggerFactory::noop(); + let mut handler = CollisionHandler::new(&logger); handler.register((String::from("obj"), String::from("obj")), |a, b| {}); let res = handler.handle(obj_a, obj_b); assert_eq!(true, res) diff --git a/pong/tests/collision_tests.rs b/pong/tests/collision_tests.rs index db08385..2a28ded 100644 --- a/pong/tests/collision_tests.rs +++ b/pong/tests/collision_tests.rs @@ -5,6 +5,7 @@ use pong::geom::shape::ShapeType; use rstest::rstest; use std::cell::{Ref, RefCell}; use std::rc::Rc; +use pong::utils::utils::DefaultLoggerFactory; #[rstest] #[case(vec![], vec![])] @@ -40,7 +41,8 @@ pub fn should_detect_collisions( #[case] objs: Vec>>>, #[case] expected_collisions: Vec, ) { - let detector = CollisionDetector::new(); + let logger = DefaultLoggerFactory::noop(); + let detector = CollisionDetector::new(&logger); let res = detector.detect_collisions(objs); assert_eq!( res.get_collisions(), diff --git a/pong/tests/pong_tests.rs b/pong/tests/pong_tests.rs index 1af47d9..e1aa74d 100644 --- a/pong/tests/pong_tests.rs +++ b/pong/tests/pong_tests.rs @@ -5,7 +5,7 @@ use pong::game_field::{Bound, Field}; use pong::game_object::game_object::{DefaultGameObject, GameObject}; use pong::geom::geom::Vector; use pong::pong::pong_collisions::handle_player_bound_collision; -use pong::utils::utils::NoopLogger; +use pong::utils::utils::{DefaultLoggerFactory, NoopLogger}; #[rstest] #[case( @@ -60,7 +60,8 @@ pub fn should_correctly_handle_player_bounds_collision( } fn create_player(id: u16, x: u16, y: u16, orientation: Vector) -> Rc>> { - let field = Field::new(Box::new(NoopLogger{})); + let logger = DefaultLoggerFactory::noop(); + let field = Field::new(logger); let mut player = DefaultGameObject::player(id, x, y, &field); let player_orientation = player.orientation_mut(); player_orientation.x = orientation.x; @@ -69,7 +70,8 @@ fn create_player(id: u16, x: u16, y: u16, orientation: Vector) -> Rc Rc>> { - let field = Field::new(Box::new(NoopLogger{})); + let logger = DefaultLoggerFactory::noop(); + let field = Field::new(logger); let bounds = DefaultGameObject::bounds(field.width, field.height); return Rc::new(RefCell::new(bounds.into_iter().find(|b| { b.0 == bound diff --git a/src/lib.rs b/src/lib.rs index b8d2b8a..8fe42bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ use pong::game_field::{Field, Input, InputType}; use pong::game_object::game_object::GameObject; use pong::geom::geom::Vector; use pong::geom::shape::ShapeType; -use pong::utils::utils::Logger; +use pong::utils::utils::{DefaultLoggerFactory, Logger}; use serde::{Deserialize, Serialize}; use serde_json::json; use std::cmp::{max, min}; @@ -102,7 +102,7 @@ pub struct FieldWrapper { #[wasm_bindgen] impl FieldWrapper { pub fn new() -> FieldWrapper { - let field = Field::new(Box::new(WasmLogger {})); + let field = Field::new(DefaultLoggerFactory::new(Box::new(WasmLogger::root()))); FieldWrapper { field } } @@ -147,9 +147,26 @@ impl FieldWrapper { } #[derive(Clone)] -pub struct WasmLogger {} -impl Logger for WasmLogger { - fn log(&self, msg: &str) { - log!("{}", msg) +pub struct WasmLogger { + name: String +} + +impl WasmLogger { + pub fn root() -> WasmLogger { + WasmLogger {name: String::from("root")} + } +} + +impl Logger for WasmLogger { + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } + + fn set_name(&mut self, name: &str) { + self.name = String::from(name); + } + + fn log(&self, msg: &str) { + log!("[{}] {}", self.name, msg) } }