YarnSpinnerTool / YarnSpinner-Rust

The friendly tool for writing game dialogue in Rust
https://janhohenheim.itch.io/yarnspinner-rust-demo
Apache License 2.0
173 stars 15 forks source link

Export `Optionality` markers #203

Closed zmbush closed 4 months ago

zmbush commented 4 months ago

In order to support custom implementations of YarnFnParam, Optional and Required need to be exported.

This exports yarnspinner_core::yarn_fn::optionality as yarnspinner_core::prelude::optionality and seals the AllowedOptionalityChain trait so it cannot be implemented.

janhohenheim commented 4 months ago

Huh, I was even considering explicitly sealing YarnFnParam. I'm curious, why do you need a custom YarnFnParam implementation?

bash commented 4 months ago

@janhohenheim If you decide to merge this then I intend to do a follow-up PR to change Optionality to be an enum / associated const. I think that would make for a nicer public API than the current approach :)

@zmbush Would you be okay with me pushing that change onto this PR?

zmbush commented 4 months ago

It's nice to have for convenience. I have a bunch of types that I use as command arguments, and instead of taking them as Strings, it's nice to be able to do something like:

    #[yarn_command(dialog_runner)]
    fn set_background(
        In((new_bg, mode)): In<(Location, ShowOption)>,
        ...
    ) { 
        ...
    }

instead of

    #[yarn_command(dialog_runner)]
    fn set_background(
        In((new_bg, mode)): In<(String, String)>,
        ...
    ) { 
        let new_bg: Location = new_bg.parse().unwrap();
        let mode: ShowOption = mode.parse().unwrap();
        ...
    }
zmbush commented 4 months ago

@zmbush Would you be okay with me pushing that change onto this PR?

@bash Yeah, go ahead!

janhohenheim commented 4 months ago

@zmbush I see! I was thinking about making automatic parsing a feature as well, so this workaround is completely valid. I'll merge @bash's counteroffer when it's ready :)

Btw, what's that #[yarn_command(dialog_runner)]? It looks nifty. I assume it expands to something like this?

fn register_set_background(mut dialog_runner: Query<&mut DialogueRunner, Added<DialogueRunner>>) {
  for mut dialog_runner in dialog_runner.iter_mut() {
    dialog_runner.commands_mut().add_command("set_background", set_background);
  }
}
zmbush commented 4 months ago

@janhohenheim Yeah, that's essentially what it does. It actually started as a way to generate ysls.json files for commands so that the language server would be able to detect them. I can try to upstream it if you're interested. (This is how the current version is used: https://gist.github.com/zmbush/f23752ac3453e9ff7d3173ca8e11f898#file-yarn_command_demo-rs)

janhohenheim commented 4 months ago

Yeah, generating ysls.json is also on my to do list 😅 I'll look into it once Yarn Spinner V3 launches at the latest because I'll need to port a whole bunch of stuff by then anyways. It should be possible to generate it without macros because we have runtime info on both the function name and its signature (well, other than the parameter names, but that's not important for the language server).

The macro looks nice! I wouldn't upstream it since I prefer to expose exactly one way to configure stuff, but I am tempted to replicate it for my own project :D

BTW, please ping me if you publish anything using the crate, I'd love to see what cool stuff people create with it :)

bash commented 4 months ago

change Optionality to be an enum / associated const

Never mind, associated consts and where clauses do not like each other :/

janhohenheim commented 4 months ago

@zmbush I assume sealing Optionality does not break your workflow?

zmbush commented 4 months ago

@janhohenheim / @bash Sealing Optionality still works for my uses.