Import Oxide engine (Stages 0–10) under MIT license
Full project snapshot migrated to new Gitea remote without history: engine, editor, physics, script, examples, tests, docs, and assets. Relicensed from GPLv3 to MIT and updated repo URLs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
//! The [`ScriptModule`] — the Stage-10 entry point that wires scripting into an
|
||||
//! [`App`].
|
||||
//!
|
||||
//! Following the engine's module convention, everything the scripting layer
|
||||
//! contributes is registered here so it can be enabled, disabled, or removed as
|
||||
//! a unit (and so an exported game that uses no scripts never compiles them in).
|
||||
//! This first piece registers the [`Script`] component *type* for reflection
|
||||
//! (making it dual-editable and captured by the play-mode snapshot), installs
|
||||
//! the `.rhai` [`ScriptLoader`], and inserts the shared [`ScriptEngine`]. The
|
||||
//! lifecycle system that compiles and runs scripts each frame is added in a
|
||||
//! later piece.
|
||||
|
||||
use oxide_engine::app::{App, Module, Schedule};
|
||||
|
||||
use crate::host::run_scripts;
|
||||
use crate::{Script, ScriptHost, ScriptLoader};
|
||||
|
||||
/// The scripting module. Add it after [`DefaultModules`] to give an app a
|
||||
/// `rhai`-backed scripting layer.
|
||||
///
|
||||
/// [`DefaultModules`]: oxide_engine::app::DefaultModules
|
||||
///
|
||||
/// ```
|
||||
/// use oxide_engine::app::App;
|
||||
/// use oxide_script::ScriptModule;
|
||||
///
|
||||
/// let mut app = App::new();
|
||||
/// app.add_module(ScriptModule);
|
||||
/// assert!(app.has_module("script"));
|
||||
/// assert!(app.types.is_registered("Script"));
|
||||
/// ```
|
||||
pub struct ScriptModule;
|
||||
|
||||
impl Module for ScriptModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"script"
|
||||
}
|
||||
|
||||
fn build(&self, app: &mut App) {
|
||||
// Register the component type for reflection so it round-trips through
|
||||
// RON (scripts/AI/inspector) and is captured by the play-mode snapshot.
|
||||
app.register_type::<Script>("Script");
|
||||
|
||||
// Teach the asset server to load `.rhai` files as `ScriptAsset`s.
|
||||
app.add_loader(ScriptLoader);
|
||||
|
||||
// The runtime that compiles and runs each entity's script, driven on
|
||||
// `Update` (after `FixedUpdate`, so scripts observe post-physics poses).
|
||||
app.insert_resource(ScriptHost::new());
|
||||
app.add_system(Schedule::Update, run_scripts);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use oxide_engine::app::DefaultModules;
|
||||
|
||||
#[test]
|
||||
fn module_registers_its_type_loader_and_host() {
|
||||
let mut app = App::new();
|
||||
app.add_modules(DefaultModules);
|
||||
app.add_module(ScriptModule);
|
||||
|
||||
assert!(app.has_module("script"));
|
||||
assert!(app.types.is_registered("Script"));
|
||||
assert!(app.has_resource::<ScriptHost>());
|
||||
// The per-frame run_scripts system was registered.
|
||||
assert!(app.system_count() >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn removing_the_module_drops_its_type() {
|
||||
let mut app = App::new();
|
||||
app.add_module(ScriptModule);
|
||||
assert!(app.types.is_registered("Script"));
|
||||
|
||||
assert!(app.remove_module("script"));
|
||||
assert!(!app.has_module("script"));
|
||||
assert!(!app.types.is_registered("Script"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user