misode / brigadier-ts

TypeScript port of Mojang/brigadier
MIT License
18 stars 5 forks source link

Allow asynchronous commands #6

Open haykam821 opened 2 years ago

haykam821 commented 2 years ago

Currently, the return type of CommandDispatcher#execute is a number, as the Command type requires a number | void return type. As a result, commands cannot be executed asynchronously.

misode commented 2 years ago

Does Mojang/brigadier allow commands to be executed asynchronously?

haykam821 commented 2 years ago

Asynchronous commands aren't supported in the Java library, but Java does not have promise or async/await support like JavaScript does. Promises would have a less intrusive presence on Brigadier than Java's futures.

misode commented 2 years ago

I'm unsure whether this would be possible, I still want to support synchronous command execution as there are cases where async execution is unpreferable.

When CommandDispatcher#execute runs it should know in advance whether or not it will return a promise or not. One idea I had was a generic parameter for the dispatcher, arguments and commands that extends number | Promise<number>. I may try this later but not sure it's going to work.

Kind of similar to https://github.com/Mojang/brigadier/pull/62 I realize, maybe I can take this as inspiration

haykam821 commented 1 year ago

Although such an approach wouldn't be entirely backwards compatible, I think the Command type could include promises, and the CommandDispatcher#execute method could upgrade the return type to a promise if any individual command returned a promise. As long as the command tree does not contain any commands returning promises, the CommandDispatcher#execute method will never return a promise.

Alternatively, your approach could work, but would require a fair bit of refactoring to pass the type parameter down from the command source to nodes.

I hope asynchronous commands become possible in the future no matter what approach is taken, because promises unlock to ability to do particularly neat things that aren't easily possible synchronously.