Skip to content

Commit

Permalink
Commit before trying to use UniqueRc
Browse files Browse the repository at this point in the history
  • Loading branch information
doonv committed Dec 23, 2023
1 parent 0193254 commit a79c1f3
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 118 deletions.
45 changes: 25 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,32 @@
## Usage

1. Add the `bevy_dev_console` git package.
```bash
cargo add --git https://github.com/doonv/bevy_dev_console.git
```

```bash
cargo add --git https://github.com/doonv/bevy_dev_console.git
```

2. Import the `prelude`.
```rs
use bevy_dev_console::prelude::*;
```

```rs
use bevy_dev_console::prelude::*;
```

3. Add the plugins.
```rs
App::new()
.add_plugins((
// Start capturing logs before the default plugins initiate.
ConsoleLogPlugin::default(),
// Add the default plugins without the LogPlugin.
// Not removing the LogPlugin will cause a panic!
DefaultPlugins.build().disable::<LogPlugin>(),
// Add the dev console plugin itself.
DevConsolePlugin,
))
```

```rs
App::new()
.add_plugins((
// Start capturing logs before the default plugins initiate.
ConsoleLogPlugin::default(),
// Add the default plugins without the LogPlugin.
// Not removing the LogPlugin will cause a panic!
DefaultPlugins.build().disable::<LogPlugin>(),
// Add the dev console plugin itself.
DevConsolePlugin,
))
```

