1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::collections::HashMap;
use std::fmt::Debug;

use serde::Serialize;
use serde::de::DeserializeOwned;
use serde_json::Value;
use serde_json;

use game::{GameWrapper, Game};
use errors::GameError;
use flow::UserFlow;
use state::UserState;
use actions::Action;

pub trait Store {
    fn dispatch(&mut self, action: Action) -> Result<(), GameError>;
    fn forfeit(&mut self, GameError);
    fn get_state(&self) -> HashMap<u16, Value>;
    fn get_move_names(&self) -> Vec<&'static str>;
    fn get_player_id(&self) -> u16;
    fn get_active_players(&self) -> Vec<u16>;
    fn is_game_over(&self) -> bool;
}

pub trait StoreFactory {
    fn create(&self, player_id: u16, players: Vec<u16>,
              multiplayer: bool, server: bool, initialize: bool, seed: Option<u128>) -> Box<dyn Store>;
}

pub trait InnerStore<S: Default, T> {
    fn new (game: Game<T>, player_id: u16, players: Vec<u16>,
            multiplayer: bool, server: bool, initialize: bool) -> Self;
    fn dispatch(&mut self, action: Action) -> Result<(), GameError>;
    fn peek(&self) -> &UserState<S>;
    fn reset(&mut self, state: UserState<S>);
    fn forfeit(&mut self, GameError);
    fn get_move_names(&self) -> Vec<&'static str>;
    fn get_player_id(&self) -> u16;
    fn get_active_players(&self) -> Vec<u16>;
    fn is_game_over(&self) -> bool;
}

pub struct StoreImpl<S: Default, T> {
    pub wrapper: GameWrapper<S, T>,
}

impl<S: Debug + Clone + Serialize + DeserializeOwned + Default, T: UserFlow<S>> InnerStore<S, T> for StoreImpl<S, T> {
    fn new (game: Game<T>, player_id: u16, players: Vec<u16>,
            multiplayer: bool, server: bool, initialize: bool) -> Self {
        let wrapper = GameWrapper::new(game, player_id, players, multiplayer, server, initialize);
        StoreImpl {
            wrapper
        }
    }

    fn dispatch(&mut self, action: Action) -> Result<(), GameError> {
        self.wrapper.handle_action(action)
    }

    fn peek(&self) -> &UserState<S> {
        self.wrapper.peek()
    }

    fn reset(&mut self, state: UserState<S>) {
        self.wrapper.reset(state)
    }

    fn get_move_names(&self) -> Vec<&'static str> {
        self.wrapper.game.flow.list_moves()
    }

    fn get_player_id(&self) -> u16 {
        self.wrapper.player_id
    }

    fn get_active_players(&self) -> Vec<u16> {
        self.wrapper.get_active_players()
    }

    fn is_game_over(&self) -> bool {
        self.wrapper.is_game_over()
    }

    fn forfeit(&mut self, error: GameError) {
        self.wrapper.forfeit(error)
    }
}

impl<S: Default + Debug + Clone + Serialize + DeserializeOwned, T: UserFlow<S>> Store for StoreImpl<S, T> {
    fn dispatch(&mut self, action: Action) -> Result<(), GameError> {
        InnerStore::dispatch(self, action)
    }

    fn get_state(&self) -> HashMap<u16, Value> {
        transform_state(self.wrapper.get_states())
    }

    fn get_move_names(&self) -> Vec<&'static str> {
        InnerStore::get_move_names(self)
    }

    fn get_player_id(&self) -> u16 {
        InnerStore::get_player_id(self)
    }

    fn get_active_players(&self) -> Vec<u16> {
        InnerStore::get_active_players(self)
    }

    fn is_game_over(&self) -> bool {
        InnerStore::is_game_over(self)
    }

    fn forfeit(&mut self, error: GameError) {
        InnerStore::forfeit(self, error)
    }
}

fn transform_state<S: Serialize + Default> (inner_state: HashMap<u16, UserState<S>>) -> HashMap<u16, Value> {
    // TODO: Error handling on the unwrap?
    inner_state.iter()
        .map(|(k, v)| (*k, serde_json::to_value(v).unwrap()))
        .collect()
}