more refactor
This commit is contained in:
@@ -663,7 +663,7 @@ mod tests {
|
||||
3,
|
||||
(3, 1),
|
||||
vec![scripted_object(2, 1, "r")],
|
||||
&[("r", "fn init() { log(board.player_x.to_string()); }")],
|
||||
&[("r", "fn init() { log(Board.player_x.to_string()); }")],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
@@ -678,7 +678,7 @@ mod tests {
|
||||
3,
|
||||
(0, 0),
|
||||
vec![scripted_object(2, 1, "m")],
|
||||
&[("m", "fn init() { move(east); }")],
|
||||
&[("m", "fn init() { move(East); }")],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
@@ -695,7 +695,7 @@ mod tests {
|
||||
3,
|
||||
(0, 0),
|
||||
vec![scripted_object(0, 1, "m")],
|
||||
&[("m", "fn init() { move(west); }")],
|
||||
&[("m", "fn init() { move(West); }")],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
@@ -748,8 +748,8 @@ mod tests {
|
||||
(0, 0),
|
||||
vec![scripted_object(0, 1, "e"), scripted_object(4, 1, "w")],
|
||||
&[
|
||||
("e", "fn init() { move(east); }"),
|
||||
("w", "fn init() { move(west); }"),
|
||||
("e", "fn init() { move(East); }"),
|
||||
("w", "fn init() { move(West); }"),
|
||||
],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
|
||||
+19
-20
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user