aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-04-18 15:18:54 +0000
committermat <github@matdoes.dev>2022-04-18 15:18:54 +0000
commitd25c9926d714e1920a8656452f20cab60565443f (patch)
tree172f556ffad34d6df96759d71cb3f16c2735d973
parentb7d4b437dc9906d63b11f70cb03a5ca52ba6e5c5 (diff)
downloadazalea-drasl-d25c9926d714e1920a8656452f20cab60565443f.tar.xz
add get_path
-rw-r--r--azalea-brigadier/src/builder/argument_builder.rs8
-rw-r--r--azalea-brigadier/src/dispatcher.rs39
2 files changed, 41 insertions, 6 deletions
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index 038b68a2..a5388a43 100644
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -53,10 +53,12 @@ impl<S> ArgumentBuilder<S> {
}
}
- // do we need to be cloning here? maybe we could return a ref to self?
pub fn then(&mut self, argument: ArgumentBuilder<S>) -> Self {
- self.arguments
- .add_child(&Rc::new(RefCell::new(argument.build())));
+ self.then_built(argument.build())
+ }
+
+ pub fn then_built(&mut self, argument: CommandNode<S>) -> Self {
+ self.arguments.add_child(&Rc::new(RefCell::new(argument)));
self.clone()
}
diff --git a/azalea-brigadier/src/dispatcher.rs b/azalea-brigadier/src/dispatcher.rs
index 28461a9e..23e855c0 100644
--- a/azalea-brigadier/src/dispatcher.rs
+++ b/azalea-brigadier/src/dispatcher.rs
@@ -162,6 +162,40 @@ impl<S> CommandDispatcher<S> {
Self::execute_parsed(parse)
}
+ pub fn add_paths(
+ &self,
+ node: Rc<RefCell<CommandNode<S>>>,
+ result: &mut Vec<Vec<Rc<RefCell<CommandNode<S>>>>>,
+ parents: Vec<Rc<RefCell<CommandNode<S>>>>,
+ ) {
+ let mut current = parents.clone();
+ current.push(node.clone());
+ result.push(current.clone());
+
+ for child in node.borrow().children.values() {
+ self.add_paths(child.clone(), result, current.clone());
+ }
+ }
+
+ pub fn get_path(&self, target: CommandNode<S>) -> Vec<String> {
+ let rc_target = Rc::new(RefCell::new(target.clone()));
+ let mut nodes: Vec<Vec<Rc<RefCell<CommandNode<S>>>>> = Vec::new();
+ self.add_paths(self.root.clone(), &mut nodes, vec![]);
+
+ for list in nodes {
+ if *list.last().expect("Nothing in list").borrow() == *rc_target.borrow() {
+ let mut result: Vec<String> = Vec::with_capacity(list.len());
+ for node in list {
+ if node != self.root {
+ result.push(node.borrow().name().to_string());
+ }
+ }
+ return result;
+ }
+ }
+ vec![]
+ }
+
/// Executes a given pre-parsed command.
pub fn execute_parsed(parse: ParseResults<S>) -> Result<i32, CommandSyntaxException> {
if parse.reader.can_read() {
@@ -236,7 +270,6 @@ impl<S> CommandDispatcher<S> {
);
}
- println!("forked: {}, successful forks: {}", forked, successful_forks);
// TODO: this is not how vanilla does it but it works
Ok(if successful_forks >= 2 {
successful_forks
@@ -945,10 +978,10 @@ mod tests {
// }
#[test]
fn get_path() {
- let mut subject = CommandDispatcher::new();
+ let mut subject = CommandDispatcher::<()>::new();
let bar = literal("bar").build();
- subject.register(literal("foo").then(bar));
+ subject.register(literal("foo").then_built(bar.clone()));
assert_eq!(
subject.get_path(bar),