transfer data to js wip

This commit is contained in:
Robin Appelman 2020-01-31 00:37:07 +01:00
commit 59c410566e
9 changed files with 338 additions and 59 deletions

View file

@ -3,7 +3,8 @@
#![macro_use]
use crate::state::ParsedDemo;
use tf_demo_parser::demo::parser::gamestateanalyser::GameStateAnalyser;
use tf_demo_parser::demo::parser::gamestateanalyser::{GameStateAnalyser, World};
use tf_demo_parser::demo::vector::Vector;
use tf_demo_parser::{Demo, DemoParser, ParseError};
use wasm_bindgen::prelude::*;
@ -14,14 +15,77 @@ macro_rules! log {
}
#[wasm_bindgen]
pub fn parse_demo(buffer: Box<[u8]>) -> Result<ParsedDemo, JsValue> {
let buffer = buffer.into_vec();
let parsed = parse_demo_inner(buffer).map_err(|e| JsValue::from(e.to_string()))?;
Ok(parsed)
#[derive(Debug, Clone, Copy)]
pub struct XY {
pub x: f32,
pub y: f32,
}
pub fn parse_demo_inner(buffer: Vec<u8>) -> Result<ParsedDemo, ParseError> {
impl From<Vector> for XY {
fn from(vec: Vector) -> Self {
XY { x: vec.x, y: vec.y }
}
}
#[wasm_bindgen]
#[derive(Debug, Clone, Copy)]
pub struct WorldBoundaries {
pub boundary_min: XY,
pub boundary_max: XY,
}
impl From<World> for WorldBoundaries {
fn from(world: World) -> Self {
WorldBoundaries {
boundary_min: world.boundary_min.into(),
boundary_max: world.boundary_max.into(),
}
}
}
#[wasm_bindgen]
pub struct FlatState {
player_count: usize,
data: Box<[u8]>,
boundaries: WorldBoundaries,
}
impl FlatState {
pub fn new(parsed: ParsedDemo, world: World) -> Self {
FlatState {
player_count: parsed.players.len(),
boundaries: world.into(),
data: parsed.flat().into_boxed_slice(),
}
}
}
#[wasm_bindgen]
pub fn parse_demo(buffer: Box<[u8]>) -> Result<FlatState, JsValue> {
let buffer = buffer.into_vec();
let (parsed, world) = parse_demo_inner(buffer).map_err(|e| JsValue::from(e.to_string()))?;
let world = world.ok_or_else(|| JsValue::from_str("No world defined in demo"))?;
Ok(FlatState::new(parsed, world))
}
#[wasm_bindgen]
pub fn get_boundaries(state: &FlatState) -> WorldBoundaries {
state.boundaries.clone()
}
#[wasm_bindgen]
pub fn get_player_count(state: &FlatState) -> usize {
state.player_count
}
#[wasm_bindgen]
pub fn get_data(state: FlatState) -> Box<[u8]> {
state.data
}
pub fn parse_demo_inner(buffer: Vec<u8>) -> Result<(ParsedDemo, Option<World>), ParseError> {
let demo = Demo::new(buffer);
let parser = DemoParser::new_with_analyser(demo.get_stream(), GameStateAnalyser::default());
let (_header, mut ticker) = parser.ticker()?;
@ -37,7 +101,8 @@ pub fn parse_demo_inner(buffer: Vec<u8>) -> Result<ParsedDemo, ParseError> {
skip = !skip;
}
Ok(parsed_demo)
let world: Option<&World> = ticker.state().world.as_ref();
Ok((parsed_demo, world.map(|w| w.clone())))
}
// This is like the `main` function, except for JavaScript.

View file

@ -1,6 +1,5 @@
use tf_demo_parser::demo::parser::gamestateanalyser::{Class, GameState, Team, World};
use tf_demo_parser::demo::vector::VectorXY;
use wasm_bindgen::prelude::*;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Angle(u8);
@ -19,11 +18,10 @@ impl From<Angle> for f32 {
}
}
#[wasm_bindgen]
#[derive(Debug, Clone, Default)]
pub struct ParsedDemo {
tick: usize,
players: Vec<Vec<u8>>,
pub tick: usize,
pub players: Vec<Vec<u8>>,
}
impl ParsedDemo {
@ -61,6 +59,13 @@ impl ParsedDemo {
.iter()
.fold(0, |size, player| size + player.len())
}
pub fn flat(self) -> Vec<u8> {
self.players
.into_iter()
.flat_map(|player| player.into_iter())
.collect()
}
}
#[derive(Debug, Default, Clone, PartialEq)]