use wasm_bindgen::prelude::*;
use crate::game::context::GameContext;
use crate::game::play::{Game as CoreGame, GameSimulator};
use crate::wasm::play::{Drive, Play};
use crate::wasm::rng::WasmRng;
use crate::wasm::team::WasmFootballTeam;
#[wasm_bindgen(js_name = "Game")]
pub struct WasmGame {
inner: CoreGame,
}
#[wasm_bindgen(js_class = "Game")]
impl WasmGame {
#[wasm_bindgen(constructor)]
pub fn new() -> WasmGame {
WasmGame {
inner: CoreGame::new(),
}
}
#[wasm_bindgen(getter)]
pub fn complete(&self) -> bool {
self.inner.complete()
}
#[wasm_bindgen(getter, js_name = "driveCount")]
pub fn drive_count(&self) -> usize {
self.inner.drives().len()
}
#[wasm_bindgen(getter, js_name = "playCount")]
pub fn play_count(&self) -> usize {
self.inner.drives().iter().map(|d| d.plays().len()).sum()
}
#[wasm_bindgen(js_name = "getDrive")]
pub fn get_drive(&self, index: usize) -> Result<Drive, JsError> {
self.inner
.drives()
.get(index)
.map(Drive::from)
.ok_or_else(|| JsError::new(&format!("Drive {} not found", index)))
}
#[wasm_bindgen(js_name = "getLatestPlay")]
pub fn get_latest_play(&self) -> Option<Play> {
self.inner
.drives()
.last()
.and_then(|d| d.plays().last())
.map(Play::from)
}
#[wasm_bindgen(js_name = "homeStats")]
pub fn home_stats(&self) -> Result<JsValue, JsError> {
let stats = self.inner.home_stats();
serde_wasm_bindgen::to_value(&stats).map_err(|e| JsError::new(&e.to_string()))
}
#[wasm_bindgen(js_name = "awayStats")]
pub fn away_stats(&self) -> Result<JsValue, JsError> {
let stats = self.inner.away_stats();
serde_wasm_bindgen::to_value(&stats).map_err(|e| JsError::new(&e.to_string()))
}
#[wasm_bindgen(js_name = "toJSON")]
pub fn to_json(&self) -> Result<JsValue, JsError> {
serde_wasm_bindgen::to_value(&self.inner).map_err(|e| JsError::new(&e.to_string()))
}
}
impl Default for WasmGame {
fn default() -> Self {
Self::new()
}
}
impl WasmGame {
pub fn inner(&self) -> &CoreGame {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut CoreGame {
&mut self.inner
}
}
#[wasm_bindgen(js_name = "GameSimulator")]
pub struct WasmGameSimulator {
inner: GameSimulator,
}
#[wasm_bindgen(js_class = "GameSimulator")]
impl WasmGameSimulator {
#[wasm_bindgen(constructor)]
pub fn new() -> WasmGameSimulator {
WasmGameSimulator {
inner: GameSimulator::new(),
}
}
#[wasm_bindgen(js_name = "simPlay")]
pub fn sim_play(
&self,
home: &WasmFootballTeam,
away: &WasmFootballTeam,
context: GameContext,
game: &mut WasmGame,
rng: &mut WasmRng,
) -> Result<GameContext, JsError> {
self.inner
.sim_play(
home.inner(),
away.inner(),
context,
&mut game.inner,
rng.inner_mut(),
)
.map_err(|e| JsError::new(&e))
}
#[wasm_bindgen(js_name = "simDrive")]
pub fn sim_drive(
&self,
home: &WasmFootballTeam,
away: &WasmFootballTeam,
context: GameContext,
game: &mut WasmGame,
rng: &mut WasmRng,
) -> Result<GameContext, JsError> {
self.inner
.sim_drive(
home.inner(),
away.inner(),
context,
&mut game.inner,
rng.inner_mut(),
)
.map_err(|e| JsError::new(&e))
}
#[wasm_bindgen(js_name = "simGame")]
pub fn sim_game(
&self,
home: &WasmFootballTeam,
away: &WasmFootballTeam,
context: GameContext,
game: &mut WasmGame,
rng: &mut WasmRng,
) -> Result<GameContext, JsError> {
self.inner
.sim_game(
home.inner(),
away.inner(),
context,
&mut game.inner,
rng.inner_mut(),
)
.map_err(|e| JsError::new(&e))
}
}
impl Default for WasmGameSimulator {
fn default() -> Self {
Self::new()
}
}
#[wasm_bindgen(js_name = "createGameContext")]
pub fn create_game_context() -> GameContext {
GameContext::new()
}