From 3264eaa56757f8a9de25f754980983ffaca6a4a2 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 8 Mar 2025 14:38:25 +0100 Subject: [PATCH 1/4] update to new (unreleased) servicepoint version --- Cargo.lock | 3 +- Cargo.toml | 2 +- src/command_executor.rs | 79 ++++++++++++++++++++++++----------------- src/cp437_font.rs | 2 +- src/gui.rs | 3 +- src/main.rs | 2 +- src/udp_server.rs | 19 +++++----- 7 files changed, 62 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 609e01d..ca82124 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1440,8 +1440,7 @@ dependencies = [ [[package]] name = "servicepoint" version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33abd53582a995aaf5d387be4a1f7eb294a084185f88f8cf61652b6272041660" +source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#300bb5d6474f0f6152ab04feed4478995fcb3ec8" dependencies = [ "bitvec", "bzip2", diff --git a/Cargo.toml b/Cargo.toml index ac7b5a2..bcb3076 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ clap = { version = "4.5", features = ["derive"] } thiserror = "2.0" # package parsing -servicepoint = { version = "0.13.2", features = ["all_compressions"] } +servicepoint = { features = ["all_compressions"], git = "https://git.berlin.ccc.de/servicepoint/servicepoint/", branch = "next" } # font rendering font-kit = "0.14.2" diff --git a/src/command_executor.rs b/src/command_executor.rs index 51ed9e1..974d3b6 100644 --- a/src/command_executor.rs +++ b/src/command_executor.rs @@ -1,13 +1,19 @@ -use crate::command_executor::ExecutionResult::{Failure, Shutdown, Success}; -use crate::cp437_font::Cp437Font; -use crate::font_renderer::FontRenderer8x8; +use crate::{ + command_executor::ExecutionResult::{Failure, Shutdown, Success}, + cp437_font::Cp437Font, + font_renderer::FontRenderer8x8, +}; use log::{debug, error, info, trace, warn}; use servicepoint::{ - BitVec, Bitmap, BrightnessGrid, CharGrid, Command, Cp437Grid, Grid, Offset, - Origin, Tiles, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, + BinaryOperation, BitVec, BitVecCommand, Bitmap, BitmapCommand, + BrightnessCommand, BrightnessGrid, BrightnessGridCommand, CharGrid, + CharGridCommand, Cp437Grid, Cp437GridCommand, Grid, Offset, Origin, Tiles, + TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, +}; +use std::{ + ops::{BitAnd, BitOr, BitXor}, + sync::RwLock, }; -use std::ops::{BitAnd, BitOr, BitXor}; -use std::sync::RwLock; #[derive(Debug)] pub struct CommandExecutor<'t> { @@ -38,53 +44,62 @@ impl<'t> CommandExecutor<'t> { } } - pub(crate) fn execute(&self, command: Command) -> ExecutionResult { + pub(crate) fn execute(&self, command: TypedCommand) -> ExecutionResult { debug!("received {command:?}"); match command { - Command::Clear => { + TypedCommand::Clear(_) => { info!("clearing display"); self.display.write().unwrap().fill(false); Success } - Command::HardReset => { + TypedCommand::HardReset(_) => { warn!("display shutting down"); Shutdown } - Command::BitmapLinearWin(Origin { x, y, .. }, pixels, _) => { - self.print_pixel_grid(x, y, &pixels) - } - Command::Cp437Data(origin, grid) => { + TypedCommand::Bitmap(BitmapCommand { + origin: Origin { x, y, .. }, + bitmap, + .. + }) => self.print_pixel_grid(x, y, &bitmap), + TypedCommand::Cp437Grid(Cp437GridCommand { origin, grid }) => { self.print_cp437_data(origin, &grid) } #[allow(deprecated)] - Command::BitmapLegacy => { + TypedCommand::BitmapLegacy(_) => { warn!("ignoring deprecated command {:?}", command); Failure } - Command::BitmapLinearAnd(offset, vec, _) => { - self.execute_bitmap_linear(offset, vec, BitAnd::bitand) + TypedCommand::BitVec(command) => { + let BitVecCommand { + offset, + bitvec, + operation, + .. + } = command; + fn overwrite(_: bool, new: bool) -> bool { + new + } + let operation = match operation { + BinaryOperation::Overwrite => overwrite, + BinaryOperation::And => BitAnd::bitand, + BinaryOperation::Or => BitOr::bitor, + BinaryOperation::Xor => BitXor::bitxor, + }; + self.execute_bitmap_linear(offset, bitvec, operation) } - Command::BitmapLinearOr(offset, vec, _) => { - self.execute_bitmap_linear(offset, vec, BitOr::bitor) - } - Command::BitmapLinearXor(offset, vec, _) => { - self.execute_bitmap_linear(offset, vec, BitXor::bitxor) - } - Command::BitmapLinear(offset, vec, _) => { - self.execute_bitmap_linear(offset, vec, move |_, new| new) - } - Command::CharBrightness(origin, grid) => { - self.execute_char_brightness(origin, grid) - } - Command::Brightness(brightness) => { + TypedCommand::BrightnessGrid(BrightnessGridCommand { + origin, + grid, + }) => self.execute_char_brightness(origin, grid), + TypedCommand::Brightness(BrightnessCommand { brightness }) => { self.luma.write().unwrap().fill(brightness); Success } - Command::FadeOut => { + TypedCommand::FadeOut(_) => { error!("command not implemented: {command:?}"); Success } - Command::Utf8Data(origin, grid) => { + TypedCommand::CharGrid(CharGridCommand { origin, grid }) => { self.print_utf8_data(origin, &grid) } } diff --git a/src/cp437_font.rs b/src/cp437_font.rs index 7c1e3ff..73a3d95 100644 --- a/src/cp437_font.rs +++ b/src/cp437_font.rs @@ -17,7 +17,7 @@ impl Cp437Font { impl Default for Cp437Font { fn default() -> Self { let mut bitmaps = - core::array::from_fn(|_| Bitmap::new(TILE_SIZE, TILE_SIZE)); + core::array::from_fn(|_| Bitmap::new(TILE_SIZE, TILE_SIZE).unwrap()); for (char_code, bitmap) in bitmaps.iter_mut().enumerate() { let bits = CP437_FONT_LINEAR[char_code]; diff --git a/src/gui.rs b/src/gui.rs index 315af42..e5f08d4 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,7 +1,6 @@ -use std::{sync::mpsc::Sender, sync::RwLock}; - use log::{info, warn}; use servicepoint::*; +use std::{sync::mpsc::Sender, sync::RwLock}; use winit::{ application::ApplicationHandler, dpi::LogicalSize, event::WindowEvent, event_loop::ActiveEventLoop, keyboard::KeyCode::KeyC, window::WindowId, diff --git a/src/main.rs b/src/main.rs index d124abe..7218896 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ fn main() { .expect("could not create event loop"); event_loop.set_control_flow(ControlFlow::Wait); - let display = RwLock::new(Bitmap::new(PIXEL_WIDTH, PIXEL_HEIGHT)); + let display = RwLock::new(Bitmap::max_sized()); let luma = RwLock::new(BrightnessGrid::new(TILE_WIDTH, TILE_HEIGHT)); let (stop_udp_tx, stop_udp_rx) = mpsc::channel(); let font_renderer = cli diff --git a/src/udp_server.rs b/src/udp_server.rs index 449ad84..7f35761 100644 --- a/src/udp_server.rs +++ b/src/udp_server.rs @@ -1,11 +1,12 @@ -use crate::command_executor::{CommandExecutor, ExecutionResult}; -use crate::gui::AppEvents; +use crate::{ + command_executor::{CommandExecutor, ExecutionResult}, + gui::AppEvents, +}; use log::{error, warn}; -use servicepoint::Command; -use std::io::ErrorKind; -use std::net::UdpSocket; -use std::sync::mpsc::Receiver; -use std::time::Duration; +use servicepoint::TypedCommand; +use std::{ + io::ErrorKind, net::UdpSocket, sync::mpsc::Receiver, time::Duration, +}; use winit::event_loop::EventLoopProxy; const BUF_SIZE: usize = 8985; @@ -65,13 +66,13 @@ impl<'t> UdpServer<'t> { } } - fn command_from_slice(slice: &[u8]) -> Option { + fn command_from_slice(slice: &[u8]) -> Option { let packet = servicepoint::Packet::try_from(slice) .inspect_err(|_| { warn!("could not load packet with length {}", slice.len()) }) .ok()?; - Command::try_from(packet) + TypedCommand::try_from(packet) .inspect_err(move |err| { warn!("could not read command for packet: {:?}", err) }) -- 2.47.0 From b307ee689bb08260e8dbb817b3cb009cac522df1 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 8 Mar 2025 15:45:20 +0100 Subject: [PATCH 2/4] split execution of commands --- src/command_executor.rs | 412 ++++++++++++++++++++-------------------- src/main.rs | 4 +- src/udp_server.rs | 12 +- 3 files changed, 215 insertions(+), 213 deletions(-) diff --git a/src/command_executor.rs b/src/command_executor.rs index 974d3b6..dd02ee9 100644 --- a/src/command_executor.rs +++ b/src/command_executor.rs @@ -5,10 +5,10 @@ use crate::{ }; use log::{debug, error, info, trace, warn}; use servicepoint::{ - BinaryOperation, BitVec, BitVecCommand, Bitmap, BitmapCommand, - BrightnessCommand, BrightnessGrid, BrightnessGridCommand, CharGrid, - CharGridCommand, Cp437Grid, Cp437GridCommand, Grid, Offset, Origin, Tiles, - TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, + BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, BrightnessCommand, + BrightnessGrid, BrightnessGridCommand, CharGridCommand, ClearCommand, + CompressionCode, Cp437GridCommand, FadeOutCommand, Grid, HardResetCommand, + Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, }; use std::{ ops::{BitAnd, BitOr, BitXor}, @@ -16,7 +16,7 @@ use std::{ }; #[derive(Debug)] -pub struct CommandExecutor<'t> { +pub struct CommandExecutionContext<'t> { display: &'t RwLock, luma: &'t RwLock, cp437_font: Cp437Font, @@ -30,210 +30,36 @@ pub enum ExecutionResult { Shutdown, } -impl<'t> CommandExecutor<'t> { - pub fn new( - display: &'t RwLock, - luma: &'t RwLock, - font_renderer: FontRenderer8x8, - ) -> Self { - CommandExecutor { - display, - luma, - font_renderer, - cp437_font: Cp437Font::default(), - } - } +pub trait CommandExecute { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult; +} - pub(crate) fn execute(&self, command: TypedCommand) -> ExecutionResult { - debug!("received {command:?}"); - match command { - TypedCommand::Clear(_) => { - info!("clearing display"); - self.display.write().unwrap().fill(false); - Success - } - TypedCommand::HardReset(_) => { - warn!("display shutting down"); - Shutdown - } - TypedCommand::Bitmap(BitmapCommand { - origin: Origin { x, y, .. }, - bitmap, - .. - }) => self.print_pixel_grid(x, y, &bitmap), - TypedCommand::Cp437Grid(Cp437GridCommand { origin, grid }) => { - self.print_cp437_data(origin, &grid) - } - #[allow(deprecated)] - TypedCommand::BitmapLegacy(_) => { - warn!("ignoring deprecated command {:?}", command); - Failure - } - TypedCommand::BitVec(command) => { - let BitVecCommand { - offset, - bitvec, - operation, - .. - } = command; - fn overwrite(_: bool, new: bool) -> bool { - new - } - let operation = match operation { - BinaryOperation::Overwrite => overwrite, - BinaryOperation::And => BitAnd::bitand, - BinaryOperation::Or => BitOr::bitor, - BinaryOperation::Xor => BitXor::bitxor, - }; - self.execute_bitmap_linear(offset, bitvec, operation) - } - TypedCommand::BrightnessGrid(BrightnessGridCommand { - origin, - grid, - }) => self.execute_char_brightness(origin, grid), - TypedCommand::Brightness(BrightnessCommand { brightness }) => { - self.luma.write().unwrap().fill(brightness); - Success - } - TypedCommand::FadeOut(_) => { - error!("command not implemented: {command:?}"); - Success - } - TypedCommand::CharGrid(CharGridCommand { origin, grid }) => { - self.print_utf8_data(origin, &grid) - } - } - } - - fn execute_char_brightness( - &self, - origin: Origin, - grid: BrightnessGrid, - ) -> ExecutionResult { - let mut luma = self.luma.write().unwrap(); - for inner_y in 0..grid.height() { - for inner_x in 0..grid.width() { - let brightness = grid.get(inner_x, inner_y); - luma.set(origin.x + inner_x, origin.y + inner_y, brightness); - } - } +impl CommandExecute for ClearCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + info!("clearing display"); + context.display.write().unwrap().fill(false); Success } +} - fn execute_bitmap_linear( - &self, - offset: Offset, - vec: BitVec, - op: Op, - ) -> ExecutionResult - where - Op: Fn(bool, bool) -> bool, - { - if !Self::check_bitmap_valid(offset as u16, vec.len()) { - return Failure; - } - let mut display = self.display.write().unwrap(); - for bitmap_index in 0..vec.len() { - let (x, y) = Self::get_coordinates_for_index(offset, bitmap_index); - let old_value = display.get(x, y); - display.set(x, y, op(old_value, vec[bitmap_index])); - } - Success - } - - fn check_bitmap_valid(offset: u16, payload_len: usize) -> bool { - if offset as usize + payload_len > PIXEL_COUNT { - error!( - "bitmap with offset {offset} is too big ({payload_len} bytes)" - ); - return false; - } - - true - } - - fn print_cp437_data( - &self, - origin: Origin, - grid: &Cp437Grid, - ) -> ExecutionResult { - let font = &self.cp437_font; - let Origin { x, y, .. } = origin; - for char_y in 0usize..grid.height() { - for char_x in 0usize..grid.width() { - let char_code = grid.get(char_x, char_y); - trace!( - "drawing char_code {char_code:#04x} (if this was UTF-8, it would be {})", - char::from(char_code) - ); - - let tile_x = char_x + x; - let tile_y = char_y + y; - - match self.print_pixel_grid( - tile_x * TILE_SIZE, - tile_y * TILE_SIZE, - &font[char_code], - ) { - Success => {} - Failure => { - error!( - "stopping drawing text because char draw failed" - ); - return Failure; - } - Shutdown => return Shutdown, - } - } - } - - Success - } - - fn print_utf8_data( - &self, - origin: Origin, - grid: &CharGrid, - ) -> ExecutionResult { - let mut display = self.display.write().unwrap(); - - let Origin { x, y, .. } = origin; - for char_y in 0usize..grid.height() { - for char_x in 0usize..grid.width() { - let char = grid.get(char_x, char_y); - trace!("drawing {char}"); - - let tile_x = char_x + x; - let tile_y = char_y + y; - - if let Err(e) = self.font_renderer.render( - char, - &mut display, - Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), - ) { - error!( - "stopping drawing text because char draw failed: {e}" - ); - return Failure; - } - } - } - - Success - } - - fn print_pixel_grid( - &self, - offset_x: usize, - offset_y: usize, - pixels: &Bitmap, - ) -> ExecutionResult { +impl CommandExecute for BitmapCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + let Self { + origin: + Origin { + x: offset_x, + y: offset_y, + .. + }, + bitmap: pixels, + .. + } = self; debug!( "printing {}x{} grid at {offset_x} {offset_y}", pixels.width(), pixels.height() ); - let mut display = self.display.write().unwrap(); + let mut display = context.display.write().unwrap(); for inner_y in 0..pixels.height() { for inner_x in 0..pixels.width() { let is_set = pixels.get(inner_x, inner_y); @@ -251,12 +77,186 @@ impl<'t> CommandExecutor<'t> { Success } +} - fn get_coordinates_for_index( - offset: usize, - index: usize, - ) -> (usize, usize) { - let pixel_index = offset + index; - (pixel_index % PIXEL_WIDTH, pixel_index / PIXEL_WIDTH) +impl CommandExecute for HardResetCommand { + fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { + warn!("display shutting down"); + Shutdown + } +} + +impl CommandExecute for BitVecCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + let BitVecCommand { + offset, + bitvec, + operation, + .. + } = self; + fn overwrite(_: bool, new: bool) -> bool { + new + } + let operation = match operation { + BinaryOperation::Overwrite => overwrite, + BinaryOperation::And => BitAnd::bitand, + BinaryOperation::Or => BitOr::bitor, + BinaryOperation::Xor => BitXor::bitxor, + }; + + if self.offset as usize + bitvec.len() > PIXEL_COUNT { + error!( + "bitmap with offset {offset} is too big ({} bytes)", + bitvec.len() + ); + return Failure; + } + + let mut display = context.display.write().unwrap(); + for bitmap_index in 0..bitvec.len() { + let pixel_index = offset + bitmap_index; + let (x, y) = (pixel_index % PIXEL_WIDTH, pixel_index / PIXEL_WIDTH); + let old_value = display.get(x, y); + display.set(x, y, operation(old_value, bitvec[bitmap_index])); + } + Success + } +} + +impl CommandExecute for Cp437GridCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + let Cp437GridCommand { origin, grid } = self; + let Origin { x, y, .. } = origin; + for char_y in 0usize..grid.height() { + for char_x in 0usize..grid.width() { + let char_code = grid.get(char_x, char_y); + trace!( + "drawing char_code {char_code:#04x} (if this was UTF-8, it would be {})", + char::from(char_code) + ); + + let tile_x = char_x + x; + let tile_y = char_y + y; + + let execute_result = BitmapCommand { + origin: Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), + bitmap: context.cp437_font[char_code].clone(), + compression: CompressionCode::default(), + } + .execute(context); + match execute_result { + Success => {} + Failure => { + error!( + "stopping drawing text because char draw failed" + ); + return Failure; + } + Shutdown => return Shutdown, + } + } + } + + Success + } +} + +#[allow(deprecated)] +impl CommandExecute for servicepoint::BitmapLegacyCommand { + fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { + warn!("ignoring deprecated command {:?}", self); + Failure + } +} + +impl CommandExecute for BrightnessGridCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + let BrightnessGridCommand { origin, grid } = self; + let mut luma = context.luma.write().unwrap(); + for inner_y in 0..grid.height() { + for inner_x in 0..grid.width() { + let brightness = grid.get(inner_x, inner_y); + luma.set(origin.x + inner_x, origin.y + inner_y, brightness); + } + } + Success + } +} + +impl CommandExecute for CharGridCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + let CharGridCommand { origin, grid } = self; + let mut display = context.display.write().unwrap(); + + let Origin { x, y, .. } = origin; + for char_y in 0usize..grid.height() { + for char_x in 0usize..grid.width() { + let char = grid.get(char_x, char_y); + trace!("drawing {char}"); + + let tile_x = char_x + x; + let tile_y = char_y + y; + + if let Err(e) = context.font_renderer.render( + char, + &mut display, + Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), + ) { + error!( + "stopping drawing text because char draw failed: {e}" + ); + return Failure; + } + } + } + + Success + } +} + +impl CommandExecute for BrightnessCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + context.luma.write().unwrap().fill(self.brightness); + Success + } +} + +impl CommandExecute for FadeOutCommand { + fn execute(&self, _: &CommandExecutionContext) -> ExecutionResult { + error!("command not implemented: {self:?}"); + Success + } +} + +impl CommandExecute for TypedCommand { + fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { + match self { + TypedCommand::Clear(command) => command.execute(context), + TypedCommand::HardReset(command) => command.execute(context), + TypedCommand::Bitmap(command) => command.execute(context), + TypedCommand::Cp437Grid(command) => command.execute(context), + #[allow(deprecated)] + TypedCommand::BitmapLegacy(command) => command.execute(context), + TypedCommand::BitVec(command) => command.execute(context), + TypedCommand::BrightnessGrid(command) => command.execute(context), + TypedCommand::Brightness(command) => command.execute(context), + TypedCommand::FadeOut(command) => command.execute(context), + TypedCommand::CharGrid(command) => command.execute(context), + } + } +} + +impl<'t> CommandExecutionContext<'t> { + pub fn new( + display: &'t RwLock, + luma: &'t RwLock, + font_renderer: FontRenderer8x8, + ) -> Self { + CommandExecutionContext { + display, + luma, + font_renderer, + cp437_font: Cp437Font::default(), + } } } diff --git a/src/main.rs b/src/main.rs index 7218896..dd7f3e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use crate::font_renderer::FontRenderer8x8; use crate::udp_server::UdpServer; -use crate::{command_executor::CommandExecutor, gui::Gui}; +use crate::{command_executor::CommandExecutionContext, gui::Gui}; use clap::Parser; use cli::Cli; use log::{info, LevelFilter}; @@ -39,7 +39,7 @@ fn main() { .font .map(FontRenderer8x8::from_name) .unwrap_or_else(FontRenderer8x8::default); - let command_executor = CommandExecutor::new(&display, &luma, font_renderer); + let command_executor = CommandExecutionContext::new(&display, &luma, font_renderer); let mut udp_server = UdpServer::new( cli.bind, stop_udp_rx, diff --git a/src/udp_server.rs b/src/udp_server.rs index 7f35761..b661067 100644 --- a/src/udp_server.rs +++ b/src/udp_server.rs @@ -1,8 +1,9 @@ +use crate::command_executor::CommandExecute; use crate::{ - command_executor::{CommandExecutor, ExecutionResult}, + command_executor::{CommandExecutionContext, ExecutionResult}, gui::AppEvents, }; -use log::{error, warn}; +use log::{debug, error, warn}; use servicepoint::TypedCommand; use std::{ io::ErrorKind, net::UdpSocket, sync::mpsc::Receiver, time::Duration, @@ -15,7 +16,7 @@ const BUF_SIZE: usize = 8985; pub struct UdpServer<'t> { socket: UdpSocket, stop_rx: Receiver<()>, - command_executor: CommandExecutor<'t>, + command_executor: CommandExecutionContext<'t>, app_events: EventLoopProxy, buf: [u8; BUF_SIZE], } @@ -24,7 +25,7 @@ impl<'t> UdpServer<'t> { pub fn new( bind: String, stop_rx: Receiver<()>, - command_executor: CommandExecutor<'t>, + command_executor: CommandExecutionContext<'t>, app_events: EventLoopProxy, ) -> Self { let socket = UdpSocket::bind(bind).expect("could not bind socket"); @@ -46,7 +47,8 @@ impl<'t> UdpServer<'t> { if let Some(cmd) = self.receive_into_buf().and_then(|amount| { Self::command_from_slice(&self.buf[..amount]) }) { - match self.command_executor.execute(cmd) { + debug!("received {cmd:?}"); + match cmd.execute(&self.command_executor) { ExecutionResult::Success => { self.app_events .send_event(AppEvents::UdpPacketHandled) -- 2.47.0 From e667c519cdcf73bb669f090311bfe65ec933388d Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 8 Mar 2025 16:16:46 +0100 Subject: [PATCH 3/4] add note to README about move --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4bc2af..a4886fa 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ Use cases: Uses the [servicepoint](https://github.com/cccb/servicepoint) library for reading the packets. The screenshot above shows the output of two example projects running in parallel (game_of_life and random_brightness). +This repository moved +to [git.berlin.ccc.de/servicepoint/servicepoint-simulator](https://git.berlin.ccc.de/servicepoint/servicepoint-simulator/). +The [GitHub repository](https://github.com/kaesaecracker/servicepoint-simulator) will remain as a mirror. + ## Running With cargo installed: `cargo install servicepoint-simulator` @@ -44,7 +48,8 @@ Options: See [env_logger](https://docs.rs/env_logger/latest/env_logger/) to configure logging. -Because this program renders to an RGB pixel buffer, you can enjoy the following additional features not available on the real display: +Because this program renders to an RGB pixel buffer, you can enjoy the following additional features not available on +the real display: - enable or disable the empty space between tile rows (`./servicepoint-simulator --spacers` to enable) - render pixels in red, green, blue or a combination of the three (`./servicepoint-simulator -rgb` for white pixels) @@ -64,6 +69,7 @@ All creatures welcome. ## Legal stuff -The included font is https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios (included in the download from https://int10h.org/oldschool-pc-fonts/download/). The font is CC BY-SA 4.0. +The included font is https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios (included in the download +from https://int10h.org/oldschool-pc-fonts/download/). The font is CC BY-SA 4.0. For everything else see the LICENSE file. -- 2.47.0 From abb0b64b7c7a9822c49772d21d3c92c805dfe322 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 8 Mar 2025 16:17:57 +0100 Subject: [PATCH 4/4] clippy --- src/command_executor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command_executor.rs b/src/command_executor.rs index dd02ee9..8ddeaab 100644 --- a/src/command_executor.rs +++ b/src/command_executor.rs @@ -104,7 +104,7 @@ impl CommandExecute for BitVecCommand { BinaryOperation::Xor => BitXor::bitxor, }; - if self.offset as usize + bitvec.len() > PIXEL_COUNT { + if self.offset + bitvec.len() > PIXEL_COUNT { error!( "bitmap with offset {offset} is too big ({} bytes)", bitvec.len() -- 2.47.0