Compare commits

..

No commits in common. "c5510c9075395da2f2858d689d092b1c06017ab2" and "fa70abac23b32b70deb76e935819c62998bef1fd" have entirely different histories.

27 changed files with 375 additions and 411 deletions

View file

@ -1,34 +0,0 @@
name: "Install Ruby"
inputs:
ruby-version:
required: true
runs:
using: "composite"
steps:
- name: Setup env
shell: bash
run: |
echo "PATH=/opt/rubies/${{ inputs.ruby-version }}/bin:$PATH" >> $GITHUB_ENV
echo "GEM_HOME=~/.gem/ruby/${{ inputs.ruby-version }}" >> $GITHUB_ENV
- name: Cache
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
with:
path: |
/opt/rubies/${{ inputs.ruby-version }}
~/.gem/ruby/${{ inputs.ruby-version }}
key: ruby-static-${{ runner.os }}-${{ inputs.ruby-version }}
- name: Build static ruby
working-directory: /tmp
shell: bash
run: |
if [ -d /opt/rubies/${{inputs.ruby-version }} ]; then
echo "Ruby ${{ inputs.ruby-version }} already installed, skipping build"
else
git clone https://github.com/rbenv/ruby-build.git
PREFIX=/usr/local sudo -E ./ruby-build/install.sh
CC=clang RUBY_CONFIGURE_OPTS="--disable-shared" sudo -E ruby-build ${{ inputs.ruby-version }} /opt/rubies/${{ inputs.ruby-version }}
fi

View file

@ -10,10 +10,35 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/ruby_install
- uses: actions/checkout@v4
with:
ruby-version: "3.4.4"
fetch-depth: 0
- name: Cache Ruby
id: cache-ruby
uses: actions/cache@v4
with:
path: rubies
key: ${{ runner.os }}-ruby
- name: Install Ruby
if: steps.cache-ruby.outputs.cache-hit != 'true'
env:
CC: clang
run: |
url="https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.4.tar.gz"
prefix=`pwd`/rubies/ruby-3.4
mkdir rubies
mkdir ruby_src
curl -sSL $url | tar -xz
cd ruby-3.4.4
mkdir build
cd build
../configure --without-shared --prefix=$prefix
make install
echo $prefix/bin >> $GITHUB_PATH
- name: Add Ruby to PATH
run: |
prefix=`pwd`/rubies/ruby-3.4
echo $prefix/bin >> $GITHUB_PATH
- name: Install latest mdbook
run: |
tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name')

View file

