Basic implementation of execute
This commit is contained in:
parent
6572243ce4
commit
c494031163
|
@ -10,6 +10,7 @@ default = ["zip"]
|
||||||
zip = ["dep:zip"]
|
zip = ["dep:zip"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
getset = "0.1.2"
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.114"
|
serde_json = "1.0.114"
|
||||||
zip = { version = "0.6.6", default-features = false, features = ["deflate", "time"], optional = true }
|
zip = { version = "0.6.6", default-features = false, features = ["deflate", "time"], optional = true }
|
||||||
|
|
|
@ -15,13 +15,10 @@ let mut dp = Datapack::new("shulkerpack", 20) // Create a new datapack with the
|
||||||
.with_supported_formats(16..=20) // Add the supported formats of the datapack
|
.with_supported_formats(16..=20) // Add the supported formats of the datapack
|
||||||
.with_template_folder(Path::new("./template")) // Add a template folder to the datapack. This will include all files in the template folder in the root of the datapack and can be used for including the "pack.png" file
|
.with_template_folder(Path::new("./template")) // Add a template folder to the datapack. This will include all files in the template folder in the root of the datapack and can be used for including the "pack.png" file
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut namespace = Namespace::new("shulker"); // Create a new namespace with the name "shulker"
|
let namespace = datapack.namespace_mut("shulker"); // Create a new namespace with the name "shulker"
|
||||||
|
|
||||||
let mut hello_function = Function::new(); // Create a new function
|
let hello_function = namespace.function_mut("hello"); // Create a new function
|
||||||
hello_function.add_command("say Hello, world!".into()); // Add a command to the function
|
hello_function.add_command("say Hello, world!"); // Add a command to the function
|
||||||
namespace.add_function("hello", hello_function); // Add the function to the namespace
|
|
||||||
|
|
||||||
dp.add_namespace(namespace); // Add the namespace to the datapack
|
|
||||||
|
|
||||||
let v_folder = dp.compile(&CompileOptions::default()); // Compile the datapack with default options
|
let v_folder = dp.compile(&CompileOptions::default()); // Compile the datapack with default options
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use std::ops::{BitAnd, BitOr, Not};
|
use std::ops::{BitAnd, BitOr, Deref, Not};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::util::compile::{CompileOptions, MutCompilerState, MutFunctionCompilerState};
|
||||||
|
|
||||||
use super::Command;
|
use super::Command;
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum Execute {
|
pub enum Execute {
|
||||||
Align(String, Box<Execute>),
|
Align(String, Box<Execute>),
|
||||||
|
@ -18,10 +21,228 @@ pub enum Execute {
|
||||||
Rotated(String, Box<Execute>),
|
Rotated(String, Box<Execute>),
|
||||||
Store(String, Box<Execute>),
|
Store(String, Box<Execute>),
|
||||||
Summon(String, Box<Execute>),
|
Summon(String, Box<Execute>),
|
||||||
If(Condition, Box<Execute>),
|
If(Condition, Box<Execute>, Option<Box<Execute>>),
|
||||||
Run(String, Box<Command>),
|
Run(Box<Command>),
|
||||||
|
Runs(Vec<Command>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Execute {
|
||||||
|
/// Compile the execute command into a list of strings.
|
||||||
|
pub fn compile(
|
||||||
|
&self,
|
||||||
|
options: &CompileOptions,
|
||||||
|
global_state: &MutCompilerState,
|
||||||
|
function_state: &MutFunctionCompilerState,
|
||||||
|
) -> Vec<String> {
|
||||||
|
self.compile_internal(
|
||||||
|
String::from("execute "),
|
||||||
|
false,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fn compile_internal(
|
||||||
|
&self,
|
||||||
|
prefix: String,
|
||||||
|
require_grouping: bool,
|
||||||
|
options: &CompileOptions,
|
||||||
|
global_state: &MutCompilerState,
|
||||||
|
function_state: &MutFunctionCompilerState,
|
||||||
|
) -> Vec<String> {
|
||||||
|
match self {
|
||||||
|
Self::Align(align, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("align {align} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Anchored(anchor, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("anchored {anchor} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::As(selector, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("as {selector} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::At(selector, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("at {selector} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::AsAt(selector, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("as {selector} at @s "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Facing(facing, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("facing {facing} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::In(dim, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("in {dim} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::On(dim, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("on {dim} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Positioned(pos, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("positioned {pos} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Rotated(rot, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("rotated {rot} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Store(store, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("store {store} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::Summon(entity, next) => format_execute(
|
||||||
|
prefix,
|
||||||
|
&format!("summon {entity} "),
|
||||||
|
next,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
),
|
||||||
|
Self::If(cond, then, el) => {
|
||||||
|
// TODO: group commands if needed and only run else commands if the first commands have not executed
|
||||||
|
let str_cond = cond.clone().compile(options, global_state, function_state);
|
||||||
|
let require_grouping = str_cond.len() > 1;
|
||||||
|
let then = then.compile_internal(
|
||||||
|
String::new(),
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
);
|
||||||
|
let then_commands = combine_conditions_commands(str_cond, then);
|
||||||
|
let el = el
|
||||||
|
.as_deref()
|
||||||
|
.map(|el| {
|
||||||
|
let else_cond =
|
||||||
|
(!cond.clone()).compile(options, global_state, function_state);
|
||||||
|
let el = el.compile_internal(
|
||||||
|
String::new(),
|
||||||
|
else_cond.len() > 1,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
);
|
||||||
|
combine_conditions_commands(else_cond, el)
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
then_commands
|
||||||
|
.into_iter()
|
||||||
|
.chain(el)
|
||||||
|
.map(|cmd| prefix.clone() + &cmd + " ")
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
Self::Run(command) if !require_grouping => command
|
||||||
|
.compile(options, global_state, function_state)
|
||||||
|
.into_iter()
|
||||||
|
.map(|c| prefix.clone() + "run " + &c)
|
||||||
|
.collect(),
|
||||||
|
Self::Run(command) => Command::Group(vec![command.deref().clone()])
|
||||||
|
.compile(options, global_state, function_state)
|
||||||
|
.into_iter()
|
||||||
|
.map(|c| prefix.clone() + "run " + &c)
|
||||||
|
.collect(),
|
||||||
|
Self::Runs(commands) if !require_grouping => commands
|
||||||
|
.iter()
|
||||||
|
.flat_map(|c| c.compile(options, global_state, function_state))
|
||||||
|
.map(|c| prefix.clone() + "run " + &c)
|
||||||
|
.collect(),
|
||||||
|
Self::Runs(commands) => Command::Group(commands.clone())
|
||||||
|
.compile(options, global_state, function_state)
|
||||||
|
.into_iter()
|
||||||
|
.map(|c| prefix.clone() + "run " + &c)
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_execute(
|
||||||
|
prefix: String,
|
||||||
|
new: &str,
|
||||||
|
next: &Execute,
|
||||||
|
require_grouping: bool,
|
||||||
|
options: &CompileOptions,
|
||||||
|
global_state: &MutCompilerState,
|
||||||
|
function_state: &MutFunctionCompilerState,
|
||||||
|
) -> Vec<String> {
|
||||||
|
next.compile_internal(
|
||||||
|
prefix + new,
|
||||||
|
require_grouping,
|
||||||
|
options,
|
||||||
|
global_state,
|
||||||
|
function_state,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn combine_conditions_commands(conditions: Vec<String>, commands: Vec<String>) -> Vec<String> {
|
||||||
|
conditions
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(|cond| commands.iter().map(move |cmd| cond.clone() + " " + cmd))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Condition {
|
pub enum Condition {
|
||||||
Atom(String),
|
Atom(String),
|
||||||
|
@ -30,11 +251,12 @@ pub enum Condition {
|
||||||
Or(Box<Condition>, Box<Condition>),
|
Or(Box<Condition>, Box<Condition>),
|
||||||
}
|
}
|
||||||
impl Condition {
|
impl Condition {
|
||||||
pub fn normalize(self) -> Self {
|
/// Normalize the condition.
|
||||||
|
pub fn normalize(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Atom(_) => self,
|
Self::Atom(_) => self.clone(),
|
||||||
Self::Not(c) => match *c {
|
Self::Not(c) => match *c.clone() {
|
||||||
Self::Atom(c) => Self::Not(Box::new(Self::Atom(c))),
|
Self::Atom(c) => Self::Not(Box::new(Self::Atom(c.clone()))),
|
||||||
Self::Not(c) => c.normalize(),
|
Self::Not(c) => c.normalize(),
|
||||||
Self::And(c1, c2) => ((!*c1).normalize()) | ((!*c2).normalize()),
|
Self::And(c1, c2) => ((!*c1).normalize()) | ((!*c2).normalize()),
|
||||||
Self::Or(c1, c2) => ((!*c1).normalize()) & ((!*c2).normalize()),
|
Self::Or(c1, c2) => ((!*c1).normalize()) & ((!*c2).normalize()),
|
||||||
|
@ -43,6 +265,42 @@ impl Condition {
|
||||||
Self::Or(c1, c2) => c1.normalize() | c2.normalize(),
|
Self::Or(c1, c2) => c1.normalize() | c2.normalize(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile the condition into a list of strings.
|
||||||
|
pub fn compile(
|
||||||
|
&self,
|
||||||
|
_options: &CompileOptions,
|
||||||
|
_global_state: &MutCompilerState,
|
||||||
|
_function_state: &MutFunctionCompilerState,
|
||||||
|
) -> Vec<String> {
|
||||||
|
match self.normalize() {
|
||||||
|
Self::Atom(a) => vec!["if ".to_string() + &a],
|
||||||
|
Self::Not(n) => match n.as_ref() {
|
||||||
|
Self::Atom(a) => vec!["unless ".to_string() + a],
|
||||||
|
_ => unreachable!("Cannot happen because of normalization"),
|
||||||
|
},
|
||||||
|
Self::And(c1, c2) => {
|
||||||
|
let c1 = c1.compile(_options, _global_state, _function_state);
|
||||||
|
let c2 = c2.compile(_options, _global_state, _function_state);
|
||||||
|
|
||||||
|
c1.into_iter()
|
||||||
|
.flat_map(|c1| c2.iter().map(move |c2| c1.clone() + " " + c2))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
Self::Or(c1, c2) => {
|
||||||
|
let mut c1 = c1.compile(_options, _global_state, _function_state);
|
||||||
|
let c2 = c2.compile(_options, _global_state, _function_state);
|
||||||
|
c1.extend(c2);
|
||||||
|
c1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Condition {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
Condition::Atom(s.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Not for Condition {
|
impl Not for Condition {
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
//! Represents a command that can be included in a function.
|
//! Represents a command that can be included in a function.
|
||||||
|
|
||||||
mod execute;
|
mod execute;
|
||||||
pub use execute::Execute;
|
|
||||||
|
pub use execute::{Condition, Execute};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::util::compile::{CompileOptions, MutCompilerState, MutFunctionCompilerState};
|
use crate::util::compile::{CompileOptions, MutCompilerState, MutFunctionCompilerState};
|
||||||
|
|
||||||
|
use super::Function;
|
||||||
|
|
||||||
/// Represents a command that can be included in a function.
|
/// Represents a command that can be included in a function.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
|
@ -16,6 +19,8 @@ pub enum Command {
|
||||||
Debug(String),
|
Debug(String),
|
||||||
/// Execute command
|
/// Execute command
|
||||||
Execute(Execute),
|
Execute(Execute),
|
||||||
|
/// Group of commands to be called instantly after each other
|
||||||
|
Group(Vec<Command>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
|
@ -30,14 +35,18 @@ impl Command {
|
||||||
options: &CompileOptions,
|
options: &CompileOptions,
|
||||||
global_state: &MutCompilerState,
|
global_state: &MutCompilerState,
|
||||||
function_state: &MutFunctionCompilerState,
|
function_state: &MutFunctionCompilerState,
|
||||||
) -> String {
|
) -> Vec<String> {
|
||||||
let _ = options;
|
|
||||||
let _ = global_state;
|
|
||||||
let _ = function_state;
|
|
||||||
match self {
|
match self {
|
||||||
Self::Raw(command) => command.clone(),
|
Self::Raw(command) => vec![command.clone()],
|
||||||
Self::Debug(message) => compile_debug(message, options),
|
Self::Debug(message) => compile_debug(message, options),
|
||||||
Self::Execute(_) => todo!(),
|
Self::Execute(ex) => ex.compile(options, global_state, function_state),
|
||||||
|
Self::Group(commands) => {
|
||||||
|
// TODO: implement correctly
|
||||||
|
commands
|
||||||
|
.iter()
|
||||||
|
.flat_map(|c| c.compile(options, global_state, function_state))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,14 +56,24 @@ impl From<&str> for Command {
|
||||||
Self::raw(command)
|
Self::raw(command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl From<&Function> for Command {
|
||||||
fn compile_debug(message: &str, option: &CompileOptions) -> String {
|
fn from(value: &Function) -> Self {
|
||||||
if option.debug {
|
Self::Raw(format!("function {}:{}", value.namespace(), value.name()))
|
||||||
format!(
|
}
|
||||||
r#"tellraw @a [{{"text":"[","color":"dark_blue"}},{{"text":"DEBUG","color":"dark_green","hoverEvent":{{"action":"show_text","value":[{{"text":"Debug message generated by Shulkerbox"}},{{"text":"\nSet debug message to 'false' to disable"}}]}}}},{{"text":"]","color":"dark_blue"}},{{"text":" {}","color":"black"}}]"#,
|
}
|
||||||
message
|
impl From<&mut Function> for Command {
|
||||||
)
|
fn from(value: &mut Function) -> Self {
|
||||||
} else {
|
Self::Raw(format!("function {}:{}", value.namespace(), value.name()))
|
||||||
String::new()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compile_debug(message: &str, option: &CompileOptions) -> Vec<String> {
|
||||||
|
if option.debug {
|
||||||
|
vec![format!(
|
||||||
|
r#"tellraw @a [{{"text":"[","color":"dark_blue"}},{{"text":"DEBUG","color":"dark_green","hoverEvent":{{"action":"show_text","value":[{{"text":"Debug message generated by Shulkerbox"}},{{"text":"\nSet debug message to 'false' to disable"}}]}}}},{{"text":"]","color":"dark_blue"}},{{"text":" {}","color":"black"}}]"#,
|
||||||
|
message
|
||||||
|
)]
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use getset::Getters;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -12,20 +13,28 @@ use crate::{
|
||||||
use super::command::Command;
|
use super::command::Command;
|
||||||
|
|
||||||
/// Function that can be called by a command
|
/// Function that can be called by a command
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, Getters)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
commands: Vec<Command>,
|
commands: Vec<Command>,
|
||||||
|
/// Name of the function
|
||||||
|
#[get = "pub"]
|
||||||
|
name: String,
|
||||||
|
/// Namespace of the function
|
||||||
|
#[get = "pub"]
|
||||||
|
namespace: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
/// Create a new function.
|
pub(in crate::datapack) fn new(namespace: &str, name: &str) -> Self {
|
||||||
pub fn new() -> Self {
|
Self {
|
||||||
Self::default()
|
commands: Vec::new(),
|
||||||
|
name: name.to_string(),
|
||||||
|
namespace: namespace.to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a command to the function.
|
/// Add a command to the function.
|
||||||
pub fn add_command(&mut self, command: Command) {
|
pub fn add_command(&mut self, command: impl Into<Command>) {
|
||||||
self.commands.push(command);
|
self.commands.push(command.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the commands of the function.
|
/// Get the commands of the function.
|
||||||
|
@ -40,7 +49,7 @@ impl Function {
|
||||||
let content = self
|
let content = self
|
||||||
.commands
|
.commands
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| c.compile(options, state, &function_state))
|
.flat_map(|c| c.compile(options, state, &function_state))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
VFile::Text(content)
|
VFile::Text(content)
|
||||||
|
|
|
@ -4,7 +4,7 @@ mod command;
|
||||||
mod function;
|
mod function;
|
||||||
mod namespace;
|
mod namespace;
|
||||||
pub mod tag;
|
pub mod tag;
|
||||||
pub use command::Command;
|
pub use command::{Command, Condition, Execute};
|
||||||
pub use function::Function;
|
pub use function::Function;
|
||||||
pub use namespace::Namespace;
|
pub use namespace::Namespace;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -72,13 +72,16 @@ impl Datapack {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a namespace to the datapack.
|
/// Get a namespace by name.
|
||||||
pub fn add_namespace(&mut self, namespace: Namespace) {
|
pub fn namespace(&self, name: &str) -> Option<&Namespace> {
|
||||||
if !namespace.get_main_function().get_commands().is_empty() {
|
self.namespaces.get(name)
|
||||||
self.add_tick(&format!("{}:main", namespace.get_name()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Butably get a namespace by name or create a new one if it doesn't exist.
|
||||||
|
pub fn namespace_mut(&mut self, name: &str) -> &mut Namespace {
|
||||||
self.namespaces
|
self.namespaces
|
||||||
.insert(namespace.get_name().to_string(), namespace);
|
.entry(name.to_string())
|
||||||
|
.or_insert_with(|| Namespace::new(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a function to the tick function list.
|
/// Add a function to the tick function list.
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub struct Namespace {
|
||||||
|
|
||||||
impl Namespace {
|
impl Namespace {
|
||||||
/// Create a new namespace.
|
/// Create a new namespace.
|
||||||
pub fn new(name: &str) -> Self {
|
pub(in crate::datapack) fn new(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
|
@ -54,9 +54,16 @@ impl Namespace {
|
||||||
&self.tags
|
&self.tags
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a function to the namespace.
|
/// Get a function by name.
|
||||||
pub fn add_function(&mut self, name: &str, function: Function) {
|
pub fn function(&self, name: &str) -> Option<&Function> {
|
||||||
self.functions.insert(name.to_string(), function);
|
self.functions.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutably get a function by name or create a new one if it doesn't exist.
|
||||||
|
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.
|
/// Add a tag to the namespace.
|
||||||
|
|
Loading…
Reference in New Issue