Skip to main content

CydMemory

Struct CydMemory 

Source
pub struct CydMemory { /* private fields */ }
Expand description

In-memory CYD device for fast, deterministic native desktop tests and screenshots.

Enable the host feature to use this in an ordinary Windows, macOS, or Linux process. Tests can draw through the portable Cyd interface, inject touch and button input, inspect pixels and flush counts, and compare the complete framebuffer with a golden PNG.

§Example

use device_envoy_core::{
    button::Button,
    cyd::{
        Cyd, CydDisplay, CydTouch,
        display::{CydFrame, DrawItem, Image565Fixed, tga},
        touch::TouchEvent,
    },
    memory::{CydMemory, assert_framebuffer_matches_expected_png},
};
use embedded_graphics::{
    mono_font::ascii::FONT_9X15_BOLD,
    pixelcolor::{Rgb888, RgbColor},
    prelude::{Point, Size},
};
use futures_executor::block_on;

const BITMAP: Image565Fixed<45, 73, { 45 * 73 }> = tga!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/docs/assets/cyd_fill_contiguous.tga"
))
.to_565();

let mut cyd_memory = CydMemory::new(
    Size::new(320, 240),
    Rgb888::BLACK,
    Rgb888::WHITE,
    &FONT_9X15_BOLD,
);
cyd_memory.push_touch_event(TouchEvent::Up);
assert!(matches!(
    cyd_memory.touch().try_read()?,
    Some(TouchEvent::Up)
));
let mut button = cyd_memory.button_memory();
button.set_pressed(true);
button.set_pressed_for_frame(1, false);
let mut display = cyd_memory.display();
let mut frame = display.full_frame_mut();
frame.write_text("Hello CYD");
DrawItem::Bitmap {
    view: BITMAP.view(),
    top_left: Point::new(128, 88),
}
.draw(&mut frame);
block_on(frame.flush())?;
assert!(!button.is_pressed());
assert_eq!(cyd_memory.flush_count(), 1);
let golden_result = assert_framebuffer_matches_expected_png(
    &cyd_memory,
    env!("CARGO_MANIFEST_DIR"),
    "cyd_memory_bitmap.png",
);
assert!(golden_result.is_ok(), "{golden_result:?}");

CydMemory framebuffer preview

Implementations§

Source§

impl CydMemory

Source

pub fn new( size: Size, background_color: Rgb888, foreground_color: Rgb888, font: &'static MonoFont<'static>, ) -> Self

Construct an empty in-memory CYD surface with the given screen style.

The CydMemory example demonstrates the canonical construction and complete host-test workflow.

Source

pub fn new_with_orientation( orientation: Orientation, background_color: Rgb888, foreground_color: Rgb888, font: &'static MonoFont<'static>, ) -> Self

Construct an in-memory CYD surface with an oriented logical screen.

§Example
use device_envoy_core::{
    cyd::{Cyd, CydDisplay, display::{CydFrame, Orientation}},
    memory::{CydMemory, Error},
};
use embedded_graphics::{
    mono_font::ascii::FONT_9X15_BOLD,
    pixelcolor::{Rgb565, Rgb888},
    prelude::{Point, RgbColor, Size},
    primitives::Rectangle,
};
use futures_executor::block_on;

let mut cyd_memory = CydMemory::new_with_orientation(
    Orientation::LandscapeInverted,
    Rgb888::BLACK,
    Rgb888::WHITE,
    &FONT_9X15_BOLD,
);
assert_eq!(cyd_memory.orientation(), Orientation::LandscapeInverted);

let pixel = Rectangle::new(Point::zero(), Size::new(1, 1));
let mut display = cyd_memory.display();
let mut first_frame = display.frame_mut(pixel);
first_frame.fill(Rgb565::RED);
block_on(first_frame.flush())?;
drop(first_frame);
assert_eq!(cyd_memory.pixel(0, 0), Rgb565::RED);
cyd_memory.rotate_framebuffer_180();
assert_eq!(cyd_memory.pixel(319, 239), Rgb565::RED);
Source

pub fn display(&self) -> CydDisplayMemory

Clone the device’s display component for an independent test task.

Source

pub fn owned_parts(&self) -> (CydDisplayMemory, CydTouchMemory)

Clone owned calibrated parts that share this harness’s backing state.

Source§

impl CydMemory

Source

pub fn set_frame_budget(&mut self, frame_budget: usize)

Limit how many frames may flush before Error::OutOfFrames.

use device_envoy_core::{
    cyd::{CydDisplay, display::CydFrame},
    memory::{CydMemory, Error},
};
use embedded_graphics::{
    mono_font::ascii::FONT_9X15_BOLD,
    pixelcolor::{Rgb888, RgbColor},
    prelude::Size,
};

let mut cyd_memory = CydMemory::new(
    Size::new(320, 240),
    Rgb888::BLACK,
    Rgb888::WHITE,
    &FONT_9X15_BOLD,
);
cyd_memory.set_frame_budget(1);
let mut display = cyd_memory.display();

let mut first_frame = display.full_frame_mut();
futures_executor::block_on(first_frame.flush())?;
drop(first_frame);
let mut second_frame = display.full_frame_mut();
assert_eq!(
    futures_executor::block_on(second_frame.flush()),
    Err(Error::OutOfFrames),
);
Source

pub fn button_memory(&self) -> ButtonMemory

Create a native desktop test button tied to this device’s frame clock.

The CydMemory example demonstrates button state changing when a frame flush advances the shared clock.

Source

pub fn push_touch_event(&mut self, touch_event: TouchEvent)

Queue one calibrated touch event for the current frame.

The CydMemory example demonstrates injecting an event and reading it through the portable CydTouch API.

Source

pub fn flush_count(&self) -> usize

Return how many frames have flushed so far.

Source

pub fn last_flush_rectangle(&self) -> Option<Rectangle>

Return the rectangle flushed most recently, if any.

Source

pub fn pixel(&self, position_x: usize, position_y: usize) -> Rgb565

Read one pixel from the in-memory framebuffer.

Source

pub fn rotate_framebuffer_180(&self)

Apply the physical 180-degree presentation used by an inverted CYD orientation.

The new_with_orientation example demonstrates rotating an inverted framebuffer and inspecting a pixel.

Hardware display drivers and browser shells apply this transform outside the logical application framebuffer. Native desktop previews can call this after rendering to compare the user-facing presentation rather than the untransformed logical buffer.

Trait Implementations§

Source§

impl Cyd for CydMemory

Source§

type Error = Error

Error returned by both the display and calibrated touch parts. See the application example for a generic operation that returns this error.
Source§

type Display = CydDisplayMemory

Source§

type Touch = CydTouchMemory

Source§

fn parts(&mut self) -> (&mut Self::Display, &mut Self::Touch)

Borrow the display and calibrated touch components at once. Read more
Source§

fn orientation(&self) -> Orientation

Return the logical orientation of this complete device. Read more
Source§

fn display(&mut self) -> &mut Self::Display

Borrow the display component. Read more
Source§

fn touch(&mut self) -> &mut Self::Touch

Borrow the calibrated touch component. Read more
Source§

impl Debug for CydMemory

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CydMemory

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> StrictAs for T

Source§

fn strict_as<Dst>(self) -> Dst
where T: StrictCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> StrictCastFrom<Src> for Dst
where Src: StrictCast<Dst>,

Source§

fn strict_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.