Skip to content

Commit 6100d4f

Browse files
committed
Convert borrow_data and borrow_data_mut to a macro
1 parent f191856 commit 6100d4f

File tree

2 files changed

+66
-53
lines changed

2 files changed

+66
-53
lines changed

src/logic/vm/buildings.rs

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use widestring::U16String;
55

66
use super::{
77
LogicVMBuilder, VMLoadError, VMLoadResult,
8-
processor::{Processor, ProcessorBuilder, ProcessorState},
8+
processor::{Processor, ProcessorBuilder},
99
variables::LValue,
1010
};
1111
use crate::types::{
@@ -178,39 +178,6 @@ impl Building {
178178
) -> VMLoadResult<Self> {
179179
Self::from_config(name, (*position).into(), config, builder)
180180
}
181-
182-
pub fn borrow_data<T, U, R>(&self, state: &ProcessorState, f_processor: T, f_other: U) -> R
183-
where
184-
T: FnOnce(&ProcessorState) -> R,
185-
U: FnOnce(&BuildingData) -> R,
186-
{
187-
match self.data.try_borrow() {
188-
Ok(data) => match &*data {
189-
BuildingData::Processor(p) => f_processor(&p.state),
190-
other => f_other(other),
191-
},
192-
Err(_) => f_processor(state),
193-
}
194-
}
195-
196-
pub fn borrow_data_mut<T, U, R>(
197-
&self,
198-
state: &mut ProcessorState,
199-
f_processor: T,
200-
f_other: U,
201-
) -> R
202-
where
203-
T: FnOnce(&mut ProcessorState) -> R,
204-
U: FnOnce(&mut BuildingData) -> R,
205-
{
206-
match self.data.try_borrow_mut() {
207-
Ok(mut data) => match &mut *data {
208-
BuildingData::Processor(p) => f_processor(&mut p.state),
209-
other => f_other(other),
210-
},
211-
Err(_) => f_processor(state),
212-
}
213-
}
214181
}
215182

216183
impl PartialEq for Building {
@@ -219,6 +186,52 @@ impl PartialEq for Building {
219186
}
220187
}
221188

189+
macro_rules! borrow_data {
190+
(
191+
mut $ref:expr,
192+
$state:ident => $expr1:expr,
193+
$data:ident => $expr2:expr $(,)?
194+
) => {
195+
borrow_data!(
196+
@impl
197+
mut, $ref.try_borrow_mut(),
198+
$state => $expr1,
199+
$data => $expr2
200+
)
201+
};
202+
(
203+
$ref:expr,
204+
$state:ident => $expr1:expr,
205+
$data:ident => $expr2:expr $(,)?
206+
) => {
207+
borrow_data!(
208+
@impl
209+
$ref.try_borrow(),
210+
$state => $expr1,
211+
$data => $expr2
212+
)
213+
};
214+
(
215+
@impl
216+
$($mut:ident,)? $ref:expr,
217+
$state:ident => $expr1:expr,
218+
$data:ident => $expr2:expr
219+
) => {
220+
match $ref {
221+
Ok($($mut)? data) => match &$($mut)? *data {
222+
BuildingData::Processor(p) => {
223+
let $state = &$($mut)? p.state;
224+
$expr1
225+
},
226+
$data => $expr2,
227+
},
228+
Err(_) => $expr1,
229+
}
230+
};
231+
}
232+
233+
pub(super) use borrow_data;
234+
222235
#[derive(Debug, IntoStaticStr)]
223236
pub enum BuildingData {
224237
Processor(Box<Processor>),

src/logic/vm/instructions.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use noise::{NoiseFn, Simplex};
66
use widestring::{U16Str, u16str};
77

88
use super::{
9-
Constants, LogicVM, VMLoadError, VMLoadResult,
9+
Constants, LogicVM, VMLoadError, VMLoadResult, borrow_data,
1010
buildings::BuildingData,
1111
processor::{MAX_TEXT_BUFFER, ProcessorState},
1212
variables::{Content, LValue, LVar, RAD_DEG},
@@ -376,9 +376,9 @@ impl SimpleInstructionTrait for Read {
376376
let address = self.address.get(state);
377377

378378
let result = match self.target.get(state) {
379-
LValue::Building(building) => building.borrow_data(
380-
state,
381-
|state| match address.clone() {
379+
LValue::Building(building) => borrow_data!(
380+
building.data,
381+
state => match address {
382382
// read variable with name, returning null for constants and undefined
383383
LValue::String(name) => {
384384
if *name == u16str!("@counter") {
@@ -391,7 +391,7 @@ impl SimpleInstructionTrait for Read {
391391
// no-op if the address is not a string
392392
_ => None,
393393
},
394-
|data| match data {
394+
data => match data {
395395
// read value at index
396396
BuildingData::Memory(memory) => {
397397
// coerce the address to a number, and return null if the address is not in range
@@ -433,19 +433,19 @@ impl SimpleInstructionTrait for Write {
433433
let address = self.address.get(state);
434434
let value = self.value.get(state);
435435

436-
building.borrow_data_mut(
437-
state,
438-
|state| match address.clone() {
436+
borrow_data!(
437+
mut building.data,
438+
state => match address {
439439
LValue::String(name) if *name == u16str!("@counter") => {
440-
state.try_set_counter(value.clone());
440+
state.try_set_counter(value);
441441
state.set_stopped(false);
442442
}
443443
LValue::String(name) if state.variables.contains_key(&*name) => {
444-
state.variables[&*name] = value.clone();
444+
state.variables[&*name] = value;
445445
}
446446
_ => {}
447447
},
448-
|data| {
448+
data => {
449449
if let BuildingData::Memory(memory) = data
450450
&& let Ok(address) = address.num_usize()
451451
&& address < memory.len()
@@ -608,10 +608,10 @@ impl SimpleInstructionTrait for Control {
608608
let enabled = self.p1.get(state);
609609
if !enabled.isobj() {
610610
let enabled = enabled.numf() != 0.;
611-
building.borrow_data_mut(
612-
state,
613-
|state| state.set_enabled(enabled),
614-
|data| {
611+
borrow_data!(
612+
mut building.data,
613+
state => state.set_enabled(enabled),
614+
data => {
615615
if let BuildingData::Switch(value) = data {
616616
*value = enabled;
617617
}
@@ -706,13 +706,13 @@ impl SimpleInstructionTrait for Sensor {
706706
FirstItem => LValue::Null,
707707
PayloadType => LValue::Null,
708708

709-
_ => building.borrow_data(
710-
state,
711-
|state| match sensor {
709+
_ => borrow_data!(
710+
building.data,
711+
state => match sensor {
712712
LAccess::Enabled => state.enabled().into(),
713713
_ => LValue::Null,
714714
},
715-
|data| match data {
715+
data => match data {
716716
BuildingData::Memory(memory) => match sensor {
717717
MemoryCapacity => memory.len().into(),
718718
Enabled => true.into(),

0 commit comments

Comments
 (0)