hohav / peppi

Rust parser for Slippi SSBM replay files
MIT License
37 stars 9 forks source link

Add new handler trait with better abstraction #31

Closed NickCondron closed 1 year ago

NickCondron commented 1 year ago

The usability of event-based parsing is hindered by the Handlers trait functioning at the event-level. This means any implementer has to worry about rollbacks, frame data duplication after character elimination, and handling all sorts of errors. Right now this issue is blocking my progress on stats. I propose to rename Handlers to EventHandler and create a new trait GameHandler

pub trait GameHandler {
    fn game_start(&mut self, _: game::Start) { }
    fn frame<const N: usize>(&mut self, _: Frame<N>) { }
    fn game_end(&mut self, _: game::End) { }
    fn metadata(&mut self, _: Metadata) { }
    fn finalize(&mut self) { }
}

Also a struct Hook that wraps a GameHandler and handles all the events feeding the GameHandler as frames are finalized.

pub struct Hook<H> where H: GameHandler {
    hook: H,
    // ...
}

impl<H> EventHandler for Hook<H> where H: GameHandler { /* ... */ }

That way a user can parse with code like this:

struct DoWhatIWant;
impl GameHandler for DoWhatIWant {
    fn frame<const N: usize>(&mut self, frame: frame::Frame<N>) {
        println!("{:?}", frame);
    }
}

let mut buf = BufReader::new(File::open("game.slp").unwrap());
let mut hook = Hook::new(DoWhatIWant);
peppi::parse(&mut buf, &mut hook, None).unwrap();

This PR is a nearly finished. TODO:

Future work:

NickCondron commented 1 year ago

Closing because I no longer like my solution even though it is in the right direction. I will give another attempt at this problem soon. As mentioned before the poor ergonomics of the Handlers trait is blocking the stats work and the usability of peppi more broadly.