-
-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Command API #351
Command API #351
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very excited to see progress on this! I haven't looked too hard at this yet, just a couple notes.
Not a full review from me yet, but that's what I've noticed so far. |
I changed the whole system again. Now:
Check out example |
What I think should also be done:
|
examples/command.rs
Outdated
.with_child(|child| { | ||
child.name(Cow::Borrowed("creative")).executor( | ||
|In(arguments): In<CommandArguments>, mut query: Query<&mut GameMode>| { | ||
if let RealCommandExecutor::Player(client) = arguments.1 { | ||
if let Ok(mut game_mode) = query.get_mut(client) { | ||
*game_mode = GameMode::Creative; | ||
} | ||
} | ||
}, | ||
); | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting... I'd like to see another example command that implements /tp x y z
or /give
. It's not really clear to me how one would go about that.
I know that this is likely completely of the rails compared to the current implementation but cant we just use bevy plugins and events? this way we are tightly coupled with bevy and would make it much nicer to code. I have a few ideas on how this could look here is one (I just typed these up on the textbox so could have errors): struct TeleportCommand;
impl Command for TeleportCommand {
fn command(&self) -> impl Into<String> {
"tp"
}
fn params(&self) -> impl Into<Vec<CommandParameter>> { // with CommandParameter being some kind of enum
vec![CommandParameter::Position]
// This might also be vec![CommandParameter::Position(None)] or even vec![CommandParameterMarker::Position]
}
// ...
}
// ...
app.add_plugins(CommandHandler::from_command(TeleportCommand))
// this should send out events that look something like CommandExecutionEvent<TeleportCommand>
// this event should contain the params. I have good ideas on how to make this happen and if you think it is a good idea I could work on the code? again I am really just throughing something out into the blue here but I would like to see an as ergonomic as possible API for this. |
I haven't looked too much into this PR yet, but would it be possible to make command parsing work via the Sorry if this PRs already doing that or anything, it was just a thought in my head and I thought I'd go ahead and mention it. |
No, the way that minecraft commands work is not compatible with clap. IIRC, this was explicitly discussed on the thread in discord. Minecraft commands can have cyclic references for suggestions, and parsers for stuff like relative coordinates and target selectors (eg, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a little skim of the code and reviewed a little.
answer: &mut crate::suggestions::SuggestionAnswerer, | ||
suggestions: Self::Suggestions, | ||
command: String, | ||
world: &bevy_ecs::world::World, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessing the whole world is not a very good idea especially for something as simple as a suggestion.
#[derive(Clone, Copy, Debug, PartialEq)] | ||
pub enum RealCommandExecutor { | ||
Player(Entity), | ||
Console, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would console exist? It should be up to the user of valance to make logic to execute commands though the console. Is this used anywhere in the protocol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not covered by protocol because it has nothing to do with it, console's command executions handled by server anyway (the same as block's command executions). And I think that console can be a command executor, the same as a block.
crates/valence_command/src/nodes.rs
Outdated
pub(crate) type PCRelationVec = SmallVec<[Entity; 2]>; | ||
|
||
#[derive(Component, Debug)] | ||
pub struct NodeName(pub(crate) Cow<'static, str>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just store a String
?
crates/valence_command/src/nodes.rs
Outdated
use crate::pkt::{self, RawCommandTreeS2c}; | ||
use crate::suggestions::RawParseSuggestions; | ||
|
||
pub(crate) type PCRelationVec = SmallVec<[Entity; 2]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this ever exceed 2 things? If not why not just use a tuple or array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a vec for parents and children relation, so yeah it can exceed 2 elements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In directed graphs generally you have a source and a target for edges, how is this data able to excede 2 elements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how this graph called but each node can have many parents and many children
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally when you have a graph like this you want to use edges between the nodes. How do you Tel if an item in this list is parent or child?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments.
} | ||
} | ||
|
||
pub const CONSOLE_EVENT_ID: u32 = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep consts at top of file
|
||
#[derive(Clone, Debug)] | ||
pub struct Suggestion<'a> { | ||
pub message: Cow<'a, str>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you using Cow<'a, str>
everywhere?
SuggestionsTransaction::Event { id } => { | ||
self.event.send(SuggestionAnswerEvent { | ||
suggestions: suggestions | ||
.map(|v| v.into_iter().map(|v| v.clone_static()).collect()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name v better: suggestion
same goes for everywhere you use v.
crates/valence_command/src/nodes.rs
Outdated
use crate::pkt::{self, RawCommandTreeS2c}; | ||
use crate::suggestions::RawParseSuggestions; | ||
|
||
pub(crate) type PCRelationVec = SmallVec<[Entity; 2]>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In directed graphs generally you have a source and a target for edges, how is this data able to excede 2 elements?
Suggestions are done. @rj00a, can you review current code? If you have any questions feel free to ask |
Sorry, I might be a bit slow to get to a review. |
This should be closed or renamed as #446 has been merged. |
@rj00a this should be closed. |
Description
Will solve issue: #332
This is draft, because I want to get feedback on early stage.
NodeFlow
NodeSystem
component, which contains a bevy's system, which will be executed when the command is executedNodeParser
component, which contains a boxed trait, which parses reader and puts the parsed object into special struct calledParseResultsWrite
NodeName
on them (noNodeParser
)NodeExclude
component on them to exclude nodes that this specific root node doesn't want to useEntityNode
component (if there is not such component on an entity thenPrimaryRootNode
will be chosen)spawn_node
,node
,spawn_root_node
)Check out example
command.rs