4. That should be it! You can now press the `` ` `` or `~` key on your keyboard and it should open the console!
## Features
Expand All @@ -37,7 +43,6 @@ App::new()
## Bevy Compatibility

| bevy | bevy_dev_console |
| ------ | ---------------- |
| 0.12.* | 0.1.0 |
| 0.12.* | 0.1.0 |
20 changes: 19 additions & 1 deletion examples/custom_functions.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! A simple exmaple
use std::{cell::RefCell, rc::Weak};

use bevy::{
log::{Level, LogPlugin},
prelude::*,
};
use bevy_dev_console::{
builtin_parser::{Environment, Spanned, Value},
builtin_parser::{Environment, RunError, Spanned, Value},
prelude::*,
register,
};
Expand Down Expand Up @@ -45,6 +47,21 @@ fn increment_global_counter(world: &mut World) -> f64 {
})
}

// Function with reference (Syntax subject to change very soon)
fn increment_number(number: Spanned<Weak<RefCell<Value>>>) -> Result<(), RunError> {
let rc = number.value.upgrade().unwrap();
let mut reference = rc.borrow_mut();
if let Value::Number(number) = &mut *reference {
*number += 1.0;
Ok(())
} else {
Err(RunError::Custom {
text: "w".to_string(),
span: number.span,
})
}
}

// For more example take a look at the standard library.

// Register our functions by creating and inserting our own environment
Expand All @@ -57,6 +74,7 @@ fn custom_environment() -> Environment {
fn add;
fn print_debug_info;
fn increment_global_counter;
fn increment_number;
});

environment
Expand Down
3 changes: 1 addition & 2 deletions src/builtin_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ pub(crate) mod lexer;
pub(crate) mod parser;
pub(crate) mod runner;

pub use runner::environment::Environment;
pub use runner::Value;
pub use runner::{environment::Environment, Value, RunError};

/// Wrapper around `T` that stores a [Span] (A location in the source code)
#[derive(Debug, Clone)]
Expand Down
3 changes: 3 additions & 0 deletions src/builtin_parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ use super::{
Environment, Spanned,
};

/// An [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
///
/// This type represents a list of expressions, which is what makes up a command.
pub type Ast = Vec<Spanned<Expression>>;

macro_rules! expect {
Expand Down
26 changes: 4 additions & 22 deletions src/builtin_parser/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,10 @@ pub mod environment;
pub mod reflection;
pub mod stdlib;
pub mod value;
pub mod unique_rc;

pub use value::Value;

// enum ReflectMutlect<'a> {
// Ref(&'a mut dyn Reflect),
// Mut(Mut<'a, dyn Reflect>)
// }
// impl<'a> ReflectMutlect<'a> {
// pub fn to_ref(&'a mut self) -> &'a mut dyn Reflect {
// match self {
// ReflectMutlect::Ref(reference) => *reference,
// ReflectMutlect::Mut(reference) => reference.as_reflect_mut()
// }
// }
// }

/// Container for every value needed by evaluation functions.
pub struct EvalParams<'world, 'env, 'reg> {
world: &'world mut World,
Expand All @@ -44,7 +32,7 @@ pub struct EvalParams<'world, 'env, 'reg> {

#[derive(Debug)]
pub enum RunError {
Basic { text: String, span: Span },
Custom { text: String, span: Span },
VariableNotFound(Span),
ExpectedNumberAfterUnaryOperator(Value),
InvalidVariantForResource(String, String),
Expand Down Expand Up @@ -107,11 +95,7 @@ pub fn run(ast: Ast, world: &mut World) {

match value {
Ok(Value::None) => {}
Ok(value) => match value.try_format(
span,
&world,
&registrations,
) {
Ok(value) => match value.try_format(span, &world, &registrations) {
Ok(value) => info!(name: "console_result", "> {value}"),
Err(err) => error!("{err:?}"),
},
Expand Down Expand Up @@ -197,9 +181,7 @@ fn eval_expression(
}
})
} else {
Err(RunError::EnumVariantNotFound {
name: variable
})
Err(RunError::EnumVariantNotFound { name: variable })
}?
}
Expression::StructObject { name, map } => {
Expand Down
25 changes: 12 additions & 13 deletions src/builtin_parser/runner/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ macro_rules! register {
/// Get around implementation of Result causing stupid errors
pub(super) struct ResultContainer<T, E>(pub Result<T, E>);

impl<T: Into<Value>> From<T> for ResultContainer<Value, RunError> {
fn from(value: T) -> Self {
ResultContainer(Ok(value.into()))
}
}
impl<T, E> From<ResultContainer<T, E>> for Result<T, E> {
fn from(ResultContainer(result): ResultContainer<T, E>) -> Self {
result
Expand All @@ -60,9 +65,12 @@ impl<T: Into<Value>, E> From<Result<T, E>> for ResultContainer<Value, E> {
ResultContainer(result.map(|v| v.into()))
}
}
/// A parameter in a [`Function`].
pub trait FunctionParam: Sized {
// TODO: Add `Self` as default when https://github.com/rust-lang/rust/issues/29661 gets merged
/// TODO: Add `Self` as default when https://github.com/rust-lang/rust/issues/29661 gets merged
type Item<'world, 'env, 'reg>;
/// Whether this parameter requires a [`Spanned<Value>`].
/// If `false` then `FunctionParam::get`'s `value` will be [`None`], and vice versa.
const USES_VALUE: bool;

fn get<'world, 'env, 'reg>(
Expand All @@ -84,16 +92,6 @@ pub trait IntoFunction<T> {
fn into_function(self) -> Function;
}

macro_rules! replace_expr {
($_t:ident $sub:expr) => {
$sub
};
}

macro_rules! count_idents {
($($tts:ident)*) => {0usize $(+ replace_expr!($tts 1usize))*};
}

macro_rules! impl_into_function {
(
$($(
Expand Down Expand Up @@ -180,6 +178,7 @@ impl_into_function!(T1, T2, T3, T4, T5, T6);
impl_into_function!(T1, T2, T3, T4, T5, T6, T7);
impl_into_function!(T1, T2, T3, T4, T5, T6, T7, T8);

/// A variable inside the [`Environment`].
pub enum Variable {
Unmoved(Rc<RefCell<Value>>),
Moved,
Expand Down Expand Up @@ -207,8 +206,8 @@ impl Default for Environment {

impl Environment {
/// Set a variable.
pub fn set(&mut self, name: String, value: Rc<RefCell<Value>>) {
self.variables.insert(name, Variable::Unmoved(value));
pub fn set(&mut self, name: impl Into<String>, value: Rc<RefCell<Value>>) {
self.variables.insert(name.into(), Variable::Unmoved(value));
}

/// Returns a reference to a function if it exists.
Expand Down
10 changes: 7 additions & 3 deletions src/builtin_parser/runner/stdlib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::register;
use bevy::{log::info, ecs::world::World, reflect::TypeRegistration};
use bevy::{ecs::world::World, log::info, reflect::TypeRegistration};
use std::{cell::Ref, ops::Range};

use super::{Environment, RunError, Spanned, Value};

fn print(value: Spanned<Value>, world: &mut World, registrations: &[&TypeRegistration]) -> Result<(), RunError> {
fn print(
value: Spanned<Value>,
world: &mut World,
registrations: &[&TypeRegistration],
) -> Result<(), RunError> {
match value.value {
Value::String(string) => info!("{string}"),
_ => {
Expand Down Expand Up @@ -50,7 +54,7 @@ fn ref_depth(Spanned { span, value }: Spanned<Value>) -> Result<f64, RunError> {
}

/// Disposes of a [`Value`].
fn drop(_v: Value) {}
fn drop(_: Value) {}

pub fn register(environment: &mut Environment) {
register!(environment => {
Expand Down
27 changes: 27 additions & 0 deletions src/builtin_parser/runner/unique_rc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::{rc::Rc, ops::{DerefMut, Deref}, cell::RefCell};

struct UniqueRc<T: ?Sized>(Rc<T>);
impl<T: ?Sized> UniqueRc<T> {
pub fn into_rc(self) -> Rc<T> {
self.0
}
}
impl<T> UniqueRc<T> {
pub fn into_inner(self) -> T {
// SAFETY: There is only ever one owner of Rc
unsafe { Rc::try_unwrap(self.0).unwrap_unchecked() }
}
}

impl<T> Deref for UniqueRc<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl<T> DerefMut for UniqueRc<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
// SAFETY: There is only ever one owner of Rc
unsafe { Rc::get_mut(&mut self.0).unwrap_unchecked() }
}
}
Loading

0 comments on commit a79c1f3

Please sign in to comment.