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
|
dp.add_load("test:foo");
|
||||||
namespace.get_main_function_mut().add_command("say tick");
|
|
||||||
|
|
||||||
// compile the datapack
|
// compile the datapack
|
||||||
let v_folder = dp.compile(&CompileOptions::default());
|
let v_folder = dp.compile(&CompileOptions::default());
|
||||||
|
|
|
@ -24,8 +24,6 @@ pub struct Datapack {
|
||||||
pack_format: u8,
|
pack_format: u8,
|
||||||
supported_formats: Option<RangeInclusive<u8>>,
|
supported_formats: Option<RangeInclusive<u8>>,
|
||||||
namespaces: HashMap<String, Namespace>,
|
namespaces: HashMap<String, Namespace>,
|
||||||
tick: Vec<String>,
|
|
||||||
load: Vec<String>,
|
|
||||||
custom_files: VFolder,
|
custom_files: VFolder,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +36,6 @@ impl Datapack {
|
||||||
pack_format,
|
pack_format,
|
||||||
supported_formats: None,
|
supported_formats: None,
|
||||||
namespaces: HashMap::new(),
|
namespaces: HashMap::new(),
|
||||||
tick: Vec::new(),
|
|
||||||
load: Vec::new(),
|
|
||||||
custom_files: VFolder::new(),
|
custom_files: VFolder::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,12 +87,16 @@ impl Datapack {
|
||||||
|
|
||||||
/// Add a function to the tick function list.
|
/// Add a function to the tick function list.
|
||||||
pub fn add_tick(&mut self, function: &str) {
|
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.
|
/// Add a function to the load function list.
|
||||||
pub fn add_load(&mut self, function: &str) {
|
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.
|
/// Add a custom file to the datapack.
|
||||||
|
@ -123,28 +123,6 @@ impl Datapack {
|
||||||
data_folder.add_existing_folder(name, namespace_folder);
|
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.add_existing_folder("data", data_folder);
|
||||||
root_folder
|
root_folder
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@ use crate::{
|
||||||
virtual_fs::VFolder,
|
virtual_fs::VFolder,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{function::Function, tag::Tag};
|
use super::{
|
||||||
|
function::Function,
|
||||||
|
tag::{Tag, TagType},
|
||||||
|
};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
/// Namespace of a datapack
|
/// Namespace of a datapack
|
||||||
|
@ -17,8 +20,7 @@ use std::collections::{HashMap, VecDeque};
|
||||||
pub struct Namespace {
|
pub struct Namespace {
|
||||||
name: String,
|
name: String,
|
||||||
functions: HashMap<String, Function>,
|
functions: HashMap<String, Function>,
|
||||||
main_function: Function,
|
tags: HashMap<(String, TagType), Tag>,
|
||||||
tags: HashMap<String, Tag>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Namespace {
|
impl Namespace {
|
||||||
|
@ -27,7 +29,6 @@ impl Namespace {
|
||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
main_function: Function::default(),
|
|
||||||
tags: HashMap::new(),
|
tags: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,16 +39,6 @@ impl Namespace {
|
||||||
&self.name
|
&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.
|
/// Get the functions of the namespace.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_functions(&self) -> &HashMap<String, Function> {
|
pub fn get_functions(&self) -> &HashMap<String, Function> {
|
||||||
|
@ -56,7 +47,7 @@ impl Namespace {
|
||||||
|
|
||||||
/// Get the tags of the namespace.
|
/// Get the tags of the namespace.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_tags(&self) -> &HashMap<String, Tag> {
|
pub fn get_tags(&self) -> &HashMap<(String, TagType), Tag> {
|
||||||
&self.tags
|
&self.tags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +58,25 @@ impl Namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutably get a function by name or create a new one if it doesn't exist.
|
/// 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 {
|
pub fn function_mut(&mut self, name: &str) -> &mut Function {
|
||||||
self.functions
|
self.functions
|
||||||
.entry(name.to_string())
|
.entry(name.to_string())
|
||||||
.or_insert_with(|| Function::new(&self.name, name))
|
.or_insert_with(|| Function::new(&self.name, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a tag to the namespace.
|
/// Get a tag by name and type.
|
||||||
pub fn add_tag(&mut self, name: &str, tag: Tag) {
|
#[must_use]
|
||||||
self.tags.insert(name.to_string(), tag);
|
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.
|
/// Compile the namespace into a virtual folder.
|
||||||
|
@ -86,16 +87,12 @@ impl Namespace {
|
||||||
let mut root_folder = VFolder::new();
|
let mut root_folder = VFolder::new();
|
||||||
|
|
||||||
// collect functions
|
// collect functions
|
||||||
let mut functions = self
|
let functions = self
|
||||||
.functions
|
.functions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, content)| (name.clone(), content.clone()))
|
.map(|(name, content)| (name.clone(), content.clone()))
|
||||||
.collect::<VecDeque<_>>();
|
.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
|
// compile all functions, allow adding new functions while compiling
|
||||||
let mut functions = ExtendableQueue::from(functions);
|
let mut functions = ExtendableQueue::from(functions);
|
||||||
while let Some((path, function)) = functions.next() {
|
while let Some((path, function)) = functions.next() {
|
||||||
|
@ -107,9 +104,15 @@ impl Namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
// compile tags
|
// compile tags
|
||||||
for (path, tag) in &self.tags {
|
for ((path, tag_type), tag) in &self.tags {
|
||||||
let (tag_type, vfile) = tag.compile(options, state);
|
let vfile = tag.compile(options, state);
|
||||||
root_folder.add_file(&format!("tags/{tag_type}/{path}.json"), vfile);
|
root_folder.add_file(
|
||||||
|
&format!(
|
||||||
|
"tags/{tag_type}/{path}.json",
|
||||||
|
tag_type = tag_type.to_string()
|
||||||
|
),
|
||||||
|
vfile,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
root_folder
|
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.
|
/// Add a value to the tag.
|
||||||
pub fn add_value(&mut self, value: TagValue) {
|
pub fn add_value(&mut self, value: TagValue) {
|
||||||
self.values.push(value);
|
self.values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the tag into a virtual file without state
|
/// 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!({
|
let json = serde_json::json!({
|
||||||
"replace": self.replace,
|
"replace": self.replace,
|
||||||
"values": self.values.iter().map(TagValue::compile).collect::<Vec<_>>()
|
"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.
|
/// 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)
|
self.compile_no_state(options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +71,7 @@ impl Tag {
|
||||||
/// The type of a tag.
|
/// The type of a tag.
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum TagType {
|
pub enum TagType {
|
||||||
/// A tag for blocks.
|
/// A tag for blocks.
|
||||||
Blocks,
|
Blocks,
|
||||||
|
|
Loading…
Reference in New Issue