I simplified the ItemHandler
abstraction to require less functions to be implemented.
The previous version looked like this:
pub trait ItemHandler {
fn accepts(
&self,
module_store: &dyn ModuleStore,
pos_self: &PosRelative,
pos_other: &PosRelative,
x: &Item,
) -> bool;
fn accept(
&mut self,
module_store: &dyn ModuleStore,
pos_self: &PosRelative,
pos_other: &PosRelative,
x: Item,
);
...
fn takes(&self, x: &Item) -> bool;
fn take(&mut self, x: Item);
}
For accepting and taking Item
s, two functions had to be implemented.
Also callers were required to call accepts
or takes
beforehand to ensure accept
and take
would succeed.
The new version now only requires one function for each flow direction:
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AcceptReject {
Accept,
Reject(Item),
}
...
pub trait ItemHandler {
fn try_accept(
&mut self,
module_store: &dyn ModuleStore,
pos_self: &PosRelative,
pos_other: &PosRelative,
x: Item,
) -> AcceptReject;
fn try_take(&mut self, x: Item) -> AcceptReject;
}
For the Belt
the implementation then looks like this:
impl ItemHandler for Belt {
fn try_accept(
&mut self,
_module_store: &dyn ModuleStore,
_pos_self: &PosRelative,
_pos_other: &PosRelative,
item: Item,
) -> AcceptReject {
if self.input.is_none() {
self.input = Some(item);
self.set_cooldown();
return AcceptReject::Accept;
}
AcceptReject::Reject(item)
}
...
fn try_take(&mut self, item: Item) -> AcceptReject {
AcceptReject::Reject(item)
}
}