use std::{
collections::HashMap,
ops::{Deref, DerefMut},
};
use crate::core::PageId;
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GameState {
inner: HashMap<PageId, PageMap>,
}
impl GameState {
pub fn inc(&mut self, key: &InternalKey) {
let (chapter_id, entry_key) = key;
let chapter = self
.inner
.entry(chapter_id.clone())
.or_insert_with(|| PageMap {
inner: HashMap::new(),
});
chapter
.inner
.entry(entry_key.clone())
.and_modify(|v| *v += 1) .or_insert(0);
}
pub fn insert(&mut self, key: InternalKey, value: u64) {
let (chapter_id, entry_key) = key;
let chapter = self.inner.entry(chapter_id).or_insert_with(|| PageMap {
inner: HashMap::new(),
});
chapter.inner.insert(entry_key, value);
}
pub fn remove(&mut self, key: &InternalKey) {
let (chapter_id, entry_key) = key;
if let Some(chapter) = self.inner.get_mut(chapter_id) {
chapter.inner.remove(&entry_key);
if chapter.inner.is_empty() {
self.inner.remove(chapter_id);
}
}
}
pub fn set_bit(&mut self, key: InternalKey, pos: u8) {
let (chapter_id, entry_key) = key;
let chapter = self.inner.entry(chapter_id).or_insert_with(|| PageMap {
inner: HashMap::new(),
});
let current = chapter.inner.get(&entry_key).copied().unwrap_or(0);
let updated = current | (1 << pos);
chapter.inner.insert(entry_key, updated);
}
pub fn get_page(&mut self, pageid: impl Into<PageId>) -> &PageMap {
self.inner.entry(pageid.into()).or_default()
}
pub fn get_page_mut(&mut self, pageid: impl Into<PageId>) -> &mut PageMap {
self.inner.entry(pageid.into()).or_default()
}
}
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PageMap {
inner: HashMap<PageKey, u64>,
}
pub type InternalKey = (PageId, PageKey);
pub type PageKey = u64;
impl GameState {
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
}
impl Deref for PageMap {
type Target = HashMap<PageKey, u64>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for PageMap {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}