This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_system
2025-05-02 21:05:30 +02:00
..
examples/hot_reload remove old examples 2025-05-02 21:05:30 +02:00
src refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
tests refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
architecture.md refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
Cargo.lock refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
Cargo.toml refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
project_structure.md refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
README.md refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00
tera_integration.md refactor: Overhaul Rhai scripting with multi-file hot reloading 2025-05-02 21:04:33 +02:00

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 are Send + 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 files
  • base_path_imports: Demonstrates the BasePathModuleResolver approach for module imports