more refactor

This commit is contained in:
2026-06-05 01:09:50 -05:00
parent 6cd34ebb4e
commit 8f2cca2907
5 changed files with 35 additions and 36 deletions
+19 -20
View File
@@ -9,9 +9,9 @@
//!
//! ## Reads vs. writes
//!
//! Scripts **read** the world directly through a read-only [`BoardView`] (getters
//! only) pushed into each scope as `board`, e.g. `board.player_x`. The view holds
//! an `Rc<RefCell<Board>>` and borrows it briefly per getter.
//! Scripts **read** the world directly through a read-only `Rc<RefCell<Board>>` (type aliased
//! as [`BoardRef`], registering getters only) pushed into each scope as `Board`, e.g.
//! `Board.player_x`. Functions borrow it briefly per getter.
//!
//! Scripts **write** by enqueuing [`Command`]s: host functions (`move`,
//! `set_tile`, `log`) push into a shared queue that [`GameState`] drains and
@@ -19,7 +19,7 @@
//! execution from ever needing a mutable borrow of the game state, and makes
//! structural/ordering effects deterministic. Which object issued a command is
//! read from the per-call **tag** (set to the object index in [`ScriptHost::run`]),
//! so scripts write `move(north)` without naming themselves.
//! so scripts write `move(North)` without naming themselves.
//!
//! [`GameState`]: crate::game::GameState
@@ -80,11 +80,10 @@ impl From<Direction> for (i32, i32) {
}
}
/// A read-only handle to the world, exposed to scripts as `board`. Holds a shared
/// A read-only handle to the world, exposed to scripts as `Board`. Holds a shared
/// reference to the [`Board`]; only getters are registered, so it is
/// read-only by construction.
#[derive(Clone)]
struct BoardView(Rc<RefCell<Board>>);
type BoardRef = Rc<RefCell<Board>>;
/// A compiled script plus which lifecycle hooks it defines.
struct CompiledScript {
@@ -128,7 +127,7 @@ impl ScriptHost {
/// fresh scope per scripted object. Compile errors and references to unknown
/// scripts are queued as [`GameCommand::Error`] (retrievable via
/// [`Self::take_commands`]); no script is run here.
pub fn new(board_cell: &Rc<RefCell<Board>>) -> Self {
pub fn new(board_cell: &BoardRef) -> Self {
let commands: CommandQueue = Rc::new(RefCell::new(Vec::new()));
let mut engine = Engine::new();
@@ -275,14 +274,14 @@ impl ScriptHost {
}
}
/// Registers the read-only `board` API: a [`BoardView`] type with getters that
/// Registers the read-only `Board` API: a [`BoardRef`] type with getters that
/// borrow the shared state briefly.
fn register_read_api(engine: &mut Engine) {
engine.register_type_with_name::<BoardView>("BoardView");
engine.register_get("player_x", |b: &mut BoardView| b.0.borrow().player.x as i64);
engine.register_get("player_y", |b: &mut BoardView| b.0.borrow().player.y as i64);
engine.register_get("width", |b: &mut BoardView| b.0.borrow().width as i64);
engine.register_get("height", |b: &mut BoardView| b.0.borrow().height as i64);
engine.register_type_with_name::<BoardRef>("Board");
engine.register_get("player_x", |b: &mut BoardRef| b.borrow().player.x as i64);
engine.register_get("player_y", |b: &mut BoardRef| b.borrow().player.y as i64);
engine.register_get("width", |b: &mut BoardRef| b.borrow().width as i64);
engine.register_get("height", |b: &mut BoardRef| b.borrow().height as i64);
}
/// Registers the write API: the `Direction` type and the `move`/`set_tile`/`log`
@@ -328,12 +327,12 @@ fn source_of(ctx: &NativeCallContext) -> usize {
/// Builds a fresh per-object scope, seeded with the read-only `board` view and
/// the four direction constants (`north`/`south`/`east`/`west`).
fn new_object_scope(board: &Rc<RefCell<Board>>) -> Scope<'static> {
fn new_object_scope(board: &BoardRef) -> Scope<'static> {
let mut scope = Scope::new();
scope.push_constant("board", BoardView(board.clone()));
scope.push_constant("north", Direction::North);
scope.push_constant("south", Direction::South);
scope.push_constant("east", Direction::East);
scope.push_constant("west", Direction::West);
scope.push_constant("Board", board.clone());
scope.push_constant("North", Direction::North);
scope.push_constant("South", Direction::South);
scope.push_constant("East", Direction::East);
scope.push_constant("West", Direction::West);
scope
}