use std::collections::HashMap;
use std::cell::RefCell;
use std::rc::Rc;
use linenoise;
use command::GameCommand;
use scenario::{Loader, Scenario};
use util::TICK;
use util::LOAD;
pub struct GameMaster<S> {
current: Rc<RefCell<Scenario<S>>>,
loader: Rc<RefCell<Loader<S>>>,
state: Rc<RefCell<S>>,
commands: HashMap<String, Box<GameCommand<S>>>,
}
impl <S> GameMaster <S> {
pub fn new(state: Rc<RefCell<S>>, start: Rc<RefCell<Scenario<S>>>)
-> GameMaster<S> {
let mut loader = Loader::new();
loader.set_scenario(start.clone());
GameMaster {
current: start,
loader: Rc::new(RefCell::new(loader)),
state: state,
commands: HashMap::new(),
}
}
pub fn add_command(&mut self, name: String, command: Box<GameCommand<S>>) {
self.commands.insert(name, command);
}
pub fn start_game(&mut self) {
self.main_loop();
}
fn load_scenario(&mut self) -> i32 {
self.current = self.loader.borrow().get_scenario();
println!(" ");
self.current.borrow().load(&self.state, &self.loader)
}
fn exec_game_command(&mut self, command: &str) -> i32 {
let game_command = match self.commands.get(command) {
Some(f) => { f },
None => return TICK
};
game_command.execute(&self.state, &self.loader)
}
fn exec_current_scenario(&mut self, command: &str) -> i32 {
let result = self.current.borrow().do_action(
&command.trim(),
&self.state,
&self.loader
);
result
}
fn main_loop(&mut self) {
linenoise::set_multiline(0);
let mut input = String::new();
let mut command;
self.current.borrow().load(&self.state, &self.loader);
loop {
input = match linenoise::input("\n> ") {
Some(i) => { i },
None => { continue }
};
command = input.clone();
println!(" ");
self.exec_game_command(&command.trim());
match self.exec_game_command(&command.trim()) {
LOAD => { self.load_scenario(); continue },
_ => {}
};
match self.exec_current_scenario(&command.trim()) {
LOAD => { self.load_scenario(); },
_ => {}
};
}
}
}