diff --git a/.cargo/config.toml b/.cargo/config.toml index ce9ac38..9d74484 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -13,19 +13,19 @@ rustflags = ["-Clink-arg=-fuse-ld=lld"] rustflags = [ "-C", "link-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld", - "-Zshare-generics=y", + # "-Zshare-generics=y", ] [target.aarch64-apple-darwin] rustflags = [ "-C", "link-arg=-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld", - "-Zshare-generics=y", + # "-Zshare-generics=y", ] [target.x86_64-pc-windows-msvc] linker = "rust-lld.exe" -rustflags = ["-Zshare-generics=n"] +# rustflags = ["-Zshare-generics=n"] # Optional: Uncommenting the following improves compile times, but reduces the amount of debug info to 'line number tables only' # In most cases the gains are negligible, but if you are on macos and have slow compile times you should see significant gains. diff --git a/examples/basic.rs b/examples/basic.rs index b016a86..aa39114 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,4 +1,4 @@ -//! A simple exmaple +//! A simple example use bevy::{ log::{Level, LogPlugin}, @@ -16,6 +16,7 @@ fn main() { // Not removing the LogPlugin will cause a panic! DefaultPlugins.build().disable::(), // Add the dev console plugin itself. + DevConsolePlugin, )) .add_systems(Startup, test) .run(); diff --git a/examples/custom_functions.rs b/examples/custom_functions.rs new file mode 100644 index 0000000..850f358 --- /dev/null +++ b/examples/custom_functions.rs @@ -0,0 +1,62 @@ +//! A simple exmaple + +use bevy::{ + log::{Level, LogPlugin}, + prelude::*, +}; +use bevy_dev_console::{ + builtin_parser::{Environment, Spanned, Value}, + prelude::*, + register, +}; + +// Declare the functions we want to create: + +// Basic function +fn time_since_epoch() { + let time = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap(); + info!("The unix epoch was {} seconds ago", time.as_secs()); +} + +// Function with parameters and return value +fn add(num1: f64, num2: f64) -> f64 { + num1 + num2 +} + +// Function with any value + span +fn print_debug_info(value: Spanned) { + info!( + "Location in command: {:?}, Value: {:?}", + value.span, value.value + ) +} + +// For more example take a look at the standard library. + +// Register our functions by creating and inserting our own environment +fn custom_environment() -> Environment { + let mut environment = Environment::default(); + + // The register macro allows us to easily add functions to the environment. + register!(&mut environment => { + fn time_since_epoch; + fn add; + fn print_debug_info; + }); + + environment +} + +fn main() { + App::new() + // Insert our new environment + .insert_non_send_resource(custom_environment()) + .add_plugins(( + ConsoleLogPlugin::default().append_filter(module_path!(), Level::TRACE), + DefaultPlugins.build().disable::(), + DevConsolePlugin, + )) + .run(); +} diff --git a/examples/resource.rs b/examples/resource.rs index a633903..5cd4218 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -1,5 +1,5 @@ //! Example of modifying resources via the console via reflection. -//! +//! //! **Warning:** This is very experimental, might not work. use bevy::{log::LogPlugin, prelude::*}; diff --git a/src/builtin_parser.rs b/src/builtin_parser.rs index a24d9b5..33322dd 100644 --- a/src/builtin_parser.rs +++ b/src/builtin_parser.rs @@ -1,7 +1,7 @@ //! [`bevy_dev_console`](crate)'s built-in command parser. -//! +//! //! Currently the built-in command parser is in very early development. -//! It's purpose is to provide a simple, yet powerful method of modifying +//! It's purpose is to provide a simple, yet powerful method of modifying //! the game world via commands. use bevy::prelude::*; @@ -16,11 +16,12 @@ pub(crate) mod parser; pub(crate) mod runner; pub use runner::environment::Environment; +pub use runner::Value; /// Wrapper around `T` that stores a [Span] (A location in the source code) #[derive(Debug, Clone)] pub struct Spanned { - /// The location of `T` in the source. + /// The location of `T` in the source/command. pub span: Span, /// The value of `T`. pub value: T, @@ -33,7 +34,7 @@ impl Default for DefaultCommandParser { } /// [`bevy_dev_console`](crate)'s built-in command parser. -/// +/// /// See the [module level documentation for more](self). #[derive(Default)] pub struct BuiltinCommandParser; diff --git a/src/builtin_parser/runner/environment.rs b/src/builtin_parser/runner/environment.rs index f236817..0cce672 100644 --- a/src/builtin_parser/runner/environment.rs +++ b/src/builtin_parser/runner/environment.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; -use bevy::{ecs::world::World, reflect::TypeRegistration}; +use bevy::{ecs::world::World, log::warn, reflect::TypeRegistration}; use logos::Span; use super::{ @@ -254,8 +254,12 @@ impl Environment { name: impl Into, function: impl IntoFunction, ) -> &mut Self { + let name = name.into(); + if self.variables.contains_key(&name) { + warn!("Function {name} declared twice.") + } self.variables - .insert(name.into(), Variable::Function(function.into_function())); + .insert(name, Variable::Function(function.into_function())); self } diff --git a/src/builtin_parser/runner/stdlib.rs b/src/builtin_parser/runner/stdlib.rs index e2913e7..5c2fe01 100644 --- a/src/builtin_parser/runner/stdlib.rs +++ b/src/builtin_parser/runner/stdlib.rs @@ -2,7 +2,7 @@ use std::{cell::Ref, ops::Range}; use bevy::log::info; -use super::{RunError, Value, Environment, Spanned}; +use super::{Environment, RunError, Spanned, Value}; fn print(value: Spanned) -> Result<(), RunError> { match value.value { @@ -49,6 +49,9 @@ fn ref_depth(Spanned { span, value }: Spanned) -> Result { }) } +/// Disposes of a [`Value`]. +fn drop(_v: Value) {} + /// Macro for mass registering functions. /// /// ``` @@ -85,10 +88,12 @@ macro_rules! register { )* }; } + pub fn register(environment: &mut Environment) { register!(environment => { fn print; fn dbg; fn ref_depth; + fn drop; }); } diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index e1a5ca1..8b91e62 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -3,7 +3,7 @@ use std::rc::Weak; use std::{cell::RefCell, rc::Rc}; use super::environment::{FunctionParameterData, ResultContainer}; -use super::{RunError, super::Spanned}; +use super::{super::Spanned, RunError}; use bevy::ecs::world::World; use bevy::reflect::Reflect; @@ -30,16 +30,23 @@ pub enum Value { /// This isn't partically efficent, so: /// TODO: Create a custom type this! Reference(Weak>), + /// A dynamic [`HashMap]. + Object(HashMap>>), + /// An [`Object`](Value::Object) with a name attached to it. StructObject { + /// The name of the struct name: String, + /// The [`Object`](Value::Object) [`HashMap`]. map: HashMap>>, }, - /// A reference to a dynamic value. (aka a reference.) + /// A reference to a dynamic value. (aka a reference) Dynamic(Box), - Object(HashMap>>), } impl Value { + /// Attempts to format this [`Value`]. + /// + /// Returns an error if the [`Value`] is a reference to moved data. pub fn try_format(&self, span: Span) -> Result { match self { Value::None => Ok(format!("()")), diff --git a/src/command.rs b/src/command.rs index 89206db..2dd99b4 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,6 +1,6 @@ //! Command execution functionality. -use bevy::{prelude::*, ecs::system::Command}; +use bevy::{ecs::system::Command, prelude::*}; /// The command parser currrently being used by the dev console. #[derive(Resource)] @@ -15,12 +15,12 @@ impl DefaultCommandParser { /// The trait that all [`CommandParser`]s implement. /// You can take a look at the [builtin parser](crate::builtin_parser) for an example. -/// +/// /// ``` /// # use bevy::ecs::world::World; /// # use bevy_dev_console::command::CommandParser; /// # use bevy::log::info; -/// +/// /// pub struct MyCustomParser; /// impl CommandParser for MyCustomParser { /// fn parse(&self, command: &str, world: &mut World) { @@ -45,4 +45,4 @@ impl Command for ExecuteCommand { error!("Default command parser doesn't exist, cannot execute command."); } } -} \ No newline at end of file +} diff --git a/src/ui.rs b/src/ui.rs index dc8a607..754d654 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -19,7 +19,7 @@ pub struct ConsoleUiState { fn system_time_to_chorno_utc(t: SystemTime) -> chrono::DateTime { let dur = t.duration_since(instant::SystemTime::UNIX_EPOCH).unwrap(); let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos()); - + chrono::Utc.timestamp_opt(sec, nsec).unwrap() } @@ -108,7 +108,7 @@ fn add_log( ui.push_id(id, |ui| { let time_utc = system_time_to_chorno_utc(*time); - let time: chrono::DateTime:: = time_utc.into(); + let time: chrono::DateTime = time_utc.into(); let res = ui .horizontal_wrapped(|ui| { ui.label(egui::RichText::new(time.format("%H:%M").to_string()).font(FONT_ID));