You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What problem does this solve or what need does it fill?
Custom commands are cumbersome and bulky to work with. See book draft for current design.
What solution would you like?
impl Command for <impl FnOnce(&mut World)>
This could be used for simple one-off use-cases where the whole struct + trait extension pattern is too heavy.
What alternative(s) have you considered?
Running systems as commands has similar effects, see #2234. However, it has higher overhead and is not well-suited to reusing custom entity spawning / other archetype modifying logic (unless we use it to insert new exclusive systems).
I see no harm in implementing Command for functions / supporting this. But I wouldn't recommend it for any "structured / reusable" command, especially those with inputs. Extension methods are 100% optional, so in practice this is the difference:
// Struct with no inputsstructFoo;implCommandforFoo{fnwrite(self,world:&mutWorld){/* do thing */}}
commands.add(Foo);// Struct with inputsstructBar{baz:usize,}implCommandforBar{fnwrite(self,world:&mutWorld){/* do thing */}}
commands.add(Bar{baz:42};
// Floating functions with no inputsfnfoo(world:&mutWorld){/* do thing */}
commands.add(foo);// Floating function with inputsfnbar(baz:usize) -> implFnOnce(&mutWorld){move |world:&mutWorld| {/* do thing with baz */}}
commands.add(bar(42));
I think functions will be most useful for one-off system-specific capture closure commands. Traits seems way clearer for reusable commands (both on the definition and consumption side).
You could go one further, and even make the extension trait with a macro 🤔
// Creates a param-storage struct and extends the Command trait.#[command]fndo_stuff(world:&mutWorld,param1:Param1){// Does things}// Usage
commands.do_stuff(param1);
Sure, but a macro doesn't seem very practical here, or very bevy-ish. But, I'd say floating fn with inputs personally looks pretty clean, though that's more so a style thing.
Activity
cart commentedon Oct 1, 2021
I see no harm in implementing Command for functions / supporting this. But I wouldn't recommend it for any "structured / reusable" command, especially those with inputs. Extension methods are 100% optional, so in practice this is the difference:
I think functions will be most useful for one-off system-specific capture closure commands. Traits seems way clearer for reusable commands (both on the definition and consumption side).
Supermath101 commentedon Oct 2, 2021
Why don't we just make a macro to convert a standard function into that special format?
alice-i-cecile commentedon Oct 2, 2021
You could go one further, and even make the extension trait with a macro 🤔
TheRawMeatball commentedon Oct 2, 2021
Sure, but a macro doesn't seem very practical here, or very bevy-ish. But, I'd say floating fn with inputs personally looks pretty clean, though that's more so a style thing.
alice-i-cecile commentedon Oct 2, 2021
Yeah, my preference is for the floating fn personally; I think it's nice for simple one-off uses.
That plus proper docs on how to do custom commands the Proper Way should be plenty.
mockersf commentedon Oct 4, 2021
Wouldn't a floating fn with input be a system? So #2234 would fix this?
TheRawMeatball commentedon Oct 5, 2021
Chances are if you're writing a custom command it's because you need direct world access, so, probably not.
alice-i-cecile commentedon Oct 5, 2021
Does #2234 work with exclusive systems @mockersf?
TheRawMeatball commentedon Oct 5, 2021
Even if it did, getting all the system stuff feels like unnecessary complexity.
impl Command for <impl FnOnce(&mut World)>
impl Command for <impl FnOnce(&mut World)> (#2996)
Squashed commit of the following: