1use core::mem;
9use core::num::NonZeroU16;
10use core::fmt::{Display, Debug};
11use core::iter::IntoIterator;
12use core::ops::{Index, IndexMut};
13
14#[cfg(feature = "snapshot")]
15use ::serde::{Serialize, Deserialize};
16
17#[cfg(feature = "snapshot")]
18mod serde;
19
20#[cfg(feature = "snapshot")]
21pub use self::serde::*;
22
23use super::{BusDevice, VFNullDevice, NullDevice};
24
25pub trait NamedBusDevice<T>: Display + BusDevice<Timestamp=T, NextDevice=NullDevice<T>>{}
30
31impl<T, D> NamedBusDevice<T> for D where D: Display + BusDevice<Timestamp=T, NextDevice=NullDevice<T>>{}
32
33pub type NamedDynDevice<T> = dyn NamedBusDevice<T>;
35pub type BoxNamedDynDevice<T> = Box<dyn NamedBusDevice<T>>;
39
40pub type DynamicVBus<V> = DynamicBus<VFNullDevice<V>>;
42
43#[derive(Default, Debug)]
55#[cfg_attr(feature = "snapshot", derive(Serialize, Deserialize))]
56pub struct DynamicBus<D: BusDevice> {
57 #[cfg_attr(feature = "snapshot", serde(default))]
58 bus: D,
59 #[cfg_attr(feature = "snapshot", serde(skip))]
60 devices: Vec<BoxNamedDynDevice<D::Timestamp>>
61}
62
63impl<'a, T, D: 'a> From<D> for Box<dyn NamedBusDevice<T> + 'a>
64 where D: BusDevice<Timestamp=T, NextDevice=NullDevice<T>> + Display
65{
66 fn from(dev: D) -> Self {
67 Box::new(dev)
68 }
69}
70
71impl<D: BusDevice> AsRef<[BoxNamedDynDevice<D::Timestamp>]> for DynamicBus<D> {
72 fn as_ref(&self) -> &[BoxNamedDynDevice<D::Timestamp>] {
73 self.devices.as_slice()
74 }
75}
76
77impl<D: BusDevice> AsMut<[BoxNamedDynDevice<D::Timestamp>]> for DynamicBus<D> {
78 fn as_mut(&mut self) -> &mut[BoxNamedDynDevice<D::Timestamp>] {
79 self.devices.as_mut_slice()
80 }
81}
82
83impl<D> DynamicBus<D>
84 where D: BusDevice
85{
86 pub fn len(&self) -> usize {
88 self.devices.len()
89 }
90 pub fn is_empty(&self) -> bool {
92 self.len() == 0
93 }
94 pub fn append_device<B>(&mut self, device: B) -> usize
97 where B: Into<BoxNamedDynDevice<D::Timestamp>>
98 {
99 self.devices.push(device.into());
100 self.devices.len() - 1
101 }
102 pub fn remove_device(&mut self) -> Option<BoxNamedDynDevice<D::Timestamp>> {
105 self.devices.pop()
106 }
107 pub fn swap_remove_device(&mut self, index: usize) -> BoxNamedDynDevice<D::Timestamp> {
114 self.devices.swap_remove(index)
115 }
116 pub fn replace_device<B>(&mut self, index: usize, device: B) -> BoxNamedDynDevice<D::Timestamp>
121 where B: Into<BoxNamedDynDevice<D::Timestamp>>
122 {
123 mem::replace(&mut self.devices[index], device.into())
124 }
125 pub fn clear(&mut self) {
127 self.devices.clear();
128 }
129 #[inline]
131 pub fn get_device_ref(&self, index: usize) -> Option<&NamedDynDevice<D::Timestamp>> {
132 self.devices.get(index).map(|d| d.as_ref())
134 }
135 #[inline]
137 pub fn get_device_mut(&mut self, index: usize) -> Option<&mut NamedDynDevice<D::Timestamp>> {
138 self.devices.get_mut(index).map(|d| d.as_mut())
139 }
140}
141
142impl<D> DynamicBus<D>
143 where D: BusDevice,
144 D::Timestamp: 'static
145{
146 pub fn remove_as_device<B>(&mut self) -> Option<Box<B>>
151 where B: NamedBusDevice<D::Timestamp> + 'static
152 {
153 self.remove_device().map(|boxdev|
154 boxdev.downcast::<B>().expect("wrong dynamic device type removed")
155 )
156 }
157 pub fn swap_remove_as_device<B>(&mut self, index: usize) -> Box<B>
164 where B: NamedBusDevice<D::Timestamp> + 'static
165 {
166 self.swap_remove_device(index).downcast::<B>().expect("wrong dynamic device type removed")
167 }
168 #[inline]
173 pub fn as_device_ref<B>(&self, index: usize) -> &B
174 where B: NamedBusDevice<D::Timestamp> + 'static
175 {
176 self.devices[index].downcast_ref::<B>().expect("wrong dynamic device type")
177 }
178 #[inline]
183 pub fn as_device_mut<B>(&mut self, index: usize) -> &mut B
184 where B: NamedBusDevice<D::Timestamp> + 'static
185 {
186 self.devices[index].downcast_mut::<B>().expect("wrong dynamic device type")
187 }
188 #[inline]
190 pub fn is_device<B>(&self, index: usize) -> bool
191 where B: NamedBusDevice<D::Timestamp> + 'static
192 {
193 self.devices.get(index).map(|d| d.is::<B>()).unwrap_or(false)
194 }
195 #[inline]
197 pub fn position_device<B>(&self) -> Option<usize>
198 where B: NamedBusDevice<D::Timestamp> + 'static
199 {
200 self.devices.iter().position(|d| d.is::<B>())
201 }
202 #[inline]
204 pub fn find_device_ref<B>(&self) -> Option<&B>
205 where B: NamedBusDevice<D::Timestamp> + 'static
206 {
207 self.devices.iter().find_map(|d| d.downcast_ref::<B>())
208 }
209 #[inline]
211 pub fn find_device_mut<B>(&mut self) -> Option<&mut B>
212 where B: NamedBusDevice<D::Timestamp> + 'static
213 {
214 self.devices.iter_mut().find_map(|d| d.downcast_mut::<B>())
215 }
216}
217
218impl<D: BusDevice> Index<usize> for DynamicBus<D> {
219 type Output = NamedDynDevice<D::Timestamp>;
220 #[inline]
221 fn index(&self, index: usize) -> &Self::Output {
222 self.devices[index].as_ref()
223 }
224}
225
226impl<D: BusDevice> IndexMut<usize> for DynamicBus<D> {
227 #[inline]
228 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
229 self.devices[index].as_mut()
230 }
231}
232
233impl<'a, D: BusDevice> IntoIterator for &'a DynamicBus<D> {
234 type Item = &'a BoxNamedDynDevice<D::Timestamp>;
235 type IntoIter = core::slice::Iter<'a, BoxNamedDynDevice<D::Timestamp>>;
236 #[inline]
237 fn into_iter(self) -> Self::IntoIter {
238 self.devices.iter()
239 }
240}
241
242impl<'a, D: BusDevice> IntoIterator for &'a mut DynamicBus<D> {
243 type Item = &'a mut BoxNamedDynDevice<D::Timestamp>;
244 type IntoIter = core::slice::IterMut<'a, BoxNamedDynDevice<D::Timestamp>>;
245 #[inline]
246 fn into_iter(self) -> Self::IntoIter {
247 self.devices.iter_mut()
248 }
249}
250
251impl<D: BusDevice> IntoIterator for DynamicBus<D> {
252 type Item = BoxNamedDynDevice<D::Timestamp>;
253 type IntoIter = std::vec::IntoIter<BoxNamedDynDevice<D::Timestamp>>;
254 #[inline]
255 fn into_iter(self) -> Self::IntoIter {
256 self.devices.into_iter()
257 }
258}
259
260impl<D> BusDevice for DynamicBus<D>
261 where D: BusDevice,
262 D::Timestamp: Debug + Copy
263{
264 type Timestamp = D::Timestamp;
265 type NextDevice = D;
266
267 #[inline]
268 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
269 &mut self.bus
270 }
271 #[inline]
272 fn next_device_ref(&self) -> &Self::NextDevice {
273 &self.bus
274 }
275 #[inline]
276 fn into_next_device(self) -> Self::NextDevice {
277 self.bus
278 }
279 #[inline]
280 fn reset(&mut self, timestamp: Self::Timestamp) {
281 for dev in self.devices.iter_mut() {
282 dev.reset(timestamp);
283 }
284 self.bus.reset(timestamp);
285 }
286
287 #[inline]
288 fn update_timestamp(&mut self, timestamp: Self::Timestamp) {
289 for dev in self.devices.iter_mut() {
290 dev.update_timestamp(timestamp);
291 }
292 self.bus.update_timestamp(timestamp);
293 }
294
295 #[inline]
296 fn next_frame(&mut self, timestamp: Self::Timestamp) {
297 for dev in self.devices.iter_mut() {
298 dev.next_frame(timestamp);
299 }
300 self.bus.next_frame(timestamp);
301 }
302
303 #[inline]
304 fn read_io(&mut self, port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
305 let mut bus_data = None;
306 for dev in self.devices.iter_mut() {
307 if let Some((data, ws)) = dev.read_io(port, timestamp) {
308 let data = data & bus_data.unwrap_or(!0);
309 if ws.is_some() {
310 return Some((data, ws));
311 }
312 bus_data = Some(data);
313 }
314 }
315 if let Some((data, ws)) = self.bus.read_io(port, timestamp) {
316 return Some((data & bus_data.unwrap_or(!0), ws))
317 }
318 bus_data.map(|data| (data, None))
319 }
320
321 #[inline]
322 fn write_io(&mut self, port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
323 for dev in self.devices.iter_mut() {
324 if let Some(res) = dev.write_io(port, data, timestamp) {
325 return Some(res);
326 }
327 }
328 self.bus.write_io(port, data, timestamp)
329 }
330}
331
332#[cfg(test)]
333mod tests {
334 use core::fmt;
335 use super::*;
336
337 #[derive(Default, Clone, PartialEq, Debug)]
338 struct TestDevice {
339 foo: i32,
340 data: u8,
341 bus: NullDevice<i32>
342 }
343
344 impl fmt::Display for TestDevice {
345 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346 f.write_str("Test Device")
347 }
348 }
349
350 impl BusDevice for TestDevice {
351 type Timestamp = i32;
352 type NextDevice = NullDevice<i32>;
353
354 fn next_device_mut(&mut self) -> &mut Self::NextDevice {
355 &mut self.bus
356 }
357 fn next_device_ref(&self) -> &Self::NextDevice {
358 &self.bus
359 }
360 fn into_next_device(self) -> Self::NextDevice {
361 self.bus
362 }
363 fn reset(&mut self, timestamp: Self::Timestamp) {
364 self.foo = i32::min_value() + timestamp;
365 }
366 fn update_timestamp(&mut self, timestamp: Self::Timestamp) {
367 self.foo = timestamp
368 }
369 fn read_io(&mut self, _port: u16, timestamp: Self::Timestamp) -> Option<(u8, Option<NonZeroU16>)> {
370 if self.foo == timestamp {
371 Some((self.data, None))
372 }
373 else {
374 None
375 }
376 }
377 fn write_io(&mut self, _port: u16, data: u8, timestamp: Self::Timestamp) -> Option<u16> {
378 self.data = data;
379 self.foo = timestamp;
380 Some(0)
381 }
382 }
383
384 #[test]
385 fn dynamic_bus_device_works() {
386 let mut dchain: DynamicBus<NullDevice<i32>> = Default::default();
387 assert_eq!(dchain.len(), 0);
388 assert_eq!(dchain.write_io(0, 0, 0), None);
389 assert_eq!(dchain.read_io(0, 0), None);
390 let test_dev: Box<dyn NamedBusDevice<_>> = Box::new(TestDevice::default());
391 let index = dchain.append_device(test_dev);
392 assert_eq!(dchain.is_device::<TestDevice>(index), true);
393 assert_eq!(index, 0);
394 assert_eq!(dchain.len(), 1);
395 let device = dchain.remove_device().unwrap();
396 assert_eq!(device.is::<TestDevice>(), true);
397 assert_eq!(dchain.len(), 0);
398
399 let index0 = dchain.append_device(NullDevice::default());
400 assert_eq!(index0, 0);
401 assert_eq!(dchain.is_device::<TestDevice>(index0), false);
402 assert_eq!(dchain.is_device::<NullDevice<_>>(index0), true);
403 assert_eq!(dchain.len(), 1);
404 let dev: &NullDevice<_> = dchain.as_device_ref(index0);
405 assert_eq!(dev, &NullDevice::default());
406
407 let index1 = dchain.append_device(TestDevice::default());
408 assert_eq!(index1, 1);
409 assert_eq!(dchain.is_device::<TestDevice>(index1), true);
410 assert_eq!(dchain.is_device::<TestDevice>(index0), false);
411 assert_eq!(dchain.is_device::<TestDevice>(usize::max_value()), false);
412 assert_eq!(dchain.is_device::<NullDevice<_>>(index0), true);
413 assert_eq!(dchain.is_device::<NullDevice<_>>(index1), false);
414 assert_eq!(dchain.is_device::<NullDevice<_>>(usize::max_value()), false);
415 let dev = dchain.get_device_ref(index1).unwrap();
416 assert_eq!(dev.is::<TestDevice>(), true);
417 assert_eq!(dev.is::<NullDevice<_>>(), false);
418 assert_eq!(format!("{}", dev), "Test Device");
419 if let Some(dev) = dchain.get_device_mut(index1) {
420 dev.update_timestamp(777);
421 assert_eq!(dev.read_io(0, 0), None);
422 assert_eq!(dev.read_io(0, 777), Some((0, None)));
423 }
424 assert_eq!(dchain.len(), 2);
425 assert_eq!(dchain.write_io(0, 42, 131999), Some(0));
426 assert_eq!(dchain.read_io(0, 0), None);
427 assert_eq!(dchain.read_io(0, 131999), Some((42, None)));
428 let dev: &TestDevice = dchain.as_device_ref(index1);
429 assert_eq!(dev.data, 42);
430 assert_eq!(dev.foo, 131999);
431 let dev: &mut TestDevice = dchain.as_device_mut(index1);
432 dev.data = 199;
433 dev.foo = -1;
434 let dev: &TestDevice = dchain.as_device_ref(index1);
435 assert_eq!(dev.data, 199);
436 assert_eq!(dev.foo, -1);
437 let device: TestDevice = *dchain.remove_as_device().unwrap();
438 assert_eq!(dchain.len(), 1);
439 assert_eq!(device, TestDevice {
440 foo: -1,
441 data: 199,
442 bus: NullDevice::<i32>::default()
443 });
444 }
445}