mirror of
https://github.com/cccb/servicepoint.git
synced 2025-01-18 10:00:14 +01:00
move grid functions to trait
This commit is contained in:
parent
314bec36f3
commit
bcf040911d
10
README.md
10
README.md
|
@ -64,13 +64,11 @@ int main(void) {
|
|||
sp2_PixelGrid *pixels = sp2_pixel_grid_new(sp2_PIXEL_WIDTH, sp2_PIXEL_HEIGHT);
|
||||
sp2_pixel_grid_fill(pixels, true);
|
||||
|
||||
command = sp2_command_bitmap_linear_win(0, 0, pixels); // pixels get consumed here
|
||||
if (command == NULL)
|
||||
return 4;
|
||||
if (!sp2_connection_send(connection, command)) // command gets consumed here
|
||||
return 5;
|
||||
sp2_Command *command = sp2_command_bitmap_linear_win(0, 0, pixels, Uncompressed);
|
||||
sp2_Packet *packet = sp2_packet_from_command(command);
|
||||
if (!sp2_connection_send(connection, packet))
|
||||
return 1;
|
||||
|
||||
// connection does not get consumed and has to be freed manually
|
||||
sp2_connection_dealloc(connection);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use clap::Parser;
|
||||
|
||||
use servicepoint2::{ByteGrid, Command, Connection, Origin};
|
||||
use servicepoint2::{ByteGrid, Command, Connection, Grid, Origin};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
|
|
@ -3,9 +3,7 @@ use std::thread;
|
|||
use clap::Parser;
|
||||
use rand::{distributions, Rng};
|
||||
|
||||
use servicepoint2::{
|
||||
Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING,
|
||||
};
|
||||
use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, Grid};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
|
|
@ -2,10 +2,7 @@ use std::thread;
|
|||
|
||||
use clap::Parser;
|
||||
|
||||
use servicepoint2::{
|
||||
Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING,
|
||||
PIXEL_HEIGHT, PIXEL_WIDTH,
|
||||
};
|
||||
use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
|
|
@ -4,10 +4,7 @@ use clap::Parser;
|
|||
use rand::Rng;
|
||||
|
||||
use servicepoint2::Command::{BitmapLinearWin, Brightness, CharBrightness};
|
||||
use servicepoint2::{
|
||||
ByteGrid, CompressionCode, Connection, Origin, PixelGrid, TILE_HEIGHT,
|
||||
TILE_WIDTH,
|
||||
};
|
||||
use servicepoint2::{ByteGrid, CompressionCode, Connection, Grid, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
|
|
@ -3,10 +3,7 @@ use std::time::Duration;
|
|||
|
||||
use clap::Parser;
|
||||
|
||||
use servicepoint2::{
|
||||
BitVec, Command, CompressionCode, Connection, PixelGrid, FRAME_PACING,
|
||||
PIXEL_HEIGHT, PIXEL_WIDTH,
|
||||
};
|
||||
use servicepoint2::{BitVec, Command, CompressionCode, Connection, PixelGrid, FRAME_PACING, PIXEL_HEIGHT, PIXEL_WIDTH, Grid};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::Grid;
|
||||
|
||||
/// A 2D grid of bytes
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ByteGrid {
|
||||
|
@ -34,40 +36,11 @@ impl ByteGrid {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the current value at the specified position
|
||||
///
|
||||
/// returns: current byte value
|
||||
pub fn get(&self, x: usize, y: usize) -> u8 {
|
||||
self.check_indexes(x, y);
|
||||
self.data[x + y * self.width]
|
||||
}
|
||||
|
||||
/// Sets the byte value at the specified position
|
||||
pub fn set(&mut self, x: usize, y: usize, value: u8) {
|
||||
self.check_indexes(x, y);
|
||||
self.data[x + y * self.width] = value;
|
||||
}
|
||||
|
||||
/// Sets all bytes in the grid to the specified value
|
||||
pub fn fill(&mut self, value: u8) {
|
||||
self.data.fill(value)
|
||||
}
|
||||
|
||||
/// Get the underlying byte rows
|
||||
pub fn mut_data_ref(&mut self) -> &mut [u8] {
|
||||
self.data.as_mut_slice()
|
||||
}
|
||||
|
||||
/// the size in x-direction
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
/// the height in y-direction
|
||||
pub fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
|
||||
fn check_indexes(&self, x: usize, y: usize) {
|
||||
if x >= self.width {
|
||||
panic!("cannot access byte {x}-{y} because x is outside of bounds 0..{}", self.width)
|
||||
|
@ -78,6 +51,34 @@ impl ByteGrid {
|
|||
}
|
||||
}
|
||||
|
||||
impl Grid<u8> for ByteGrid {
|
||||
fn set(&mut self, x: usize, y: usize, value: u8) -> u8 {
|
||||
self.check_indexes(x, y);
|
||||
let pos = &mut self.data[x + y * self.width];
|
||||
let old_val = *pos;
|
||||
*pos = value;
|
||||
old_val
|
||||
}
|
||||
|
||||
fn get(&self, x: usize, y: usize) -> u8 {
|
||||
self.check_indexes(x, y);
|
||||
self.data[x + y * self.width]
|
||||
}
|
||||
|
||||
fn fill(&mut self, value: u8) {
|
||||
self.data.fill(value)
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl From<ByteGrid> for Vec<u8> {
|
||||
/// Turn into the underlying `Vec<u8>` containing the rows of bytes.
|
||||
fn from(value: ByteGrid) -> Self {
|
||||
|
@ -88,6 +89,7 @@ impl From<ByteGrid> for Vec<u8> {
|
|||
#[cfg(feature = "c_api")]
|
||||
pub mod c_api {
|
||||
use crate::{ByteGrid, CByteSlice};
|
||||
use crate::grid::Grid;
|
||||
|
||||
/// Creates a new `ByteGrid` instance.
|
||||
/// The returned instance has to be freed with `byte_grid_dealloc`.
|
||||
|
@ -198,7 +200,7 @@ pub mod c_api {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ByteGrid;
|
||||
use crate::{ByteGrid, Grid};
|
||||
|
||||
#[test]
|
||||
fn fill() {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use crate::command_code::CommandCode;
|
||||
use crate::compression::{into_compressed, into_decompressed};
|
||||
use crate::{
|
||||
BitVec, ByteGrid, CompressionCode, Header, Packet, PixelGrid, TILE_SIZE,
|
||||
};
|
||||
use crate::{BitVec, ByteGrid, CompressionCode, Grid, Header, Packet, PixelGrid, TILE_SIZE};
|
||||
|
||||
/// An origin marks the top left position of a window sent to the display.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
@ -728,6 +726,7 @@ mod tests {
|
|||
if compression != CompressionCode::Uncompressed {
|
||||
assert_eq!(result, Err(TryFromPacketError::DecompressionFailed))
|
||||
} else {
|
||||
// when not compressing, there is no way to detect corrupted data
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
|
|
18
servicepoint2/src/grid.rs
Normal file
18
servicepoint2/src/grid.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
pub trait Grid<T> {
|
||||
/// Sets the value at the specified position
|
||||
///
|
||||
/// returns: the old value
|
||||
fn set(&mut self, x: usize, y: usize, value: T) -> T;
|
||||
|
||||
/// Get the current value at the specified position
|
||||
fn get(&self, x: usize, y: usize) -> T;
|
||||
|
||||
/// Sets all cells in the grid to the specified value
|
||||
fn fill(&mut self, value: T);
|
||||
|
||||
/// the size in x-direction
|
||||
fn width(&self) -> usize;
|
||||
|
||||
/// the height in y-direction
|
||||
fn height(&self) -> usize;
|
||||
}
|
|
@ -5,6 +5,7 @@ pub use crate::compression_code::CompressionCode;
|
|||
pub use crate::connection::Connection;
|
||||
pub use crate::packet::{Header, Packet, Payload};
|
||||
pub use crate::pixel_grid::PixelGrid;
|
||||
pub use crate::grid::Grid;
|
||||
use std::time::Duration;
|
||||
|
||||
#[cfg(feature = "c_api")]
|
||||
|
@ -20,17 +21,23 @@ mod compression_code;
|
|||
mod connection;
|
||||
mod packet;
|
||||
mod pixel_grid;
|
||||
mod grid;
|
||||
|
||||
/// size of a single tile in one dimension
|
||||
pub const TILE_SIZE: u16 = 8;
|
||||
|
||||
/// tile count in the x-direction
|
||||
pub const TILE_WIDTH: u16 = 56;
|
||||
|
||||
/// tile count in the y-direction
|
||||
pub const TILE_HEIGHT: u16 = 20;
|
||||
|
||||
/// screen width in pixels
|
||||
pub const PIXEL_WIDTH: u16 = TILE_WIDTH * TILE_SIZE;
|
||||
|
||||
/// screen height in pixels
|
||||
pub const PIXEL_HEIGHT: u16 = TILE_HEIGHT * TILE_SIZE;
|
||||
|
||||
/// pixel count on whole screen
|
||||
pub const PIXEL_COUNT: usize = PIXEL_WIDTH as usize * PIXEL_HEIGHT as usize;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{BitVec, PIXEL_HEIGHT, PIXEL_WIDTH};
|
||||
use crate::{BitVec, Grid, PIXEL_HEIGHT, PIXEL_WIDTH};
|
||||
|
||||
/// A grid of pixels stored in packed bytes.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
@ -58,38 +58,10 @@ impl PixelGrid {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sets the byte value at the specified position
|
||||
pub fn set(&mut self, x: usize, y: usize, value: bool) -> bool {
|
||||
self.check_indexes(x, y);
|
||||
self.bit_vec.set(x + y * self.width, value)
|
||||
}
|
||||
|
||||
/// Get the current value at the specified position
|
||||
///
|
||||
/// returns: current pixel value
|
||||
pub fn get(&self, x: usize, y: usize) -> bool {
|
||||
self.bit_vec.get(x + y * self.width)
|
||||
}
|
||||
|
||||
/// Sets all pixels in the grid to the specified value
|
||||
pub fn fill(&mut self, value: bool) {
|
||||
self.bit_vec.fill(value);
|
||||
}
|
||||
|
||||
pub fn mut_data_ref(&mut self) -> &mut [u8] {
|
||||
self.bit_vec.mut_data_ref()
|
||||
}
|
||||
|
||||
/// the size in x-direction in pixels
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
/// the height in y-direction in pixels
|
||||
pub fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
|
||||
fn check_indexes(&self, x: usize, y: usize) {
|
||||
if x >= self.width {
|
||||
panic!("cannot access pixel {x}-{y} because x is outside of bounds 0..{}", self.width)
|
||||
|
@ -100,6 +72,29 @@ impl PixelGrid {
|
|||
}
|
||||
}
|
||||
|
||||
impl Grid<bool> for PixelGrid {
|
||||
fn set(&mut self, x: usize, y: usize, value: bool) -> bool {
|
||||
self.check_indexes(x, y);
|
||||
self.bit_vec.set(x + y * self.width, value)
|
||||
}
|
||||
|
||||
fn get(&self, x: usize, y: usize) -> bool {
|
||||
self.bit_vec.get(x + y * self.width)
|
||||
}
|
||||
|
||||
fn fill(&mut self, value: bool) {
|
||||
self.bit_vec.fill(value);
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PixelGrid> for Vec<u8> {
|
||||
/// Turns a `PixelGrid` into the underlying `Vec<u8>`.
|
||||
fn from(value: PixelGrid) -> Self {
|
||||
|
@ -110,7 +105,7 @@ impl From<PixelGrid> for Vec<u8> {
|
|||
#[cfg(feature = "c_api")]
|
||||
pub mod c_api {
|
||||
use crate::c_slice::CByteSlice;
|
||||
use crate::PixelGrid;
|
||||
use crate::{Grid, PixelGrid};
|
||||
|
||||
/// Creates a new `PixelGrid` instance.
|
||||
/// The returned instance has to be freed with `pixel_grid_dealloc`.
|
||||
|
@ -221,7 +216,7 @@ pub mod c_api {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::PixelGrid;
|
||||
use crate::{Grid, PixelGrid};
|
||||
|
||||
#[test]
|
||||
fn fill() {
|
||||
|
|
Loading…
Reference in a new issue