From cf62725a5e2aa3a9cf86f3c65b5690092cf9cd3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20H=C3=B6lting?= <87192362+moritz-hoelting@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:38:23 +0200 Subject: [PATCH] change tag creation behaviour --- CHANGELOG.md | 26 ++++++++++++++++++ examples/basic.rs | 3 +-- src/datapack/mod.rs | 34 +++++------------------- src/datapack/namespace.rs | 55 +++++++++++++++++++++------------------ src/datapack/tag.rs | 33 ++++++++++++++++++----- 5 files changed, 89 insertions(+), 62 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9c3885f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Datapack struct with compile function +- Namespace struct with compile function +- Function struct with compile function +- Tag struct with compile function +- Command struct with compile function + - Raw command + - Comment + - Execute + - Debug + - Group +- Virtual file system + +### Changed + +### Removed diff --git a/examples/basic.rs b/examples/basic.rs index a811a90..ca48405 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -32,8 +32,7 @@ fn main() { )), ))); - // get the main function of the namespace "test" and add a command - namespace.get_main_function_mut().add_command("say tick"); + dp.add_load("test:foo"); // compile the datapack let v_folder = dp.compile(&CompileOptions::default()); diff --git a/src/datapack/mod.rs b/src/datapack/mod.rs index cac606d..7086880 100644 --- a/src/datapack/mod.rs +++ b/src/datapack/mod.rs @@ -24,8 +24,6 @@ pub struct Datapack { pack_format: u8, supported_formats: Option>, namespaces: HashMap, - tick: Vec, - load: Vec, custom_files: VFolder, } @@ -38,8 +36,6 @@ impl Datapack { pack_format, supported_formats: None, namespaces: HashMap::new(), - tick: Vec::new(), - load: Vec::new(), custom_files: VFolder::new(), } } @@ -91,12 +87,16 @@ impl Datapack { /// Add a function to the tick function list. pub fn add_tick(&mut self, function: &str) { - self.tick.push(function.to_string()); + self.namespace_mut("minecraft") + .tag_mut("tick", tag::TagType::Functions) + .add_value(tag::TagValue::Simple(function.to_string())); } /// Add a function to the load function list. pub fn add_load(&mut self, function: &str) { - self.load.push(function.to_string()); + self.namespace_mut("minecraft") + .tag_mut("load", tag::TagType::Functions) + .add_value(tag::TagValue::Simple(function.to_string())); } /// Add a custom file to the datapack. @@ -123,28 +123,6 @@ impl Datapack { data_folder.add_existing_folder(name, namespace_folder); } - // Compile tick and load tag - if !self.tick.is_empty() { - let mut tick_tag = tag::Tag::new(tag::TagType::Functions, false); - for function in &self.tick { - tick_tag.add_value(tag::TagValue::Simple(function.to_owned())); - } - data_folder.add_file( - "minecraft/tags/function/tick.json", - tick_tag.compile_no_state(options).1, - ); - } - if !self.load.is_empty() { - let mut load_tag = tag::Tag::new(tag::TagType::Functions, false); - for function in &self.load { - load_tag.add_value(tag::TagValue::Simple(function.to_owned())); - } - data_folder.add_file( - "minecraft/tags/function/load.json", - load_tag.compile_no_state(options).1, - ); - } - root_folder.add_existing_folder("data", data_folder); root_folder } diff --git a/src/datapack/namespace.rs b/src/datapack/namespace.rs index 67f2f70..58cd10f 100644 --- a/src/datapack/namespace.rs +++ b/src/datapack/namespace.rs @@ -8,7 +8,10 @@ use crate::{ virtual_fs::VFolder, }; -use super::{function::Function, tag::Tag}; +use super::{ + function::Function, + tag::{Tag, TagType}, +}; use std::collections::{HashMap, VecDeque}; /// Namespace of a datapack @@ -17,8 +20,7 @@ use std::collections::{HashMap, VecDeque}; pub struct Namespace { name: String, functions: HashMap, - main_function: Function, - tags: HashMap, + tags: HashMap<(String, TagType), Tag>, } impl Namespace { @@ -27,7 +29,6 @@ impl Namespace { Self { name: name.to_string(), functions: HashMap::new(), - main_function: Function::default(), tags: HashMap::new(), } } @@ -38,16 +39,6 @@ impl Namespace { &self.name } - /// Get the main function of the namespace. - #[must_use] - pub fn get_main_function(&self) -> &Function { - &self.main_function - } - /// Get the main function of the namespace mutably. - pub fn get_main_function_mut(&mut self) -> &mut Function { - &mut self.main_function - } - /// Get the functions of the namespace. #[must_use] pub fn get_functions(&self) -> &HashMap { @@ -56,7 +47,7 @@ impl Namespace { /// Get the tags of the namespace. #[must_use] - pub fn get_tags(&self) -> &HashMap { + pub fn get_tags(&self) -> &HashMap<(String, TagType), Tag> { &self.tags } @@ -67,15 +58,25 @@ impl Namespace { } /// Mutably get a function by name or create a new one if it doesn't exist. + #[must_use] pub fn function_mut(&mut self, name: &str) -> &mut Function { self.functions .entry(name.to_string()) .or_insert_with(|| Function::new(&self.name, name)) } - /// Add a tag to the namespace. - pub fn add_tag(&mut self, name: &str, tag: Tag) { - self.tags.insert(name.to_string(), tag); + /// Get a tag by name and type. + #[must_use] + pub fn tag(&self, name: &str, tag_type: TagType) -> Option<&Tag> { + self.tags.get(&(name.to_string(), tag_type)) + } + + /// Mutably get a tag by name and type or create a new one if it doesn't exist. + #[must_use] + pub fn tag_mut(&mut self, name: &str, tag_type: TagType) -> &mut Tag { + self.tags + .entry((name.to_string(), tag_type.clone())) + .or_insert_with(|| Tag::new(tag_type, false)) } /// Compile the namespace into a virtual folder. @@ -86,16 +87,12 @@ impl Namespace { let mut root_folder = VFolder::new(); // collect functions - let mut functions = self + let functions = self .functions .iter() .map(|(name, content)| (name.clone(), content.clone())) .collect::>(); - if !self.main_function.get_commands().is_empty() { - functions.push_front(("main".to_string(), self.main_function.clone())); - } - // compile all functions, allow adding new functions while compiling let mut functions = ExtendableQueue::from(functions); while let Some((path, function)) = functions.next() { @@ -107,9 +104,15 @@ impl Namespace { } // compile tags - for (path, tag) in &self.tags { - let (tag_type, vfile) = tag.compile(options, state); - root_folder.add_file(&format!("tags/{tag_type}/{path}.json"), vfile); + for ((path, tag_type), tag) in &self.tags { + let vfile = tag.compile(options, state); + root_folder.add_file( + &format!( + "tags/{tag_type}/{path}.json", + tag_type = tag_type.to_string() + ), + vfile, + ); } root_folder diff --git a/src/datapack/tag.rs b/src/datapack/tag.rs index 9f0a401..d3254ce 100644 --- a/src/datapack/tag.rs +++ b/src/datapack/tag.rs @@ -24,25 +24,46 @@ impl Tag { } } + /// Get the type of the tag. + #[must_use] + pub fn get_type(&self) -> &TagType { + &self.r#type + } + + /// Get whether the tag should replace existing values. + #[must_use] + pub fn get_replace(&self) -> bool { + self.replace + } + + /// Set whether the tag should replace existing values. + pub fn set_replace(&mut self, replace: bool) { + self.replace = replace; + } + + /// Get the values of the tag. + #[must_use] + pub fn get_values(&self) -> &Vec { + &self.values + } + /// Add a value to the tag. pub fn add_value(&mut self, value: TagValue) { self.values.push(value); } /// Compile the tag into a virtual file without state - pub fn compile_no_state(&self, _options: &CompileOptions) -> (String, VFile) { + pub fn compile_no_state(&self, _options: &CompileOptions) -> VFile { let json = serde_json::json!({ "replace": self.replace, "values": self.values.iter().map(TagValue::compile).collect::>() }); - let type_str = self.r#type.to_string(); - let vfile = VFile::Text(serde_json::to_string(&json).expect("Failed to serialize tag")); - (type_str, vfile) + VFile::Text(serde_json::to_string(&json).expect("Failed to serialize tag")) } /// Compile the tag into a virtual file. - pub fn compile(&self, options: &CompileOptions, _state: &MutCompilerState) -> (String, VFile) { + pub fn compile(&self, options: &CompileOptions, _state: &MutCompilerState) -> VFile { self.compile_no_state(options) } } @@ -50,7 +71,7 @@ impl Tag { /// The type of a tag. #[allow(clippy::module_name_repetitions)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TagType { /// A tag for blocks. Blocks,