mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-07-11 02:29:25 +00:00
logger impl
This commit is contained in:
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
29
src/lib.rs
29
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<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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user