.. | ||
examples/hot_reload | ||
src | ||
tests | ||
architecture.md | ||
Cargo.lock | ||
Cargo.toml | ||
project_structure.md | ||
README.md | ||
tera_integration.md |
Rhai System
A thread-safe system for creating and managing Rhai script engines with hot reloading support for multiple script files.
Overview
Rhai System is a Rust module that simplifies working with the Rhai scripting language by providing a system for creating thread-safe Rhai engines with pre-compiled scripts. It supports hot reloading of multiple script files, ensuring your application always uses the latest version of your scripts without requiring a restart.
Features
- Thread Safety: Uses Rhai's
sync
feature to ensure engines areSend + Sync
- Multiple Script Support: Compiles and merges multiple Rhai script files into a single AST
- Hot Reload: Automatically detects changes to script files and recompiles them without requiring application restart
- Cross-Script Function Calls: Functions defined in one script can call functions defined in another script
- Detailed Error Handling: Provides clear error messages when scripts fail to compile
- Performance Optimized: Efficiently recompiles only the scripts that have changed
Usage
Basic Usage
use rhai_system::create_hot_reloadable_system;
use std::path::PathBuf;
// Create a hot reloadable system with multiple script files
let script_paths = vec![
PathBuf::from("scripts/main.rhai"),
PathBuf::from("scripts/utils.rhai"),
];
let system = create_hot_reloadable_system(&script_paths, None).unwrap();
// Call a function from the script
let result: i64 = system.call_fn("add", (40, 2)).unwrap();
assert_eq!(result, 42);
// The system will automatically reload scripts when they change
Watching for Changes
The system automatically sets up file watchers for all script files:
use rhai_system::create_hot_reloadable_system;
use std::path::PathBuf;
use std::thread;
use std::time::Duration;
// Create a hot reloadable system
let script_paths = vec![PathBuf::from("scripts/main.rhai")];
let system = create_hot_reloadable_system(&script_paths, None).unwrap();
// Start watching for changes to the script files
system.watch();
// The system will now automatically reload scripts when they change
// Your application can continue running and using the latest version of the scripts
Thread-Safe Usage
The system is designed to be thread-safe, allowing you to use it from multiple threads:
use rhai_system::create_hot_reloadable_system;
use std::path::PathBuf;
use std::thread;
use std::sync::Arc;
// Create a hot reloadable system
let script_paths = vec![PathBuf::from("scripts/main.rhai")];
let system = Arc::new(create_hot_reloadable_system(&script_paths, None).unwrap());
// Clone the system for use in another thread
let system_clone = Arc::clone(&system);
// Start watching for changes in the main thread
system.watch();
// Use the system in another thread
let handle = thread::spawn(move || {
// Create a thread-local clone of the system
let thread_system = system_clone.clone_for_thread();
// Call functions from the script
let result: i64 = thread_system.call_fn("add", (40, 2)).unwrap();
assert_eq!(result, 42);
});
handle.join().unwrap();
Module Resolution
Rhai System supports the BasePathModuleResolver approach for resolving module imports:
- Uses a single base path for resolving all module imports
- Makes the resolution process more predictable and consistent
- Simplifies the Rhai module import system by removing the complexity of relative path resolution
See the examples/base_path_imports
directory for a comprehensive example of this approach.
Error Handling
The system provides detailed error information when scripts fail to compile:
use rhai_system::create_hot_reloadable_system;
use std::path::PathBuf;
let script_paths = vec![PathBuf::from("non_existent.rhai")];
let result = create_hot_reloadable_system(&script_paths, None);
match result {
Err(err) => {
// Error will contain:
// - Which script failed to compile
// - The reason for the failure
println!("Error: {}", err);
}
Ok(_) => panic!("Expected an error"),
}
Testing
The project follows Rust's standard testing approach:
# Run all tests
cargo test
# Run a specific test
cargo test test_hot_reload_callback
Installation
Add this to your Cargo.toml
:
[dependencies]
rhai_system = { path = "path/to/rhai_system" }
Examples
See the examples
directory for complete examples:
hot_reload
: Demonstrates hot reloading of multiple script filesbase_path_imports
: Demonstrates the BasePathModuleResolver approach for module imports