@ -11,19 +11,36 @@ env:
jobs:
build:
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings
strategy:
matrix:
ruby-version: ["3.4.4"]
sys:
- os: ubuntu-latest
runs-on: ${{ matrix.sys.os }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/ruby_install
- name: Cache Ruby
id: cache-ruby
uses: actions/cache@v4
with:
ruby-version: ${{ matrix.ruby-version }}
path: rubies
key: ${{ runner.os }}-ruby
- name: Install Ruby
if: steps.cache-ruby.outputs.cache-hit != 'true'
env:
CC: clang
run: |
url="https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.4.tar.gz"
prefix=`pwd`/rubies/ruby-3.4
mkdir rubies
mkdir ruby_src
curl -sSL $url | tar -xz
cd ruby-3.4.4
mkdir build
cd build
../configure --without-shared --prefix=$prefix
make install
- name: Add Ruby to PATH
run: |
prefix=`pwd`/rubies/ruby-3.4
echo $prefix/bin >> $GITHUB_PATH
- name: Clippy
run: cargo clippy --all-features --verbose -- -D warnings
- name: Build

View file

@ -1,7 +1,7 @@
[package]
name = "bevy_scriptum"
authors = ["Jaroslaw Konik <konikjar@gmail.com>"]
version = "0.10.0"
version = "0.9.1"
edition = "2024"
license = "MIT OR Apache-2.0"
readme = "README.md"
@ -16,14 +16,14 @@ rhai = ["dep:rhai"]
ruby = ["dep:magnus", "dep:rb-sys"]
[dependencies]
bevy = { default-features = false, version = "0.17", features = ["bevy_asset", "bevy_log"] }
bevy = { default-features = false, version = "0.16", features = ["bevy_asset", "bevy_log"] }
serde = "1.0.162"
rhai = { version = "1.14.0", features = [
"sync",
"internals",
"unchecked",
], optional = true }
thiserror = "1.0.69"
thiserror = "1.0.40"
anyhow = "1.0.82"
tracing = "0.1.40"
mlua = { version = "0.9.8", features = [
@ -31,7 +31,7 @@ mlua = { version = "0.9.8", features = [
"vendored",
"send",
], optional = true }
magnus = { version = "0.8.2", optional = true }
magnus = { version = "0.7.1", optional = true }
rb-sys = { version = "0.9", default-features = false, features = ["link-ruby", "ruby-static"], optional = true }
crossbeam-channel = "0.5.15"
libc = "0.2.172"

View file

@ -98,7 +98,7 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy_scriptum = { version = "0.10", features = ["lua"] }
bevy_scriptum = { version = "0.9", features = ["lua"] }
```
or execute `cargo add bevy_scriptum --features lua` from your project directory.
@ -167,7 +167,6 @@ The examples live in `examples` directory and their corresponding scripts live i
| bevy version | bevy_scriptum version |
|--------------|-----------------------|
| 0.17 | 0.10 |
| 0.16 | 0.8-0.9 |
| 0.15 | 0.7 |
| 0.14 | 0.6 |

View file

@ -7,7 +7,7 @@ currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 0.10 | :white_check_mark: |
| 0.9 | :white_check_mark: |
## Reporting a Vulnerability

533
book/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
[book]
authors = ["Jaroslaw Konik"]
language = "en"
multilingual = false
src = "src"
title = "bevy_scriptum"

View file

@ -2,7 +2,6 @@
| bevy version | bevy_scriptum version |
| ------------ | --------------------- |
| 0.17 | 0.10 |
| 0.16 | 0.8-0.9 |
| 0.15 | 0.7 |
| 0.14 | 0.6 |

View file

@ -120,7 +120,7 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy_scriptum = { version = "0.10", features = ["lua"] }
bevy_scriptum = { version = "0.9", features = ["lua"] }
```
or execute `cargo add bevy_scriptum --features lua` from your project directory.

View file

@ -4,8 +4,8 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy = "0.17"
bevy_scriptum = { version = "0.10", features = ["lua"] }
bevy = "0.16"
bevy_scriptum = { version = "0.9", features = ["lua"] }
```
If you need a different version of bevy you need to use a matching bevy_scriptum

View file

@ -4,8 +4,8 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy = "0.17"
bevy_scriptum = { version = "0.10", features = ["rhai"] }
bevy = "0.16"
bevy_scriptum = { version = "0.9", features = ["rhai"] }
```
If you need a different version of bevy you need to use a matching bevy_scriptum

View file

@ -13,20 +13,9 @@ After installing `rbenv` along with its `ruby-build` plugin you can build and
install a Ruby installation that will work with `bevy_scriptum` by executing:
```sh
CC=clang RUBY_CONFIGURE_OPTS="--disable-shared" rbenv install 3.4.4
CC=clang rbenv install 3.4.4
```
Before building make sure you are using the correct Ruby version.
It can be done for example by executing `which ruby`.
Output should be similar to `/home/$USER/.rbenv/shims/ruby`.
If the version is not correct then refer to `rbenv` manual or documentation
relevant for your method of installation to switch to correct Ruby.
To set Ruby version for current shell for example `rbenv shell 3.4.4` can be
used.
If ruby-static installation can't be found its advisable to run `cargo clean`
before building as `rb-sys` may have cached an incorrect Ruby version.
Above assumes that you also have `clang` installed on your system.
For `clang` installation instruction consult your
OS vendor provided documentation or [clang official webiste](https://clang.llvm.org).
@ -45,8 +34,8 @@ Add the following to your `Cargo.toml`:
```toml
[dependencies]
bevy = "0.17"
bevy_scriptum = { version = "0.10", features = ["ruby"] }
bevy = "0.16"
bevy_scriptum = { version = "0.9", features = ["ruby"] }
```
If you need a different version of bevy you need to use a matching bevy_scriptum

View file

@ -6,7 +6,7 @@ To enable live reload it should be enough to enable `file-watcher` feature
within bevy dependency in `Cargo.toml`
```toml
bevy = { version = "0.17", features = ["file_watcher"] }
bevy = { version = "0.16", features = ["file_watcher"] }
```
## Init-teardown pattern
@ -81,7 +81,7 @@ fn update(
fn teardown(
mut ev_asset: MessageReader<AssetEvent<LuaScript>>,
mut ev_asset: EventReader<AssetEvent<LuaScript>>,
scripting_runtime: ResMut<LuaRuntime>,
mut scripted_entities: Query<(Entity, &mut LuaScriptData)>,
) {

View file

@ -8,7 +8,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_lua_on_update_from_rust)
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})

View file

@ -8,7 +8,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_lua_on_update_from_rust)
.add_scripting::<LuaRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})
@ -24,7 +24,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
fn call_lua_on_update_from_rust(
mut scripted_entities: Query<(Entity, &mut LuaScriptData)>,
scripting_runtime: ResMut<LuaRuntime>,
mut exit: MessageWriter<AppExit>,
mut exit: EventWriter<AppExit>,
) {
for (entity, mut script_data) in &mut scripted_entities {
let val = scripting_runtime

View file

@ -33,7 +33,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
),));
}
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: MessageWriter<AppExit>) {
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: EventWriter<AppExit>) {
if !query.is_empty() {
for e in &query {
println!("{}", e);

View file

@ -8,7 +8,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_rhai_on_update_from_rust)
.add_scripting::<RhaiRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})

