263 lines
8.1 KiB
Rust
Executable File
263 lines
8.1 KiB
Rust
Executable File
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<dyn StaticDataTrait>;
|
|
|
|
pub trait LibrarySettingsTrait {
|
|
fn maximum_level(&self) -> LevelInt;
|
|
}
|
|
|
|
pub type LibrarySettings = Rc<dyn LibrarySettingsTrait>;
|
|
|
|
#[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<StaticDataImpl>,
|
|
move_library: CachedValue<MoveLibrary>,
|
|
item_library: CachedValue<ItemLibrary>,
|
|
species_library: CachedValue<SpeciesLibrary>,
|
|
type_library: CachedValue<Typelibrary>,
|
|
settings: CachedValue<LibrarySettings>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct StaticDataImpl {
|
|
inner: Rc<StaticDataInner>,
|
|
}
|
|
|
|
impl StaticDataImpl {
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub(crate) fn new(reference: ExternRef<StaticDataImpl>) -> 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>) -> Self {
|
|
StaticDataImpl::new(reference)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct LibrarySettingsImpl {
|
|
inner: Rc<LibrarySettingsInner>,
|
|
}
|
|
|
|
struct LibrarySettingsInner {
|
|
maximum_level: CachedValue<LevelInt>,
|
|
}
|
|
|
|
impl LibrarySettingsImpl {
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub(crate) fn new(ptr: ExternRef<LibrarySettingsImpl>) -> 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>) -> Self {
|
|
LibrarySettingsImpl::new(reference)
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
extern "wasm" {
|
|
fn static_data_get_move_library(
|
|
ptr: ExternRef<StaticDataImpl>,
|
|
) -> ExternRef<MoveLibraryImpl>;
|
|
fn static_data_get_item_library(
|
|
ptr: ExternRef<StaticDataImpl>,
|
|
) -> ExternRef<ItemLibraryImpl>;
|
|
fn static_data_get_species_library(
|
|
ptr: ExternRef<StaticDataImpl>,
|
|
) -> ExternRef<SpeciesLibraryImpl>;
|
|
fn static_data_get_type_library(
|
|
ptr: ExternRef<StaticDataImpl>,
|
|
) -> ExternRef<TypeLibraryImpl>;
|
|
fn static_data_get_library_settings(
|
|
ptr: ExternRef<StaticDataImpl>,
|
|
) -> ExternRef<LibrarySettingsImpl>;
|
|
|
|
fn library_settings_get_maximum_level(ptr: ExternRef<LibrarySettingsImpl>) -> LevelInt;
|
|
}
|
|
|
|
pub trait DataLibrary<T>: Cacheable
|
|
where
|
|
T: Clone,
|
|
{
|
|
fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>;
|
|
fn get_self_ref(&self) -> ExternRef<Self>
|
|
where
|
|
Self: Sized;
|
|
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32
|
|
where
|
|
Self: Sized;
|
|
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32
|
|
where
|
|
Self: Sized;
|
|
|
|
fn _from_external_ref_index(index: u32) -> Option<T>
|
|
where
|
|
Self: Sized;
|
|
|
|
fn get(&self, name: &StringKey) -> Option<T>
|
|
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<T>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
self.get_by_hash(get_hash(name))
|
|
}
|
|
|
|
fn get_by_hash(&self, hash: u32) -> Option<T>
|
|
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<T>
|
|
where
|
|
T: Clone,
|
|
{
|
|
fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>;
|
|
fn get_self_ref(&self) -> ExternRef<Self>
|
|
where
|
|
Self: Sized;
|
|
|
|
fn get(&self, name: &StringKey) -> Option<T>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
self.get_cache().read().get(&name.hash()).cloned()
|
|
}
|
|
|
|
fn get_by_hash(&self, hash: u32) -> Option<T>
|
|
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::*;
|