Skip to content

Commit

Permalink
Merge pull request #200 from zmbush/optional-command-args
Browse files Browse the repository at this point in the history
  • Loading branch information
janhohenheim authored Jun 23, 2024
2 parents 63624b9 + 8dea3cc commit a0ab91c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 19 deletions.
8 changes: 7 additions & 1 deletion crates/bevy_plugin/src/commands/command_wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ where
let mut system_state: SystemState<T::Param> = SystemState::new(world);
let param = system_state.get_mut(world);
let mut input: Vec<_> = input.into_iter().map(YarnValueWrapper::from).collect();
let mut iter = input.iter_mut();
let mut iter = input.iter_mut().peekable();
let input = T::In::retrieve(&mut iter);
assert!(
iter.next().is_none(),
Expand Down Expand Up @@ -285,6 +285,12 @@ pub mod tests {
accepts_yarn_command(f);
}

#[test]
fn accepts_function_with_optional_in_param() {
fn f(_: In<Option<usize>>) {}
accepts_yarn_command(f);
}

#[test]
fn accepts_function_with_tuple_in_param() {
fn f(_: In<(usize, isize, (String, &str))>) {}
Expand Down
23 changes: 9 additions & 14 deletions crates/bevy_plugin/src/yarn_file_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ use crate::prelude::*;
use bevy::asset::{io::Reader, AsyncReadExt};
use bevy::prelude::*;

use bevy::{
asset::{AssetLoader, LoadContext},
utils::BoxedFuture,
};
use bevy::asset::{AssetLoader, LoadContext};
use std::hash::Hash;
use yarnspinner::prelude::YarnFile as InnerYarnFile;

Expand Down Expand Up @@ -80,18 +77,16 @@ impl AssetLoader for YarnFileAssetLoader {
type Asset = YarnFile;
type Settings = ();
type Error = anyhow::Error;
fn load<'a>(
async fn load<'a>(
&'a self,
reader: &'a mut Reader,
reader: &'a mut Reader<'_>,
_settings: &'a (),
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<Self::Asset, Self::Error>> {
Box::pin(async move {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let yarn_file = read_yarn_file(bytes, load_context)?;
Ok(yarn_file)
})
load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let yarn_file = read_yarn_file(bytes, load_context)?;
Ok(yarn_file)
}

fn extensions(&self) -> &[&str] {
Expand Down
18 changes: 17 additions & 1 deletion crates/core/src/yarn_fn/function_wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ macro_rules! impl_yarn_fn_tuple {
let mut params: Vec<_> = input.into_iter().map(YarnValueWrapper::from).collect();

#[allow(unused_variables, unused_mut)] // for n = 0 tuples
let mut iter = params.iter_mut();
let mut iter = params.iter_mut().peekable();

// $param is the type implementing YarnFnParam
let input = (
Expand Down Expand Up @@ -275,6 +275,22 @@ mod tests {
accept_yarn_fn(f);
}

#[test]
fn accepts_optional_value() {
fn f(_: Option<String>) -> bool {
true
}
accept_yarn_fn(f);
}

#[test]
fn accepts_optional_value_ref() {
fn f(_: Option<&YarnValue>) -> bool {
true
}
accept_yarn_fn(f);
}

#[test]
fn accepts_multiple_strings() {
fn f(s: String, _: String, _: &str, _: String, _: &str) -> String {
Expand Down
15 changes: 14 additions & 1 deletion crates/core/src/yarn_fn/parameter_wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::prelude::*;
use std::any::Any;
use std::borrow::Borrow;
use std::fmt::{Debug, Display};
use std::iter::Peekable;
use std::marker::PhantomData;
use std::slice::IterMut;
use yarnspinner_macros::all_tuples;
Expand All @@ -19,7 +20,7 @@ pub struct YarnValueWrapper {
}

#[doc(hidden)]
pub type YarnValueWrapperIter<'a> = IterMut<'a, YarnValueWrapper>;
pub type YarnValueWrapperIter<'a> = Peekable<IterMut<'a, YarnValueWrapper>>;

impl From<YarnValue> for YarnValueWrapper {
fn from(value: YarnValue) -> Self {
Expand Down Expand Up @@ -62,6 +63,18 @@ pub trait YarnFnParam {
/// Shorthand way of accessing the associated type [`YarnFnParam::Item`] for a given [`YarnFnParam`].
pub type YarnFnParamItem<'a, P> = <P as YarnFnParam>::Item<'a>;

impl<T: YarnFnParam> YarnFnParam for Option<T> {
type Item<'new> = Option<T::Item<'new>>;

fn retrieve<'a>(iter: &mut YarnValueWrapperIter<'a>) -> Self::Item<'a> {
if iter.peek().is_some() {
Some(T::retrieve(iter))
} else {
None
}
}
}

macro_rules! impl_yarn_fn_param_tuple {
($($param: ident),*) => {
#[allow(non_snake_case)]
Expand Down
3 changes: 3 additions & 0 deletions examples/bevy_yarnspinner/assets/dialogue/custom_command.yarn
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ title: CustomCommand
Inserting a resource after you continue this line.
<<insert_resource "Bob" 42>>

Update the name in the resource after you continue this line.
<<update_resource "Ivan">>

Reading the inserted resource after you continue this line. The output will be printed to the console.
<<read_resource>>
===
16 changes: 16 additions & 0 deletions examples/bevy_yarnspinner/src/bin/custom_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fn spawn_dialogue_runner(mut commands: Commands, project: Res<YarnProject>) {
dialogue_runner
.commands_mut()
.add_command("insert_resource", insert_resource)
.add_command("update_resource", update_resource)
.add_command("read_resource", read_resource);
dialogue_runner.start_node("CustomCommand");
commands.spawn(dialogue_runner);
Expand All @@ -54,3 +55,18 @@ fn read_resource(_: In<()>, previously_added_resource: Res<SomethingAddedByYarnS
previously_added_resource.name, previously_added_resource.age
);
}

// Commands may also take arguments as `Option<_>` which allows commands with optional arguments.
// This function can be called either like:
// `<<update_resource "Bob">>`
// or
// `<<update_resource "Bob" 42>>`
fn update_resource(
In((name, age)): In<(String, Option<f32>)>,
mut resource: ResMut<SomethingAddedByYarnSpinner>,
) {
resource.name = name;
if let Some(age) = age {
resource.age = age;
}
}
2 changes: 0 additions & 2 deletions rust-toolchain.toml

This file was deleted.

0 comments on commit a0ab91c

Please sign in to comment.