101 lines
3.2 KiB
Rust
101 lines
3.2 KiB
Rust
use paste::paste;
|
|
use std::sync::OnceLock;
|
|
|
|
use super::DataLoadError;
|
|
|
|
macro_rules! template_id {
|
|
($type_name:ident $underlying_type:ident $id_field:ident) => {
|
|
::paste::paste! {
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ::serde::Deserialize, ::serde::Serialize)]
|
|
pub struct [<$type_name ID>]($underlying_type);
|
|
|
|
impl [<$type_name ID>] {
|
|
pub fn new(id: $underlying_type) -> Option<Self> {
|
|
if crate::tables::[<$type_name:snake _template_tb>]::iter().any(|tmpl| tmpl.$id_field.value() == id) {
|
|
Some(Self(id))
|
|
}
|
|
else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn new_unchecked(id: $underlying_type) -> Self {
|
|
Self(id)
|
|
}
|
|
|
|
pub fn value(&self) -> $underlying_type {
|
|
self.0
|
|
}
|
|
|
|
pub fn template(&self) -> &[<$type_name Template>] {
|
|
crate::tables::[<$type_name:snake _template_tb>]::iter().find(|tmpl| tmpl.$id_field == *self).unwrap()
|
|
}
|
|
}
|
|
|
|
impl ::std::fmt::Display for [<$type_name ID>] {
|
|
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
|
f.write_fmt(format_args!("{}", self.0))
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! template_tables {
|
|
($($template_type:ident;)*) => {
|
|
$(paste! {
|
|
mod [<$template_type:snake>];
|
|
pub use [<$template_type:snake>]::*;
|
|
})*
|
|
|
|
$(paste! {
|
|
static [<$template_type:snake:upper _TB>]: OnceLock<Vec<$template_type>> = OnceLock::new();
|
|
})*
|
|
|
|
pub(crate) fn load_tables(filecfg_path: &str) -> Result<(), DataLoadError> {
|
|
$(paste! {
|
|
let file_name = concat!(stringify!($template_type), "Tb.json");
|
|
let path = format!("{filecfg_path}/{file_name}");
|
|
|
|
let data = std::fs::read_to_string(path)?;
|
|
[<$template_type:snake:upper _TB>].set(serde_json::from_str(&data).map_err(|err| DataLoadError::FromJsonError(String::from(stringify!($template_type)), err))?).unwrap();
|
|
})*
|
|
|
|
Ok(())
|
|
}
|
|
|
|
$(paste! {
|
|
pub mod [<$template_type:snake _tb>] {
|
|
pub fn iter() -> ::std::slice::Iter<'static, super::$template_type> {
|
|
super::[<$template_type:snake:upper _TB>].get().unwrap().iter()
|
|
}
|
|
}
|
|
})*
|
|
};
|
|
}
|
|
|
|
template_tables! {
|
|
AvatarBaseTemplate;
|
|
UnlockConfigTemplate;
|
|
SectionConfigTemplate;
|
|
ProcedureConfigTemplate;
|
|
PostGirlConfigTemplate;
|
|
TrainingQuestTemplate;
|
|
WeaponTemplate;
|
|
MainCityObjectTemplate;
|
|
MainCityDefaultObjectTemplate;
|
|
MainCityBgmConfigTemplate;
|
|
ArchiveFileQuestTemplate;
|
|
ArchiveBattleQuestTemplate;
|
|
HollowQuestTemplate;
|
|
HollowConfigTemplate;
|
|
BattleEventConfigTemplate;
|
|
BattleGroupConfigTemplate;
|
|
SubAreaDataTemplate;
|
|
VariableDataTemplate;
|
|
OnceRewardTemplate;
|
|
QuickAccessTemplate;
|
|
QuickFuncTemplate;
|
|
TeleportConfigTemplate;
|
|
ItemTemplate;
|
|
}
|