diff --git a/Cargo.toml b/Cargo.toml index 88f3db6..6fbaa60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,19 +23,20 @@ builtin-parser = ["dep:logos"] [dependencies] # This crate by itself doesn't use any bevy features, but `bevy_egui` (dep) uses "bevy_asset". -bevy = { version = "0.14.0", default-features = false, features = [] } -bevy_egui = "0.28.0" +bevy = { version = "0.15.0", default-features = false, features = [] } +bevy_egui = "0.31.1" chrono = "0.4.31" tracing-log = "0.2.0" tracing-subscriber = "0.3.18" web-time = "1.0.0" +winit = "0.30.5" # builtin-parser features logos = { version = "0.14.0", optional = true } fuzzy-matcher = { version = "0.3.7", optional = true } [dev-dependencies] -bevy = "0.14.0" +bevy = "0.15.0" [lints] clippy.useless_format = "allow" diff --git a/src/builtin_parser/runner.rs b/src/builtin_parser/runner.rs index 1146605..500efcf 100644 --- a/src/builtin_parser/runner.rs +++ b/src/builtin_parser/runner.rs @@ -332,7 +332,7 @@ fn eval_expression( }?; dynamic_tuple.insert_boxed( - element.value.into_inner().reflect(element.span, ty)?, + element.value.into_inner().reflect(element.span, ty)?.into_partial_reflect(), ); } @@ -369,12 +369,8 @@ fn eval_expression( .reflect_path_mut(resource.path.as_str()) .unwrap(); - reflect.set(value_reflect).map_err(|value_reflect| { - EvalError::IncompatibleReflectTypes { - span, - expected: reflect.reflect_type_path().to_string(), - actual: value_reflect.reflect_type_path().to_string(), - } + reflect.try_apply(value_reflect.as_partial_reflect()).map_err(|apply_error| { + EvalError::ApplyError {apply_error, span} })?; } } @@ -441,7 +437,6 @@ fn eval_expression( )?; Ok(Value::StructTuple { name, tuple }) } - Expression::BinaryOp { left, operator, diff --git a/src/builtin_parser/runner/environment.rs b/src/builtin_parser/runner/environment.rs index b30d345..4463134 100644 --- a/src/builtin_parser/runner/environment.rs +++ b/src/builtin_parser/runner/environment.rs @@ -246,11 +246,11 @@ impl Environment { let var = env.variables.get_mut(name); let fn_obj = match var { Some(Variable::Function(_)) => { - let Variable::Function(mut fn_obj) = - std::mem::replace(var.unwrap(), Variable::Moved) - else { - unreachable!() - }; + let Variable::Function(mut fn_obj) = + std::mem::replace(var.unwrap(), Variable::Moved) + else { + unreachable!() + }; return_result = function(env, &mut fn_obj); diff --git a/src/builtin_parser/runner/error.rs b/src/builtin_parser/runner/error.rs index 6892de4..99785d5 100644 --- a/src/builtin_parser/runner/error.rs +++ b/src/builtin_parser/runner/error.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use bevy::reflect::ApplyError; use logos::Span; use crate::builtin_parser::number::Number; @@ -75,6 +76,10 @@ pub enum EvalError { field_index: usize, tuple_size: usize, }, + ApplyError { + apply_error: ApplyError, + span: Span + } } impl EvalError { @@ -106,6 +111,7 @@ impl EvalError { E::InvalidOperation { span, .. } => vec![span.clone()], E::IncorrectAccessOperation { span, .. } => vec![span.clone()], E::FieldNotFoundInTuple { span, .. } => vec![span.clone()], + E::ApplyError { span , ..} => vec![span.clone()], } } /// Returns all the hints for this error. @@ -232,6 +238,9 @@ impl std::fmt::Display for EvalError { f, "Field {field_index} is out of bounds for tuple of size {tuple_size}" ), + E::ApplyError { apply_error, span: _} => { + write!(f, "Error while applying value (todo make this error better): {apply_error}") + } } } } diff --git a/src/builtin_parser/runner/reflection.rs b/src/builtin_parser/runner/reflection.rs index 2114f5d..c107c75 100644 --- a/src/builtin_parser/runner/reflection.rs +++ b/src/builtin_parser/runner/reflection.rs @@ -48,13 +48,14 @@ impl IntoResource { pub fn object_to_dynamic_struct( hashmap: HashMap, ) -> Result { - let mut dynamic_struct = DynamicStruct::default(); + todo!() + // let mut dynamic_struct = DynamicStruct::default(); - for (key, (value, span, reflect)) in hashmap { - dynamic_struct.insert_boxed(&key, value.reflect(span, reflect)?); - } + // for (key, (value, span, reflect)) in hashmap { + // dynamic_struct.insert_boxed(&key, value.reflect(span, reflect)?); + // } - Ok(dynamic_struct) + // Ok(dynamic_struct) } pub fn mut_dyn_reflect<'a>( diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index 711ed3a..d86e2d8 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -12,8 +12,7 @@ use super::unique_rc::WeakRef; use bevy::ecs::world::World; use bevy::reflect::{ - DynamicStruct, DynamicTuple, GetPath, Reflect, ReflectRef, TypeInfo, TypeRegistration, - VariantInfo, VariantType, + DynamicStruct, DynamicTuple, GetPath, PartialReflect, Reflect, ReflectRef, TypeInfo, TypeRegistration, VariantInfo, VariantType }; use logos::Span; @@ -61,13 +60,13 @@ pub enum Value { } impl Value { - /// Converts this value into a [`Box`]. + /// Converts this value into a [`Box`]. /// /// `ty` is used for type inference. - pub fn reflect(self, span: Span, ty: &str) -> Result, EvalError> { + pub fn reflect(self, span: Span, ty: &str) -> Result, EvalError> { match self { Value::None => Ok(Box::new(())), - Value::Number(number) => number.reflect(span, ty), + Value::Number(number) => number.reflect(span, ty).map(PartialReflect::into_partial_reflect), Value::Boolean(boolean) => Ok(Box::new(boolean)), Value::String(string) => Ok(Box::new(string)), Value::Reference(_reference) => Err(EvalError::CannotReflectReference(span)), @@ -245,7 +244,7 @@ fn fancy_debug_print( let reflect = dyn_reflect.reflect_path(resource.path.as_str()).unwrap(); - fn debug_subprint(reflect: &dyn Reflect, indentation: usize) -> String { + fn debug_subprint(reflect: &dyn PartialReflect, indentation: usize) -> String { let mut f = String::new(); let reflect_ref = reflect.reflect_ref(); let indentation_string = TAB.repeat(indentation); @@ -311,9 +310,10 @@ fn fancy_debug_print( VariantType::Unit => {} } } - ReflectRef::Value(_) => { + ReflectRef::Opaque(_) => { f += &format!("{reflect:?}"); } + ReflectRef::Set(_) => todo!() } f @@ -343,6 +343,7 @@ fn fancy_debug_print( ReflectRef::List(_) => todo!(), ReflectRef::Array(_) => todo!(), ReflectRef::Map(_) => todo!(), + ReflectRef::Set(_) => todo!(), ReflectRef::Enum(set_variant_info) => { // Print out the enum types f += &format!("enum {} {{\n", set_variant_info.reflect_short_type_path()); @@ -401,7 +402,7 @@ fn fancy_debug_print( VariantType::Unit => {} } } - ReflectRef::Value(value) => { + ReflectRef::Opaque(value) => { f += &format!("{value:?}"); } } diff --git a/src/ui.rs b/src/ui.rs index aa859d5..fed5d90 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -117,7 +117,7 @@ pub fn render_ui( info!(name: COMMAND_MESSAGE_NAME, "{COMMAND_MESSAGE_PREFIX}{}", command.trim()); // Get the owned command string by replacing it with an empty string let command = std::mem::take(command); - commands.add(ExecuteCommand(command)); + commands.queue(ExecuteCommand(command)); } } diff --git a/src/ui/completions.rs b/src/ui/completions.rs index 208cc13..026a512 100644 --- a/src/ui/completions.rs +++ b/src/ui/completions.rs @@ -60,7 +60,7 @@ pub fn completions( // If not found, the whole substring is a word None => before_cursor, }; - commands.add(UpdateAutoComplete(keyword_before.to_owned())); + commands.queue(UpdateAutoComplete(keyword_before.to_owned())); } else { ui.memory_mut(|mem| { if mem.is_popup_open(text_edit_complete_id) {