Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Complete Rewrite #183

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bbfda42
feat: complete plugin re-write
makspll Jan 5, 2025
b9ca7ae
chore: release v0.9.0-alpha.2 (#189)
github-actions[bot] Jan 5, 2025
eff1cc3
chore: replace wildcard import for uuid with fixed version
makspll Jan 5, 2025
e6f817c
chore: add lua publish feature to bevy_mod_scripting package
makspll Jan 5, 2025
fc03230
feat: make script contexts public (#193)
makspll Jan 8, 2025
7595742
feat: Improvements to BMS in multi-language context (#194)
makspll Jan 13, 2025
a61e9c6
chore: use matrix job generation from xtask in CI/CD (#198)
makspll Jan 13, 2025
5462a6e
chore: Improve CI/CD further (#199)
makspll Jan 13, 2025
f77f246
chore: fix release plz config
makspll Jan 13, 2025
099cdb3
chore: disable default features for cargo commands in xtask, move uns…
makspll Jan 13, 2025
d9bfc37
chore: don't add profile arg for fmt commands in xtask
makspll Jan 13, 2025
7921e19
chore: Fix bindings stability, order things more (#200)
makspll Jan 13, 2025
c1b6375
feat: Implement global namespace registration (#202)
makspll Jan 13, 2025
c109fb6
chore: release v0.9.0-alpha.3 (#203)
github-actions[bot] Jan 14, 2025
bc83c5a
fix: remove test time dependencies from functions (#204)
makspll Jan 14, 2025
39cf747
chore: Improve docs (#205)
makspll Jan 14, 2025
614431f
chore: fix edit url in mdbook (#207)
makspll Jan 14, 2025
7aedd1a
chore: Improve test coverage (#208)
makspll Jan 17, 2025
67b253d
chore: release v0.9.0-alpha.4 (#206)
github-actions[bot] Jan 17, 2025
b874050
fix: Fix missing functions in codegen (#210)
makspll Jan 19, 2025
ecf613d
chore: release v0.9.0-alpha.5 (#215)
github-actions[bot] Jan 19, 2025
eb1f46f
feat: Don't panic! (#216)
makspll Jan 19, 2025
6c92a68
chore: release v0.9.0-alpha.6 (#217)
github-actions[bot] Jan 19, 2025
9b9dd57
feat: Add component `upsert` function (#218)
makspll Jan 20, 2025
c9a6ffa
docs: Update docs for refactor (#221)
makspll Jan 20, 2025
f71561f
feat!: Remove `WorldCallbackAccess` & Combine context args for dynami…
makspll Jan 20, 2025
c71fa0a
chore: release v0.9.0-alpha.7 (#220)
github-actions[bot] Jan 20, 2025
b2c39d0
feat: Add world.with_or_insert_component_mut() (#223)
shanecelis Jan 22, 2025
361ca78
feat: re-implement rhai again (#222)
makspll Jan 24, 2025
dbfef74
feat: Add `optional` arguments to script functions (#225)
makspll Jan 25, 2025
db8a7c3
feat: Call custom `get` and `set` functions on the type when indexing…
makspll Jan 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: Improvements to BMS in multi-language context (#194)
* fix: bugs to do with multiple languages being initialized

* rhai re-implementation WIP

* feat: switch vscode to xtask

* re-write lua tests to use common integration test framework

* setup rhai tests

* add assertions

* start writing marshalling code for rhai

* move world pointers to thread locals

* move namespace stuff into core

* chore(codegen): update bevy bindings (#195)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* refactor function interface, reduce amount of string cloning, happy cows

* remove extra import, fix lua to_string

* clean up comments

* remove rhai and rune support for now

* correct for changed features in xtasks

* Add note in readme about removal of features

* start adding documentation for new languages

* format

* fix failing test utils test

* generate matrix from xtask

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
makspll and github-actions[bot] authored Jan 13, 2025
commit 7595742d931fa23a6b95708adaad5ff9c84fda8a
1 change: 0 additions & 1 deletion .github/workflows/bevy_mod_scripting.yml
Original file line number Diff line number Diff line change
@@ -32,7 +32,6 @@ jobs:
{label: Windows, os: windows-latest },
{label: MacOS, os: macOS-latest },
{label: Ubuntu, os: ubuntu-latest },
{label: Ubuntu Aarch64, os: ubuntu-latest }
]
steps:
- name: Checkout
8 changes: 5 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -10,11 +10,10 @@
},
"rust-analyzer.rustc.source": "discover",
"rust-analyzer.linkedProjects": [
"./crates/bevy_api_gen/Cargo.toml",
// "./crates/bevy_api_gen/Cargo.toml",
"Cargo.toml",
],
"rust-analyzer.check.invocationStrategy": "per_workspace",
"rust-analyzer.check.invocationLocation": "workspace",
"rust-analyzer.check.invocationStrategy": "once",
"rust-analyzer.check.overrideCommand": [
"/home/makspll/git/bevy_mod_scripting/check.sh"
],
@@ -28,5 +27,8 @@
"rust-analyzer.runnables.extraArgs": [
"--profile=release-with-debug",
],
// "rust-analyzer.cargo.features": [
// "bevy_mod_scripting_functions/test_functions"
// ]
// "rust-analyzer.semanticHighlighting.operator.enable": false
}
3 changes: 1 addition & 2 deletions CONTRIBUTING.MD
Original file line number Diff line number Diff line change
@@ -135,8 +135,7 @@ Enhancement suggestions are tracked as [GitHub issues](https://github.com/makspl

### Your First Code Contribution

This project uses xtask to manage the build and test process. You can run `cargo xtask` to see the available commands. Run `xtask init` to setup your local development environment.

Before contributing see the [book](https://makspll.github.io/bevy_mod_scripting) for helpful guides on how to get started with the project.


### Improving The Documentation
35 changes: 17 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ name = "bevy_mod_scripting"
path = "src/lib.rs"

[package.metadata."docs.rs"]
features = ["lua54", "rhai", "rune"]
features = ["lua54"]

[features]
default = ["core_functions", "bevy_bindings", "unsafe_lua_modules"]
@@ -44,44 +44,48 @@ mlua_macros = ["bevy_mod_scripting_lua/mlua_macros"]
mlua_async = ["bevy_mod_scripting_lua/mlua_async"]

## rhai
rhai = ["bevy_mod_scripting_rhai"]
# rhai = ["bevy_mod_scripting_rhai"]

## rune
rune = ["bevy_mod_scripting_rune"]
# rune = ["bevy_mod_scripting_rune"]

[dependencies]
bevy = { workspace = true }
bevy_mod_scripting_core = { workspace = true }
bevy_mod_scripting_lua = { path = "crates/languages/bevy_mod_scripting_lua", version = "0.9.0-alpha.2", optional = true }
bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.9.0-alpha.2", optional = true }
bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.9.0-alpha.2", optional = true }
# bevy_mod_scripting_rhai = { path = "crates/languages/bevy_mod_scripting_rhai", version = "0.9.0-alpha.2", optional = true }
# bevy_mod_scripting_rune = { path = "crates/languages/bevy_mod_scripting_rune", version = "0.9.0-alpha.2", optional = true }
bevy_mod_scripting_functions = { workspace = true }

[workspace.dependencies]
bevy = { version = "0.15.0", default-features = false }
bevy_mod_scripting_core = { path = "crates/bevy_mod_scripting_core", version = "0.9.0-alpha.2" }
bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.2" }
test_utils = { path = "crates/test_utils" }
bevy_mod_scripting_functions = { path = "crates/bevy_mod_scripting_functions", version = "0.9.0-alpha.2", default-features = false }
mlua = { version = "0.10" }
rhai = { version = "1.20.1" }
# rhai = { version = "1.20.1" }

# test utilities
script_integration_test_harness = { path = "crates/script_integration_test_harness" }
test_utils = { path = "crates/test_utils" }

[dev-dependencies]
bevy = { workspace = true, default-features = true }
clap = { version = "4.1", features = ["derive"] }
rand = "0.8.5"
bevy_console = "0.13"
rhai-rand = "0.1"
# rhai-rand = "0.1"
ansi-parser = "0.9"

[workspace]
members = [
"crates/bevy_mod_scripting_core",
"crates/languages/bevy_mod_scripting_lua",
"crates/languages/bevy_mod_scripting_rhai",
"crates/languages/bevy_mod_scripting_rune",
# "crates/languages/bevy_mod_scripting_rhai",
# "crates/languages/bevy_mod_scripting_rune",
"crates/test_utils",
"crates/bevy_mod_scripting_functions",
"crates/xtask",
"crates/script_integration_test_harness",
]
resolver = "2"
exclude = ["crates/bevy_api_gen", "crates/macro_tests"]
@@ -106,11 +110,6 @@ inherits = "release"
debug = true

[[example]]
name = "game_of_life_lua"
path = "examples/lua/game_of_life.rs"
name = "game_of_life"
path = "examples/game_of_life.rs"
required-features = ["lua54", "bevy/file_watcher", "bevy/multi_threaded"]

# [[example]]
# required-features = ["rhai", "bevy/file_watcher", "bevy/multi_threaded"]
# name = "game_of_life_rhai"
# path = "examples/rhai/game_of_life.rs"
1 change: 1 addition & 0 deletions assets/scripts/game_of_life.lua
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ end
function on_click(x,y)
-- get the settings
world.info("Lua: Clicked at x: " .. x .. " y: " .. y)
print(entity)
local life_state = fetch_life_state()
local cells = life_state.cells

19 changes: 10 additions & 9 deletions assets/scripts/game_of_life.rhai
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
fn init() {
let LifeState = world.get_type_by_name("LifeState");
let life_state = world.get_component(entity,LifeState);
let cells = life_state.cells;
fn on_script_loaded() {
world.info("Game of Life script loaded");
// let LifeState = world.get_type_by_name("LifeState");
// let life_state = world.get_component(entity,LifeState);
// let cells = life_state.cells;

// set some cells alive
for x in 1..10000 {
let index = rand(0..cells.len());
cells[index] = 255;
}
// // set some cells alive
// for x in 1..10000 {
// let index = rand(0..cells.len());
// cells[index] = 255;
// }
}

fn on_update() {
11 changes: 2 additions & 9 deletions check.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
#!/bin/bash
unset RUSTUP_TOOLCHAIN
CURRENT_DIR=$(basename "$PWD")


if [[ "$CURRENT_DIR" == "bevy_api_gen" ]]; then
cargo +nightly-2024-11-05 clippy --all-targets --message-format=json
else
cargo clippy --workspace --all-targets --message-format=json --features="lua54 rhai rune bevy/file_watcher bevy/multi_threaded"
fi
cd "$(dirname "$0")"
cargo xtask check --ide-mode
2 changes: 1 addition & 1 deletion crates/bevy_api_gen/templates/header.tera
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ use bevy_mod_scripting_core::{
StoreDocumentation,
bindings::{
ReflectReference,
function::from::{Ref, Mut, Val}
function::{from::{Ref, Mut, Val}, namespace::{NamespaceBuilder}}
}
};
{% if args.self_is_bms_lua %}
4 changes: 2 additions & 2 deletions crates/bevy_mod_scripting_core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -21,11 +21,11 @@ doc_always = []

# if enabled enables some common mlua trait implementations
mlua_impls = ["mlua"]
rhai_impls = ["rhai"]
# rhai_impls = ["rhai"]

[dependencies]
mlua = { optional = true, workspace = true }
rhai = { optional = true, workspace = true }
# rhai = { optional = true, workspace = true }

bevy = { workspace = true, default-features = false, features = [
"bevy_asset",
72 changes: 60 additions & 12 deletions crates/bevy_mod_scripting_core/src/asset.rs
Original file line number Diff line number Diff line change
@@ -10,18 +10,39 @@ use std::{
path::{Path, PathBuf},
};

/// Represents a scripting language. Languages which compile into another language should use the target language as their language.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Language {
Rhai,
Lua,
Rune,
External(Cow<'static, str>),
/// Set if none of the asset path to language mappers match
Unknown,
}

impl std::fmt::Display for Language {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Language::Rhai => "Rhai".fmt(f),
Language::Lua => "Lua".fmt(f),
Language::Rune => "Rune".fmt(f),
Language::External(cow) => cow.fmt(f),
Language::Unknown => "Unknown".fmt(f),
}
}
}

/// Represents a script loaded into memory as an asset
#[derive(Asset, TypePath, Clone)]
pub struct ScriptAsset {
pub content: Box<[u8]>,
/// The virtual filesystem path of the asset, used to map to the script Id for asset backed scripts
pub asset_path: PathBuf,
pub language: Cow<'static, str>,
}

#[derive(Default)]
pub struct ScriptAssetLoader {
/// Used to set the language of the script
pub language: Cow<'static, str>,
/// The file extensions this loader should handle
pub extensions: &'static [&'static str],
/// preprocessor to run on the script before saving the content to an asset
@@ -52,7 +73,6 @@ impl AssetLoader for ScriptAssetLoader {
let asset = ScriptAsset {
content: content.into_boxed_slice(),
asset_path: load_context.path().to_owned(),
language: self.language.clone(),
};
Ok(asset)
}
@@ -62,9 +82,24 @@ impl AssetLoader for ScriptAssetLoader {
}
}

#[derive(Clone, Copy, Resource)]
#[derive(Clone, Resource)]
pub struct ScriptAssetSettings {
pub script_id_mapper: AssetPathToScriptIdMapper,
pub script_language_mappers: Vec<AssetPathToLanguageMapper>,
}

impl ScriptAssetSettings {
pub fn select_script_language(&self, path: &Path) -> Language {
for mapper in &self.script_language_mappers {
let language = (mapper.map)(path);
match language {
Language::Unknown => continue,
_ => return language,
}
}

Language::Unknown
}
}

impl Default for ScriptAssetSettings {
@@ -73,6 +108,7 @@ impl Default for ScriptAssetSettings {
script_id_mapper: AssetPathToScriptIdMapper {
map: (|path: &Path| path.to_string_lossy().into_owned().into()),
},
script_language_mappers: vec![],
}
}
}
@@ -83,22 +119,34 @@ pub struct AssetPathToScriptIdMapper {
pub map: fn(&Path) -> ScriptId,
}

#[derive(Clone, Copy)]
pub struct AssetPathToLanguageMapper {
pub map: fn(&Path) -> Language,
}

/// A cache of asset id's to their script id's. Necessary since when we drop an asset we won't have the ability to get the path from the asset.
#[derive(Default, Debug, Resource)]
pub struct AssetIdToScriptIdMap {
pub map: HashMap<AssetId<ScriptAsset>, ScriptId>,
pub struct ScriptMetadataStore {
pub map: HashMap<AssetId<ScriptAsset>, ScriptMetadata>,
}

#[derive(Debug, Clone)]
pub struct ScriptMetadata {
pub script_id: ScriptId,
pub language: Language,
}

impl AssetIdToScriptIdMap {
pub fn insert(&mut self, id: AssetId<ScriptAsset>, path: ScriptId) {
self.map.insert(id, path);
impl ScriptMetadataStore {
pub fn insert(&mut self, id: AssetId<ScriptAsset>, meta: ScriptMetadata) {
// TODO: new generations of assets are not going to have the same ID as the old one
self.map.insert(id, meta);
}

pub fn get(&self, id: AssetId<ScriptAsset>) -> Option<&ScriptId> {
pub fn get(&self, id: AssetId<ScriptAsset>) -> Option<&ScriptMetadata> {
self.map.get(&id)
}

pub fn remove(&mut self, id: AssetId<ScriptAsset>) -> Option<ScriptId> {
pub fn remove(&mut self, id: AssetId<ScriptAsset>) -> Option<ScriptMetadata> {
self.map.remove(&id)
}
}
1 change: 0 additions & 1 deletion crates/bevy_mod_scripting_core/src/bindings/allocator.rs
Original file line number Diff line number Diff line change
@@ -195,7 +195,6 @@ impl ReflectAllocator {
/// Runs a garbage collection pass on the allocations, removing any allocations which have no more strong references
/// Needs to be run periodically to prevent memory leaks
pub fn clean_garbage_allocations(&mut self) {
bevy::log::trace!("Cleaning garbage allocations");
self.allocations.retain(|k, _| Arc::strong_count(&k.0) > 1);
}

36 changes: 36 additions & 0 deletions crates/bevy_mod_scripting_core/src/bindings/function/from.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@ use std::{
path::PathBuf,
};

use super::script_function::{DynamicScriptFunction, DynamicScriptFunctionMut};

/// Describes the procedure for constructing a value of type `T` from a [`ScriptValue`].
///
/// The [`FromScript::This`] associated type is used to allow for the implementation of this trait to return
@@ -387,3 +389,37 @@ where
}
}
}

impl FromScript for DynamicScriptFunctionMut {
type This<'w> = Self;

fn from_script(value: ScriptValue, _: WorldGuard<'_>) -> Result<Self::This<'_>, InteropError>
where
Self: Sized,
{
match value {
ScriptValue::FunctionMut(f) => Ok(f),
_ => Err(InteropError::value_mismatch(
std::any::TypeId::of::<Self>(),
value,
)),
}
}
}

impl FromScript for DynamicScriptFunction {
type This<'w> = Self;

fn from_script(value: ScriptValue, _: WorldGuard<'_>) -> Result<Self::This<'_>, InteropError>
where
Self: Sized,
{
match value {
ScriptValue::Function(f) => Ok(f),
_ => Err(InteropError::value_mismatch(
std::any::TypeId::of::<Self>(),
value,
)),
}
}
}
6 changes: 6 additions & 0 deletions crates/bevy_mod_scripting_core/src/bindings/function/into.rs
Original file line number Diff line number Diff line change
@@ -33,6 +33,12 @@ impl IntoScript for () {
self_type_dependency_only!(());

impl IntoScript for DynamicScriptFunctionMut {
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
Ok(ScriptValue::FunctionMut(self))
}
}

impl IntoScript for DynamicScriptFunction {
fn into_script(self, _world: WorldGuard) -> Result<ScriptValue, InteropError> {
Ok(ScriptValue::Function(self))
}
Loading