IndieGame/config/Table/Tools/Luban/Templates/rust-bin/mod.sbn

281 lines
8.8 KiB
Plaintext
Raw Normal View History

2024-10-11 10:12:15 +08:00
{{~ for mod in __mod.sub_mods ~}}
pub mod {{mod.name}};
{{~end~}}
{{~ if __mod.name != '' ~}}
use super::*;
{{~end~}}
use luban_lib::*;
{{~ for enum in __mod.enums ~}}
{{~ if enum.comment != '' ~}}
///{{enum.comment | html.escape}}
{{~end~}}
{{~ if enum.is_flags ~}}
bitflags::bitflags!{
#[derive(Debug, Hash, Eq, PartialEq)]
pub struct {{enum.name}} : u32 {
{{~ for item in enum.items ~}}
{{~if item.comment_or_alias != '' ~}}
///{{item.comment_or_alias | html.escape}}
{{~end~}}
const {{item.name}} = {{item.int_value}};
{{~end~}}
}
}
{{~else~}}
#[derive(Debug, Hash, Eq, PartialEq, macros::EnumFromNum)]
pub enum {{enum.name}} {
{{~ for item in enum.items ~}}
{{~if item.comment_or_alias != '' ~}}
///{{item.comment_or_alias | html.escape}}
{{~end~}}
{{item.name}} = {{item.value}},
{{~end~}}
{{~if enum.items.empty?~}}
None
{{~end~}}
}
impl From<i32> for {{enum.name}} {
fn from(value: i32) -> Self {
match value {
{{~ for item in enum.items ~}}
{{item.value}} => {{enum.name}}::{{item.name}},
{{~end~}}
_ => panic!("Invalid value for {{enum.name}}:{}", value),
}
}
}
{{~end~}}
{{~end~}}
{{~ for bean in __mod.beans
hierarchy_fields = bean.hierarchy_export_fields
~}}
#[derive(Debug)]
{{~if bean.parent != ''~}}
#[derive(macros::TryIntoBase)]
{{~end~}}
pub struct {{bean.name}} {
{{~ for field in hierarchy_fields ~}}
{{~if field.comment != '' ~}}
/// {{escape_comment field.comment}}
{{~end~}}
pub {{field.name}}: {{declaring_type_name field.ctype}},
{{~end~}}
}
{{~if bean.is_abstract_type~}}
impl {{bean.name}} {
pub fn new(mut buf: &mut ByteBuf) -> Result<std::sync::Arc<AbstractBase>, LubanError> {
let type_id = buf.read_int();
match type_id {
{{~for child in bean.hierarchy_not_abstract_children~}}
{{full_name child}}::__ID__ => Ok(std::sync::Arc::new({{full_name child}}::new(buf)?)),
{{~end~}}
_ => Err(LubanError::Bean(format!("Invalid type for {{bean.name}}:{}", type_id)))
}
}
}
pub trait T{{bean.name}} {
{{~ for field in hierarchy_fields ~}}
fn {{getter_name field.name}}(&self) -> &{{declaring_type_name field.ctype}};
{{~end~}}
}
{{~for child in bean.hierarchy_not_abstract_children~}}
impl {{base_trait_name bean}} for {{full_name child}} {
{{~ for field in hierarchy_fields ~}}
fn {{getter_name field.name}}(&self) -> &{{declaring_type_name field.ctype}} {
&self.{{field.name}}
}
{{~end~}}
}
{{~end~}}
impl<'a> GetBase<'a, &'a dyn {{base_trait_name bean}}> for AbstractBase {
fn get_base(&'a self) -> Result<&'a dyn {{base_trait_name bean}}, LubanError> {
{{~for child in bean.hierarchy_not_abstract_children~}}
let base: Result<&{{full_name child}}, _> = self.try_into();
if let Ok(r) = base {
return Ok(r);
}
{{~end~}}
Err(LubanError::Polymorphic(format!("Invalid type for {{bean.name}}")))
}
}
{{~else~}}
impl {{bean.name}}{
pub fn new(mut buf: &mut ByteBuf) -> Result<{{bean.name}}, LubanError> {
{{~ for field in hierarchy_fields ~}}
{{deserialize field.name 'buf' field.ctype}}
{{~end~}}
Ok({{bean.name}} { {{ for field in hierarchy_fields }}{{field.name}}, {{end}}})
}
pub const __ID__: i32 = {{bean.id}};
}
{{~end~}}
{{~end~}}
{{~ for table in __mod.tables
key_type = declaring_type_name table.key_ttype
if table.value_ttype.def_bean.is_abstract_type
value_type = declaring_type_name table.value_ttype
else
value_type = "std::sync::Arc<"+declaring_type_name table.value_ttype+">"
end
name = table.name
map_type = "std::collections::HashMap<"+key_type+", "+value_type+">"
~}}
{{
func index_type_name
ret (declaring_type_name $0.type)
end
func table_union_map_type_name
ret 'std::collections::HashMap<(' + (array.each table.index_list @index_type_name | array.join ', ') + '), ' + value_type + '>'
end
func table_key_list
varName = $0
indexList = table.index_list |array.each do; ret varName + '.' + (format_property_name __code_style $0.index_field.name); end;
ret array.join indexList ', '
end
func table_param_def_list
paramList = table.index_list |array.each do; ret (declaring_type_name $0.type) + ' ' + $0.index_field.name; end
ret array.join paramList ', '
end
func table_param_name_list
paramList = table.index_list |array.each do; ret $0.index_field.name; end
ret array.join paramList ', '
end
}}
{{~ if table.comment != '' ~}}
///{{table.comment | html.escape}}
{{~end~}}
#[derive(Debug)]
pub struct {{table.name}} {
{{~if table.is_map_table ~}}
pub data_list: Vec<{{value_type}}>,
pub data_map: {{map_type}},
{{~else if table.is_list_table ~}}
pub data_list: Vec<{{value_type}}>,
{{~if table.is_union_index~}}
pub data_map_union: {{table_union_map_type_name}},
{{~else if !table.index_list.empty?~}}
{{~for idx in table.index_list~}}
pub data_map_{{idx.index_field.name}}: std::collections::HashMap<{{declaring_type_name idx.type}}, {{value_type}}>,
{{~end~}}
{{~end~}}
{{~else~}}
pub data: {{declaring_type_name table.value_ttype}},
{{~end~}}
}
{{~if table.is_map_table ~}}
impl {{name}} {
pub fn new(mut buf: ByteBuf) -> Result<std::sync::Arc<{{name}}>, LubanError> {
let mut data_map: {{map_type}} = Default::default();
let mut data_list: Vec<{{value_type}}> = vec![];
for x in (0..buf.read_size()).rev() {
{{deserialize_row "row" "buf" table.value_ttype}}
data_list.push(row.clone());
{{~ if table.value_ttype.def_bean.is_abstract_type ~}}
let key = <AbstractBase as GetBase<&dyn {{base_trait_name table.value_ttype.def_bean}}>>::get_base(std::ops::Deref::deref(&row))?;
data_map.insert(key.{{getter_name table.index_field.name}}().clone(), row.clone());
{{~else~}}
data_map.insert(row.{{table.index_field.name}}.clone(), row.clone());
{{~end~}}
}
Ok(std::sync::Arc::new({{name}} { data_map, data_list }))
}
pub fn get(&self, key: &{{key_type}}) -> Option<{{value_type}}> {
self.data_map.get(key).map(|x| x.clone())
}
}
impl std::ops::Index<{{key_type}}> for {{name}} {
type Output = {{value_type}};
fn index(&self, index: {{key_type}}) -> &Self::Output {
&self.data_map.get(&index).unwrap()
}
}
{{~else if table.is_list_table ~}}
impl {{name}} {
pub fn new(mut buf: ByteBuf) -> Result<std::sync::Arc<{{name}}>, LubanError> {
let mut data_list: Vec<{{value_type}}> = vec![];
for x in (0..buf.read_size()).rev() {
{{deserialize_row "row" "buf" table.value_ttype}}
data_list.push(row.clone());
}
{{~if table.is_union_index~}}
let mut data_map_union: {{table_union_map_type_name}} = Default::default();
for x in &data_list {
data_map_union.insert(({{table_key_list "x"}}.clone()), x.clone());
}
{{~else if !table.index_list.empty?~}}
{{~for idx in table.index_list~}}
let mut data_map_{{idx.index_field.name}}: std::collections::HashMap<{{declaring_type_name idx.index_field.ctype}}, {{value_type}}> = Default::default();
{{~end~}}
for x in &data_list {
{{~for idx in table.index_list~}}
data_map_{{idx.index_field.name}}.insert(x.{{format_property_name __code_style idx.index_field.name}}.clone(), x.clone());
{{~end~}}
}
{{~end~}}
Ok(std::sync::Arc::new({{table.name}} {
data_list,
{{~if table.is_union_index~}}
data_map_union,
{{~else if !table.index_list.empty?~}}
{{~for idx in table.index_list~}}
data_map_{{idx.index_field.name}},
{{~end~}}
{{~end~}}
}))
}
{{~if table.is_union_index~}}
pub fn get(&self, key: &({{array.each table.index_list @index_type_name | array.join ', '}})) -> Option<{{value_type}}> {
self.data_map_union.get(key).map(|x| x.clone())
}
{{~else if !table.index_list.empty? ~}}
{{~for idx in table.index_list
index = format_property_name __code_style idx.index_field.name
~}}
pub fn get_by_{{index}}(&self, key: &{{declaring_type_name idx.type}}) -> Option<{{value_type}}> {
self.data_map_{{index}}.get(key).map(|x| x.clone())
}
{{~end~}}
{{~end~}}
}
{{~else~}}
impl {{name}} {
pub fn new(mut buf: ByteBuf) -> Result<std::sync::Arc<{{name}}>, LubanError> {
let n = buf.read_size();
if n != 1 { return Err(LubanError::Table(format!("table mode=one, but size != 1"))); }
{{deserialize 'data' 'buf' table.value_ttype}}
Ok(std::sync::Arc::new({{name}} { data }))
}
}
{{~end~}}
{{~end~}}