logger impl

This commit is contained in:
Thilo Behnke
2022-05-02 11:29:09 +02:00
parent 9d89c70195
commit ccfe632c17
7 changed files with 98 additions and 25 deletions

View File

@@ -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<dyn Logger>
}
impl CollisionDetector {
pub fn new(logger: Box<dyn Logger>) -> CollisionDetector {
pub fn new(logger_factory: &Box<dyn LoggerFactory>) -> 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<dyn Logger>,
handlers: HashMap<(String, String), fn(Rc<RefCell<Box<dyn GameObject>>>, Rc<RefCell<Box<dyn GameObject>>>)>
}
impl CollisionHandler {
pub fn new() -> CollisionHandler {
pub fn new(logger_factory: &Box<dyn LoggerFactory>) -> 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));

View File

@@ -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<dyn LoggerFactory>,
pub logger: Box<dyn Logger>,
pub width: u16,
pub height: u16,
@@ -35,12 +36,12 @@ pub struct Field {
}
impl Field {
pub fn new(logger: Box<dyn Logger>) -> Field {
pub fn new(logger_factory: Box<dyn LoggerFactory>) -> 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<dyn CollisionRegistry> {
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)
}

View File

@@ -1,11 +1,51 @@
pub mod utils {
pub trait Logger : Clone {
pub trait LoggerFactory {
fn get(&self, name: &str) -> Box<dyn Logger>;
}
pub struct DefaultLoggerFactory {
proto: Box<dyn Logger>
}
impl LoggerFactory for DefaultLoggerFactory {
fn get(&self, name: &str) -> Box<dyn Logger> {
let mut clone = self.proto.box_clone();
clone.set_name(name);
clone
}
}
impl DefaultLoggerFactory {
pub fn new(proto: Box<dyn Logger>) -> Box<dyn LoggerFactory> {
Box::new(DefaultLoggerFactory {proto})
}
pub fn noop() -> Box<dyn LoggerFactory> {
Box::new(DefaultLoggerFactory {proto: Box::new(NoopLogger {})})
}
}
pub trait Logger {
fn box_clone(&self) -> Box<dyn Logger>;
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<dyn Logger> {
Box::new(self.clone())
}
fn set_name(&mut self, name: &str) {}
fn log(&self, msg: &str) {}
}
impl NoopLogger {
fn new() -> Box<dyn Logger> {
Box::new(NoopLogger {})
}
}
}

View File

@@ -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<RefCell<Box<dyn GameObject>>>,
#[case] expected_b: Rc<RefCell<Box<dyn GameObject>>>,
) {
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)

View File

@@ -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<Rc<RefCell<Box<dyn GameObject>>>>,
#[case] expected_collisions: Vec<Collision>,
) {
let detector = CollisionDetector::new();
let logger = DefaultLoggerFactory::noop();
let detector = CollisionDetector::new(&logger);
let res = detector.detect_collisions(objs);
assert_eq!(
res.get_collisions(),

View File

@@ -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<RefCell<Box<dyn GameObject>>> {
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<RefCell<Box
}
fn get_bound(bound: Bound) -> Rc<RefCell<Box<dyn GameObject>>> {
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

View File

@@ -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<dyn Logger> {
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)
}
}