From d25c9926d714e1920a8656452f20cab60565443f Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 18 Apr 2022 15:18:54 +0000 Subject: [PATCH] add get_path --- .../src/builder/argument_builder.rs | 8 ++-- azalea-brigadier/src/dispatcher.rs | 39 +++++++++++++++++-- 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 ArgumentBuilder { } } - // do we need to be cloning here? maybe we could return a ref to self? pub fn then(&mut self, argument: ArgumentBuilder) -> Self { - self.arguments - .add_child(&Rc::new(RefCell::new(argument.build()))); + self.then_built(argument.build()) + } + + pub fn then_built(&mut self, argument: CommandNode) -> 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 CommandDispatcher { Self::execute_parsed(parse) } + pub fn add_paths( + &self, + node: Rc>>, + result: &mut Vec>>>>, + parents: Vec>>>, + ) { + 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) -> Vec { + let rc_target = Rc::new(RefCell::new(target.clone())); + let mut nodes: Vec>>>> = 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 = 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) -> Result { if parse.reader.can_read() { @@ -236,7 +270,6 @@ impl CommandDispatcher { ); } - 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),