Files
@ cecf94fdb875
Branch filter:
Location: CSY/reowolf/src/runtime/retired/connector.rs
cecf94fdb875
6.9 KiB
application/rls-services+xml
simplified approach to the piecewise acquisition of port info. starting to reintegrate communication phase
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | use crate::common::*;
use crate::runtime::{errors::*, *};
pub fn random_controller_id() -> ControllerId {
type Bytes8 = [u8; std::mem::size_of::<ControllerId>()];
let mut bytes = Bytes8::default();
getrandom::getrandom(&mut bytes).unwrap();
unsafe { std::mem::transmute::<Bytes8, ControllerId>(bytes) }
}
impl Default for Unconfigured {
fn default() -> Self {
let controller_id = random_controller_id();
Self { controller_id }
}
}
impl Default for Connector {
fn default() -> Self {
Self::Unconfigured(Unconfigured::default())
}
}
impl Connector {
/// Configure the Connector with the given Pdl description.
pub fn configure(&mut self, pdl: &[u8], main_component: &[u8]) -> Result<(), ConfigErr> {
use ConfigErr::*;
let controller_id = match self {
Connector::Configured(_) => return Err(AlreadyConfigured),
Connector::Connected(_) => return Err(AlreadyConnected),
Connector::Unconfigured(Unconfigured { controller_id }) => *controller_id,
};
let protocol_description = Arc::new(ProtocolD::parse(pdl).map_err(ParseErr)?);
let polarities = protocol_description.component_polarities(main_component)?;
let configured = Configured {
controller_id,
protocol_description,
bindings: Default::default(),
polarities,
main_component: main_component.to_vec(),
logger: "Logger created!\n".into(),
};
*self = Connector::Configured(configured);
Ok(())
}
/// Bind the (configured) connector's port corresponding to the
pub fn bind_port(
&mut self,
proto_port_index: usize,
binding: PortBinding,
) -> Result<(), PortBindErr> {
use PortBindErr::*;
match self {
Connector::Unconfigured { .. } => Err(NotConfigured),
Connector::Connected(_) => Err(AlreadyConnected),
Connector::Configured(configured) => {
if configured.polarities.len() <= proto_port_index {
return Err(IndexOutOfBounds);
}
configured.bindings.insert(proto_port_index, binding);
Ok(())
}
}
}
pub fn connect(&mut self, timeout: Duration) -> Result<(), ConnectErr> {
let deadline = Instant::now() + timeout;
use ConnectErr::*;
let configured = match self {
Connector::Unconfigured { .. } => return Err(NotConfigured),
Connector::Connected(_) => return Err(AlreadyConnected),
Connector::Configured(configured) => configured,
};
// 1. Unwrap bindings or err
let bound_proto_interface: Vec<(_, _)> = configured
.polarities
.iter()
.copied()
.enumerate()
.map(|(native_index, polarity)| {
let binding = configured
.bindings
.get(&native_index)
.copied()
.ok_or(PortNotBound { native_index })?;
Ok((binding, polarity))
})
.collect::<Result<Vec<(_, _)>, ConnectErr>>()?;
let (controller, native_interface) = Controller::connect(
configured.controller_id,
&configured.main_component,
configured.protocol_description.clone(),
&bound_proto_interface[..],
&mut configured.logger,
deadline,
)?;
*self = Connector::Connected(Connected {
native_interface,
sync_batches: vec![Default::default()],
controller,
});
Ok(())
}
pub fn get_mut_logger(&mut self) -> Option<&mut String> {
match self {
Connector::Configured(configured) => Some(&mut configured.logger),
Connector::Connected(connected) => Some(&mut connected.controller.inner.logger),
_ => None,
}
}
pub fn put(&mut self, native_port_index: usize, payload: Payload) -> Result<(), PortOpErr> {
use PortOpErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let (port, native_polarity) =
*connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if native_polarity != Putter {
return Err(WrongPolarity);
}
let sync_batch = connected.sync_batches.iter_mut().last().expect("no sync batch!");
if sync_batch.puts.contains_key(&port) {
return Err(DuplicateOperation);
}
sync_batch.puts.insert(port, payload);
Ok(())
}
pub fn get(&mut self, native_port_index: usize) -> Result<(), PortOpErr> {
use PortOpErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let (port, native_polarity) =
*connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if native_polarity != Getter {
return Err(WrongPolarity);
}
let sync_batch = connected.sync_batches.iter_mut().last().expect("no sync batch!");
if sync_batch.gets.contains(&port) {
return Err(DuplicateOperation);
}
sync_batch.gets.insert(port);
Ok(())
}
pub fn next_batch(&mut self) -> Result<usize, ()> {
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(()),
};
connected.sync_batches.push(SyncBatch::default());
Ok(connected.sync_batches.len() - 2)
}
pub fn sync(&mut self, timeout: Duration) -> Result<usize, SyncErr> {
let deadline = Instant::now() + timeout;
use SyncErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
// do the synchronous round!
let res =
connected.controller.sync_round(Some(deadline), Some(connected.sync_batches.drain(..)));
connected.sync_batches.push(SyncBatch::default());
res?;
Ok(connected.controller.inner.mono_n.result.as_mut().expect("qqqs").0)
}
pub fn read_gotten(&self, native_port_index: usize) -> Result<&[u8], ReadGottenErr> {
use ReadGottenErr::*;
let connected = match self {
Connector::Connected(connected) => connected,
_ => return Err(NotConnected),
};
let &(key, polarity) =
connected.native_interface.get(native_port_index).ok_or(IndexOutOfBounds)?;
if polarity != Getter {
return Err(WrongPolarity);
}
let result = connected.controller.inner.mono_n.result.as_ref().ok_or(NoPreviousRound)?;
let payload = result.1.get(&key).ok_or(DidNotGet)?;
Ok(payload.as_slice())
}
}
|