View file

@ -8,7 +8,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_rhai_on_update_from_rust)
.add_scripting::<RhaiRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})
@ -24,7 +24,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
fn call_rhai_on_update_from_rust(
mut scripted_entities: Query<(Entity, &mut RhaiScriptData)>,
scripting_runtime: ResMut<RhaiRuntime>,
mut exit: MessageWriter<AppExit>,
mut exit: EventWriter<AppExit>,
) {
for (entity, mut script_data) in &mut scripted_entities {
let val = scripting_runtime

View file

@ -33,7 +33,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
),));
}
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: MessageWriter<AppExit>) {
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: EventWriter<AppExit>) {
if !query.is_empty() {
for e in &query {
println!("{}", e);

View file

@ -8,7 +8,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_ruby_on_update_from_rust)
.add_scripting::<RubyRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})

View file

@ -10,7 +10,7 @@ fn main() {
.add_systems(Startup, startup)
.add_systems(Update, call_lua_on_update_from_rust)
.add_scripting::<RubyRuntime>(|runtime| {
runtime.add_function(String::from("quit"), |mut exit: MessageWriter<AppExit>| {
runtime.add_function(String::from("quit"), |mut exit: EventWriter<AppExit>| {
exit.write(AppExit::Success);
});
})
@ -26,7 +26,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
fn call_lua_on_update_from_rust(
mut scripted_entities: Query<(Entity, &mut RubyScriptData)>,
scripting_runtime: ResMut<RubyRuntime>,
mut exit: MessageWriter<AppExit>,
mut exit: EventWriter<AppExit>,
) {
for (entity, mut script_data) in &mut scripted_entities {
let val = scripting_runtime

View file

@ -33,7 +33,7 @@ fn startup(mut commands: Commands, assets_server: Res<AssetServer>) {
),));
}
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: MessageWriter<AppExit>) {
fn print_entity_names_and_quit(query: Query<&Name>, mut exit: EventWriter<AppExit>) {
if !query.is_empty() {
for e in &query {
println!("{}", e);

View file

@ -1,4 +1,4 @@
use bevy::{ecs::system::RunSystemError, prelude::*};
use bevy::prelude::*;
use core::any::TypeId;
use std::sync::{Arc, Mutex};
@ -39,7 +39,7 @@ impl<R: Runtime> CallbackSystem<R> {
&mut self,
call: &FunctionCallEvent<R::CallContext, R::Value>,
world: &mut World,
) -> Result<R::Value, RunSystemError> {
) -> R::Value {
self.system.run(call.params.clone(), world)
}
}
@ -74,9 +74,7 @@ where
let mut inner_system = IntoSystem::into_system(self);
inner_system.initialize(world);
let system_fn = move |_args: In<Vec<R::Value>>, world: &mut World| {
let result = inner_system
.run((), world)
.expect("Callback system failed to run");
let result = inner_system.run((), world);
inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<R>().expect("No runtime resource");
@ -114,7 +112,7 @@ macro_rules! impl_tuple {
)
});
let result = inner_system.run(args, world).expect("Callback system failed to run");
let result = inner_system.run(args, world);
inner_system.apply_deferred(world);
let mut runtime = world.get_resource_mut::<RN>().expect("No runtime resource");

View file

@ -103,7 +103,7 @@
//!
//! ```toml
//! [dependencies]
//! bevy_scriptum = { version = "0.10", features = ["lua"] }
//! bevy_scriptum = { version = "0.9", features = ["lua"] }
//! ```
//!
//! or execute `cargo add bevy_scriptum --features lua` from your project directory.
@ -176,7 +176,6 @@
//!
//! | bevy version | bevy_scriptum version |
//! |--------------|-----------------------|
//! | 0.17 | 0.10 |
//! | 0.16 | 0.8-0.9 |
//! | 0.15 | 0.7 |
//! | 0.14 | 0.6 |
@ -281,12 +280,6 @@ pub enum ScriptingError {
NoSettingsResource,
}
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum ScriptSystemSet {
Reload,
Process,
}
/// Trait that represents a scripting runtime/engine. In practice it is
/// implemented for a scripint language interpreter and the implementor provides
/// function implementations for calling and registering functions within the interpreter.
@ -440,14 +433,6 @@ impl<'a, R: Runtime> ScriptingRuntimeBuilder<'a, R> {
}
}
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
pub enum ScriptSystems {
Reload,
InitCallbacks,
ProcessNewScripts,
ProcessCalls,
}
impl BuildScriptingRuntime for App {
/// Adds a scripting runtime. Registers required bevy systems that take
/// care of processing and running the scripts.
@ -456,14 +441,13 @@ impl BuildScriptingRuntime for App {
if R::needs_rdynamic_linking() && !is_rdynamic_linking() {
panic!(
"Missing `-rdynamic`: symbol resolution failed.\n\
It is needed by {:?}.\n\
Please add `println!(\"cargo:rustc-link-arg=-rdynamic\");` to your build.rs\n\
or set `RUSTFLAGS=\"-C link-arg=-rdynamic\"`.",
It is needed by {:?}.\n\
Please add `println!(\"cargo:rustc-link-arg=-rdynamic\");` to your build.rs\n\
or set `RUSTFLAGS=\"-C link-arg=-rdynamic\"`.",
std::any::type_name::<R>()
);
}
// Insert the runtime schedule after Update
self.world_mut()
.resource_mut::<MainScheduleOrder>()
.insert_after(Update, R::Schedule::default());
@ -473,35 +457,22 @@ impl BuildScriptingRuntime for App {
.init_asset::<R::ScriptAsset>()
.init_resource::<Callbacks<R>>()
.insert_resource(R::default())
.configure_sets(
R::Schedule::default(),
(
ScriptSystems::Reload,
ScriptSystems::InitCallbacks.after(ScriptSystems::Reload),
ScriptSystems::ProcessNewScripts.after(ScriptSystems::InitCallbacks),
ScriptSystems::ProcessCalls.after(ScriptSystems::ProcessNewScripts),
),
)
.add_systems(
R::Schedule::default(),
(
reload_scripts::<R>.in_set(ScriptSystems::Reload),
init_callbacks::<R>
.pipe(log_errors)
.in_set(ScriptSystems::InitCallbacks)
.after(ScriptSystems::Reload),
process_new_scripts::<R>
.pipe(log_errors)
.in_set(ScriptSystems::ProcessNewScripts)
.after(ScriptSystems::InitCallbacks),
reload_scripts::<R>,
process_calls::<R>
.pipe(log_errors)
.in_set(ScriptSystems::ProcessCalls)
.after(ScriptSystems::ProcessNewScripts),
.after(process_new_scripts::<R>),
init_callbacks::<R>.pipe(log_errors),
process_new_scripts::<R>
.pipe(log_errors)
.after(init_callbacks::<R>),
),
);
let runtime = ScriptingRuntimeBuilder::<R>::new(self.world_mut());
f(runtime);
self

View file

@ -171,7 +171,7 @@ fn then(r_self: magnus::Value) -> magnus::Value {
}
.as_value(),
))
.into_value_with(&ruby)
.into_value()
}
#[derive(Clone, Debug)]
@ -448,11 +448,11 @@ impl Runtime for RubyRuntime {
let result = f(
(),
args.iter()
.map(|arg| RubyValue::new(arg.into_value_with(&ruby)))
.map(|arg| RubyValue::new(arg.into_value()))
.collect(),
)
.expect("failed to call callback");
result.into_value_with(&ruby)
result.into_value()
}
self.execute_in_thread(Box::new(move |ruby: &Ruby| {
@ -527,8 +527,8 @@ impl<T: TryConvert> FromRuntimeValueWithEngine<'_, RubyRuntime> for T {
}
impl<T: IntoValue> IntoRuntimeValueWithEngine<'_, T, RubyRuntime> for T {
fn into_runtime_value_with_engine(value: T, engine: &magnus::Ruby) -> RubyValue {
RubyValue::new(value.into_value_with(engine))
fn into_runtime_value_with_engine(value: T, _engine: &magnus::Ruby) -> RubyValue {
RubyValue::new(value.into_value())
}
}
@ -539,9 +539,9 @@ impl FuncArgs<'_, RubyValue, RubyRuntime> for () {
}
impl<T: IntoValue> FuncArgs<'_, RubyValue, RubyRuntime> for Vec<T> {
fn parse(self, engine: &magnus::Ruby) -> Vec<RubyValue> {
fn parse(self, _engine: &magnus::Ruby) -> Vec<RubyValue> {
self.into_iter()
.map(|x| RubyValue::new(x.into_value_with(engine)))
.map(|x| RubyValue::new(x.into_value()))
.collect()
}
}
@ -562,9 +562,9 @@ macro_rules! impl_tuple {
impl<'a, $($t: IntoValue,)+> FuncArgs<'a, RubyValue, RubyRuntime>
for ($($t,)+)
{
fn parse(self, engine: &'a magnus::Ruby) -> Vec<RubyValue> {
fn parse(self, _engine: &'a magnus::Ruby) -> Vec<RubyValue> {
vec![
$(RubyValue::new(self.$idx.into_value_with(engine)), )+
$(RubyValue::new(self.$idx.into_value()), )+
]
}
}

View file

@ -15,7 +15,7 @@ use super::components::Script;
/// Reloads scripts when they are modified.
pub(crate) fn reload_scripts<R: Runtime>(
mut commands: Commands,
mut ev_asset: MessageReader<AssetEvent<R::ScriptAsset>>,
mut ev_asset: EventReader<AssetEvent<R::ScriptAsset>>,
mut scripts: Query<(Entity, &mut Script<R::ScriptAsset>)>,
) {
for ev in ev_asset.read() {
@ -149,9 +149,7 @@ pub(crate) fn process_calls<R: Runtime>(world: &mut World) -> Result<(), Scripti
.system
.lock()
.expect("Failed to lock callback system mutex");
let val = system
.call(&call, world)
.expect("Callback system call failed");
let val = system.call(&call, world);
let mut runtime = world
.get_resource_mut::<R>()
.ok_or(ScriptingError::NoRuntimeResource)?;