change tag creation behaviour
This commit is contained in:
parent
451626312f
commit
cf62725a5e
|
@ -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
|
|
@ -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());
|
||||
|
|
|
@ -24,8 +24,6 @@ pub struct Datapack {
|
|||
pack_format: u8,
|
||||
supported_formats: Option<RangeInclusive<u8>>,
|
||||
namespaces: HashMap<String, Namespace>,
|
||||
tick: Vec<String>,
|
||||
load: Vec<String>,
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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<String, Function>,
|
||||
main_function: Function,
|
||||
tags: HashMap<String, Tag>,
|
||||
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<String, Function> {
|
||||
|
@ -56,7 +47,7 @@ impl Namespace {
|
|||
|
||||
/// Get the tags of the namespace.
|
||||
#[must_use]
|
||||
pub fn get_tags(&self) -> &HashMap<String, Tag> {
|
||||
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::<VecDeque<_>>();
|
||||
|
||||
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
|
||||
|
|
|
@ -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<TagValue> {
|
||||
&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::<Vec<_>>()
|
||||
});
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue