use crate::app_interface::item_library::ItemLibrary; use crate::app_interface::move_library::MoveLibrary; use crate::app_interface::species_library::SpeciesLibrary; use crate::app_interface::type_library::Typelibrary; use crate::app_interface::LevelInt; use alloc::rc::Rc; pub mod item_library; pub mod move_library; pub mod species_library; pub mod type_library; pub trait StaticDataTrait { fn move_library(&self) -> MoveLibrary; fn item_library(&self) -> ItemLibrary; fn species_library(&self) -> SpeciesLibrary; fn type_library(&self) -> Typelibrary; } pub type StaticData = Rc; pub trait LibrarySettingsTrait { fn maximum_level(&self) -> LevelInt; } pub type LibrarySettings = Rc; #[cfg(not(feature = "mock_data"))] mod implementation { use super::*; use crate::app_interface::item_library::ItemLibraryImpl; use crate::app_interface::move_library::MoveLibraryImpl; use crate::app_interface::species_library::SpeciesLibraryImpl; use crate::app_interface::type_library::TypeLibraryImpl; use crate::app_interface::{get_hash, StringKey}; use crate::handling::cached_value::CachedValue; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; use crate::handling::Cacheable; use crate::{cached_value, cached_value_getters}; use spin::RwLock; struct StaticDataInner { reference: ExternRef, move_library: CachedValue, item_library: CachedValue, species_library: CachedValue, type_library: CachedValue, settings: CachedValue, } #[derive(Clone)] pub struct StaticDataImpl { inner: Rc, } impl StaticDataImpl { #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(StaticDataInner { reference, move_library: cached_value!({ Rc::new(static_data_get_move_library(reference).get_value().unwrap()) }), item_library: cached_value!({ Rc::new(static_data_get_item_library(reference).get_value().unwrap()) }), species_library: cached_value!({ Rc::new( static_data_get_species_library(reference) .get_value() .unwrap(), ) }), type_library: cached_value!({ Rc::new(static_data_get_type_library(reference).get_value().unwrap()) }), settings: cached_value!({ Rc::new( static_data_get_library_settings(reference) .get_value() .unwrap(), ) }), }), }) } } impl StaticDataTrait for StaticDataImpl { cached_value_getters! { fn move_library(&self) -> MoveLibrary; fn item_library(&self) -> ItemLibrary; fn species_library(&self) -> SpeciesLibrary; fn type_library(&self) -> Typelibrary; } } crate::handling::cacheable::cacheable!(StaticDataImpl); #[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for StaticDataImpl { fn from_extern_value(reference: ExternRef) -> Self { StaticDataImpl::new(reference) } } #[derive(Clone)] pub struct LibrarySettingsImpl { inner: Rc, } struct LibrarySettingsInner { maximum_level: CachedValue, } impl LibrarySettingsImpl { #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { Self { inner: Rc::new(LibrarySettingsInner { maximum_level: cached_value!({ library_settings_get_maximum_level(ptr) }), }), } } } impl LibrarySettingsTrait for LibrarySettingsImpl { cached_value_getters! { fn maximum_level(&self) -> LevelInt; } } #[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for LibrarySettingsImpl { fn from_extern_value(reference: ExternRef) -> Self { LibrarySettingsImpl::new(reference) } } #[cfg(not(feature = "mock_data"))] extern "wasm" { fn static_data_get_move_library( ptr: ExternRef, ) -> ExternRef; fn static_data_get_item_library( ptr: ExternRef, ) -> ExternRef; fn static_data_get_species_library( ptr: ExternRef, ) -> ExternRef; fn static_data_get_type_library( ptr: ExternRef, ) -> ExternRef; fn static_data_get_library_settings( ptr: ExternRef, ) -> ExternRef; fn library_settings_get_maximum_level(ptr: ExternRef) -> LevelInt; } pub trait DataLibrary: Cacheable where T: Clone, { fn get_cache(&self) -> &RwLock>; fn get_self_ref(&self) -> ExternRef where Self: Sized; fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> u32 where Self: Sized; fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> u32 where Self: Sized; fn _from_external_ref_index(index: u32) -> Option where Self: Sized; fn get(&self, name: &StringKey) -> Option where Self: Sized, { if let Some(v) = self.get_cache().read().get(&name.hash()) { return Some(v.clone()); } let index = Self::_get_ref_by_name(self.get_self_ref(), name.ptr()); let v = Self::_from_external_ref_index(index); if let Some(v) = &v { self.get_cache().write().insert(name.hash(), v.clone()); } v } fn get_by_str(&self, name: &str) -> Option where Self: Sized, { self.get_by_hash(get_hash(name)) } fn get_by_hash(&self, hash: u32) -> Option where Self: Sized, { if let Some(v) = self.get_cache().read().get(&hash) { return Some(v.clone()); } let index = Self::_get_ref_by_hash(self.get_self_ref(), hash); let v = Self::_from_external_ref_index(index); if let Some(v) = &v { self.get_cache().write().insert(hash, v.clone()); } v } } } #[cfg(not(feature = "mock_data"))] pub use implementation::*; #[cfg(feature = "mock_data")] mod mocked { use crate::app_interface::StringKey; use crate::handling::extern_ref::ExternRef; use spin::RwLock; #[cfg(feature = "mock_data")] pub trait DataLibrary where T: Clone, { fn get_cache(&self) -> &RwLock>; fn get_self_ref(&self) -> ExternRef where Self: Sized; fn get(&self, name: &StringKey) -> Option where Self: Sized, { self.get_cache().read().get(&name.hash()).cloned() } fn get_by_hash(&self, hash: u32) -> Option where Self: Sized, { self.get_cache().read().get(&hash).cloned() } fn insert(&self, hash: u32, item: T) { self.get_cache().write().insert(hash, item); } } } #[cfg(feature = "mock_data")] pub use mocked::*;