use rhai::{Dynamic, Engine, Scope, AST}; use super::engine::setup_engine; use super::types::{CardId, Player, RhaiResult}; pub struct Functions { // // turn_start(data, player) -> data // pub turn_start: Option RhaiResult + Send>>, // // turn_end(data, current_player) -> [data, next_player] // pub turn_end: Box RhaiResult + Send>, // // on_click(data, card, action_author, current_player) -> [data, turn_end] // pub on_click: Box RhaiResult + Send>, ast: AST, engine: Engine, has_turn_start: bool, } impl Functions { pub fn new(fns: &[String], ast: AST, game_name: &str) -> Self { if !fns.contains(&"turn_end".to_string()) { panic!( "Expected turn_end function in game code for the game \"{}\"", game_name ) }; if !fns.contains(&"on_click".to_string()) { panic!( "Expected on_click function in game code for the game \"{}\"", game_name ) }; let has_turn_start = fns.contains(&"turn_start".to_string()); let engine = setup_engine(); Self { engine, ast, has_turn_start, } } pub fn turn_start(&self, d: Dynamic, p: Player) -> Option> { if self.has_turn_start { Some( self.engine .call_fn(&mut Scope::new(), &self.ast, "turn_start", (d, p)), ) } else { None } } pub fn turn_end(&self, d: Dynamic, p: Player) -> RhaiResult { self.engine .call_fn(&mut Scope::new(), &self.ast, "turn_end", (d, p)) // TODO Check if the game has ended (With variable in the scope) } pub fn on_click( &self, data: Dynamic, card: CardId, action_author: Player, current_turn: Player, ) -> RhaiResult { self.engine.call_fn( &mut Scope::new(), &self.ast, "on_click", (data, card, action_author, current_turn), ) } }