use ::std::{thread, time::Duration};
use crate::error::Result;
use crate::mem::{
PhysicalMemory, PhysicalMemoryMapping, PhysicalMemoryMetadata, PhysicalReadMemOps,
PhysicalWriteMemOps,
};
pub struct DelayedPhysicalMemory<T> {
mem: T,
delay: Duration,
}
impl<T> Clone for DelayedPhysicalMemory<T>
where
T: Clone,
{
fn clone(&self) -> Self {
Self {
mem: self.mem.clone(),
delay: self.delay,
}
}
}
impl<T: PhysicalMemory> DelayedPhysicalMemory<T> {
pub fn new(mem: T, delay: Duration) -> Self {
Self { mem, delay }
}
pub fn into_inner(self) -> T {
self.mem
}
}
impl<T: PhysicalMemory> DelayedPhysicalMemory<T> {
pub fn builder(mem: T) -> DelayedPhysicalMemoryBuilder<T> {
DelayedPhysicalMemoryBuilder::new(mem)
}
}
impl<T: PhysicalMemory> PhysicalMemory for DelayedPhysicalMemory<T> {
#[inline]
fn phys_read_raw_iter(&mut self, data: PhysicalReadMemOps) -> Result<()> {
thread::sleep(self.delay);
self.mem.phys_read_raw_iter(data)
}
#[inline]
fn phys_write_raw_iter(&mut self, data: PhysicalWriteMemOps) -> Result<()> {
thread::sleep(self.delay);
self.mem.phys_write_raw_iter(data)
}
#[inline]
fn metadata(&self) -> PhysicalMemoryMetadata {
self.mem.metadata()
}
#[inline]
fn set_mem_map(&mut self, mem_map: &[PhysicalMemoryMapping]) {
self.mem.set_mem_map(mem_map)
}
}
pub struct DelayedPhysicalMemoryBuilder<T> {
mem: T,
delay: Duration,
}
impl<T: PhysicalMemory> DelayedPhysicalMemoryBuilder<T> {
pub fn new(mem: T) -> Self {
Self {
mem,
delay: Duration::from_millis(10),
}
}
pub fn delay(mut self, delay: Duration) -> Self {
self.delay = delay;
self
}
pub fn build(self) -> Result<DelayedPhysicalMemory<T>> {
Ok(DelayedPhysicalMemory::new(self.mem, self.delay))
}
}
#[cfg(feature = "plugins")]
::cglue::cglue_impl_group!(
DelayedPhysicalMemory<T: PhysicalMemory>,
crate::plugins::ConnectorInstance,
{}
);