use crate::dict::{DictEntry, DictKey, DictStore};
use crate::entity_table::EntityMeta;
use crate::object::{EntityId, PsObject};
pub struct DualDictStore {
pub global: DictStore,
pub local: DictStore,
}
impl DualDictStore {
pub fn new() -> Self {
Self {
global: DictStore::new(),
local: DictStore::new(),
}
}
#[inline]
fn store(&self, entity: EntityId) -> &DictStore {
if entity.is_global() {
&self.global
} else {
&self.local
}
}
#[inline]
fn store_mut(&mut self, entity: EntityId) -> &mut DictStore {
if entity.is_global() {
&mut self.global
} else {
&mut self.local
}
}
pub fn allocate(&mut self, max_length: usize, name: &[u8]) -> EntityId {
self.local.allocate(max_length, name)
}
pub fn allocate_with(
&mut self,
max_length: usize,
name: &[u8],
save_level: u16,
global: bool,
created_after_save: u32,
) -> EntityId {
if global {
self.global
.allocate_with(max_length, name, save_level, global, created_after_save)
} else {
self.local
.allocate_with(max_length, name, save_level, global, created_after_save)
}
}
#[inline]
pub fn get(&self, entity: EntityId, key: &DictKey) -> Option<PsObject> {
self.store(entity).get(entity, key)
}
pub fn put(&mut self, entity: EntityId, key: DictKey, value: PsObject) {
self.store_mut(entity).put(entity, key, value);
}
pub fn known(&self, entity: EntityId, key: &DictKey) -> bool {
self.store(entity).known(entity, key)
}
pub fn get_name(&self, entity: EntityId) -> &[u8] {
self.store(entity).get_name(entity)
}
pub fn set_name(&mut self, entity: EntityId, name: &[u8]) {
self.store_mut(entity).set_name(entity, name);
}
pub fn length(&self, entity: EntityId) -> usize {
self.store(entity).length(entity)
}
pub fn max_length(&self, entity: EntityId) -> usize {
self.store(entity).max_length(entity)
}
pub fn remove(&mut self, entity: EntityId, key: &DictKey) {
self.store_mut(entity).remove(entity, key);
}
pub fn entry(&self, entity: EntityId) -> &DictEntry {
self.store(entity).entry(entity)
}
pub fn entry_mut(&mut self, entity: EntityId) -> &mut DictEntry {
self.store_mut(entity).entry_mut(entity)
}
pub fn keys(&self, entity: EntityId) -> impl Iterator<Item = &DictKey> {
self.store(entity).keys(entity)
}
pub fn access(&self, entity: EntityId) -> u8 {
self.store(entity).access(entity)
}
#[inline]
pub fn require_read(&self, entity: EntityId) -> Result<(), crate::error::PsError> {
self.store(entity).require_read(entity)
}
#[inline]
pub fn require_write(&self, entity: EntityId) -> Result<(), crate::error::PsError> {
self.store(entity).require_write(entity)
}
pub fn set_access(&mut self, entity: EntityId, access: u8) {
self.store_mut(entity).set_access(entity, access);
}
pub fn cow_copy(&mut self, entity: EntityId) -> EntityId {
debug_assert!(!entity.is_global(), "COW copy on global entity");
self.local.cow_copy(entity)
}
pub fn swap_offsets(&mut self, a: EntityId, b: EntityId) {
debug_assert!(
!a.is_global() && !b.is_global(),
"swap_offsets on global entity"
);
self.local.swap_offsets(a, b);
}
pub fn entity_meta(&self, entity: EntityId) -> &EntityMeta {
self.store(entity).entities.get(entity)
}
pub fn entity_meta_mut(&mut self, entity: EntityId) -> &mut EntityMeta {
self.store_mut(entity).entities.get_mut(entity)
}
pub fn entity_count(&self) -> usize {
self.local.entities.len() + self.global.entities.len()
}
pub fn reset_local(&mut self) {
self.local = DictStore::new();
}
}
impl Default for DualDictStore {
fn default() -> Self {
Self::new()
}
}