Compare commits

...

8 commits

Author SHA1 Message Date
Vinzenz Schroeter 635fef0244 move command to module, first separate types
Some checks failed
Rust / build (pull_request) Failing after 1m20s
2025-06-13 11:47:23 +02:00
Vinzenz Schroeter cee4937270 move containers to module 2025-06-13 11:45:11 +02:00
Vinzenz Schroeter 27d71cefe6 update to nixos 25.05 2025-06-13 11:05:31 +02:00
Vinzenz Schroeter 8f03010944 update servicepoint, simplify copy_raw 2025-06-13 10:17:59 +02:00
Vinzenz Schroeter 7fe5ef07a8 add get set fill macro 2025-06-13 09:52:07 +02:00
Vinzenz Schroeter 0b3f243ffa add width and height macro 2025-06-13 01:27:57 +02:00
Vinzenz Schroeter fda2b9419d add clone to macro 2025-06-13 01:13:51 +02:00
Vinzenz Schroeter 88f7696dbd declare wrapper types with macro 2025-06-13 01:09:31 +02:00
20 changed files with 311 additions and 349 deletions

8
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "adler2"
@ -425,9 +425,9 @@ dependencies = [
[[package]]
name = "servicepoint"
version = "0.14.1"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6bd5cfa49c73aeecb344680ffbf697abf73e0563a441b93b9723ae43867500f"
checksum = "91a33bff7f9db5008748b23ca0c906c276fe00694390b681f004a55968a42cfe"
dependencies = [
"bitvec",
"bzip2",
@ -441,7 +441,7 @@ dependencies = [
[[package]]
name = "servicepoint_binding_uniffi"
version = "0.13.1"
version = "0.15.0"
dependencies = [
"servicepoint",
"thiserror 2.0.11",

View file

@ -1,6 +1,6 @@
[package]
name = "servicepoint_binding_uniffi"
version = "0.13.1"
version = "0.15.0"
publish = false
edition = "2021"
license = "GPL-3.0-or-later"
@ -21,7 +21,7 @@ uniffi = { version = "0.28.3" }
thiserror = "2.0"
[dependencies.servicepoint]
version = "0.14.1"
version = "0.15.0"
features = ["all_compressions"]
[package.metadata.docs.rs]

View file

@ -2,16 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1739357830,
"narHash": "sha256-9xim3nJJUFbVbJCz48UP4fGRStVW5nv4VdbimbKxJ3I=",
"lastModified": 1749494155,
"narHash": "sha256-FG4DEYBpROupu758beabUk9lhrblSf5hnv84v1TLqMc=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "0ff09db9d034a04acd4e8908820ba0b410d7a33a",
"rev": "88331c17ba434359491e8d5889cce872464052c2",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.11",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}

View file

@ -2,7 +2,7 @@
description = "Flake for the servicepoint library.";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
};
outputs =

View file

@ -1,77 +0,0 @@
use servicepoint::{DataRef, Grid};
use std::sync::{Arc, RwLock};
#[derive(uniffi::Object)]
pub struct Bitmap {
pub(crate) actual: RwLock<servicepoint::Bitmap>,
}
impl Bitmap {
fn internal_new(actual: servicepoint::Bitmap) -> Arc<Self> {
Arc::new(Self {
actual: RwLock::new(actual),
})
}
}
#[uniffi::export]
impl Bitmap {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(servicepoint::Bitmap::new(
width as usize,
height as usize,
).unwrap())
}
#[uniffi::constructor]
pub fn new_max_sized() -> Arc<Self> {
Self::internal_new(servicepoint::Bitmap::max_sized())
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(servicepoint::Bitmap::load(
width as usize,
height as usize,
&data,
).unwrap())
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
pub fn set(&self, x: u64, y: u64, value: bool) {
self.actual
.write()
.unwrap()
.set(x as usize, y as usize, value)
}
pub fn get(&self, x: u64, y: u64) -> bool {
self.actual.read().unwrap().get(x as usize, y as usize)
}
pub fn fill(&self, value: bool) {
self.actual.write().unwrap().fill(value)
}
pub fn width(&self) -> u64 {
self.actual.read().unwrap().width() as u64
}
pub fn height(&self) -> u64 {
self.actual.read().unwrap().height() as u64
}
pub fn equals(&self, other: &Bitmap) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual.read().unwrap().data_ref().to_vec()
}
}

19
src/brightness.rs Normal file
View file

@ -0,0 +1,19 @@
use crate::UniffiCustomTypeConverter;
use servicepoint::Brightness;
uniffi::custom_type!(Brightness, u8);
impl UniffiCustomTypeConverter for Brightness {
type Builtin = u8;
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self>
where
Self: Sized,
{
Ok(Brightness::saturating_from(val))
}
fn from_custom(obj: Self) -> Self::Builtin {
obj.into()
}
}

View file

@ -1,86 +0,0 @@
use servicepoint::{Brightness, DataRef, Grid};
use std::sync::{Arc, RwLock};
#[derive(uniffi::Object)]
pub struct BrightnessGrid {
pub(crate) actual: RwLock<servicepoint::BrightnessGrid>,
}
impl BrightnessGrid {
fn internal_new(actual: servicepoint::BrightnessGrid) -> Arc<Self> {
Arc::new(Self {
actual: RwLock::new(actual),
})
}
}
#[uniffi::export]
impl BrightnessGrid {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(servicepoint::BrightnessGrid::new(
width as usize,
height as usize,
))
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(servicepoint::BrightnessGrid::saturating_load(
width as usize,
height as usize,
&data,
).unwrap())
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
pub fn set(&self, x: u64, y: u64, value: u8) {
self.actual.write().unwrap().set(
x as usize,
y as usize,
Brightness::saturating_from(value),
)
}
pub fn get(&self, x: u64, y: u64) -> u8 {
self.actual
.read()
.unwrap()
.get(x as usize, y as usize)
.into()
}
pub fn fill(&self, value: u8) {
self.actual
.write()
.unwrap()
.fill(Brightness::saturating_from(value))
}
pub fn width(&self) -> u64 {
self.actual.read().unwrap().width() as u64
}
pub fn height(&self) -> u64 {
self.actual.read().unwrap().height() as u64
}
pub fn equals(&self, other: &BrightnessGrid) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual
.read()
.unwrap()
.data_ref()
.iter()
.map(u8::from)
.collect()
}
}

23
src/commands/cc_only.rs Normal file
View file

@ -0,0 +1,23 @@
use std::sync::Arc;
macro_rules! command_code_only_command {
($command_struct:ident) => {
#[derive(uniffi::Object)]
pub struct $command_struct;
#[uniffi::export]
impl $command_struct {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
const _: () =
assert!(size_of::<servicepoint::$command_struct>() == 0);
Arc::new($command_struct)
}
}
};
}
command_code_only_command!(ClearCommand);
command_code_only_command!(HardResetCommand);
command_code_only_command!(BitmapLegacyCommand);
command_code_only_command!(FadeOutCommand);

View file

@ -1,23 +1,20 @@
use crate::bitmap::Bitmap;
use crate::bitvec::BitVec;
use crate::brightness_grid::BrightnessGrid;
use crate::char_grid::CharGrid;
use crate::compression_code::CompressionCode;
use crate::cp437_grid::Cp437Grid;
use crate::errors::ServicePointError;
use servicepoint::{BitVecCommand, BrightnessGridCommand, CharGridCommand, ClearCommand, Cp437GridCommand, FadeOutCommand, GlobalBrightnessCommand, HardResetCommand, Origin};
use crate::{
compression_code::CompressionCode,
containers::{
bitmap::Bitmap, bitvec::BitVec, brightness_grid::BrightnessGrid,
char_grid::CharGrid, cp437_grid::Cp437Grid,
},
errors::ServicePointError,
macros::wrap_uniffi_object,
};
use servicepoint::{
BitVecCommand, BrightnessGridCommand, CharGridCommand, ClearCommand,
Cp437GridCommand, FadeOutCommand, GlobalBrightnessCommand,
HardResetCommand, Origin,
};
use std::sync::Arc;
#[derive(uniffi::Object)]
pub struct Command {
pub(crate) actual: servicepoint::TypedCommand,
}
impl Command {
fn internal_new(actual: servicepoint::TypedCommand) -> Arc<Command> {
Arc::new(Command { actual })
}
}
wrap_uniffi_object!(TypedCommand, Command);
#[uniffi::export]
impl Command {
@ -30,7 +27,7 @@ impl Command {
pub fn brightness(brightness: u8) -> Result<Arc<Self>, ServicePointError> {
servicepoint::Brightness::try_from(brightness)
.map_err(move |value| ServicePointError::InvalidBrightness {
value
value,
})
.map(GlobalBrightnessCommand::from)
.map(servicepoint::TypedCommand::Brightness)
@ -59,7 +56,9 @@ impl Command {
let actual = servicepoint::BitmapCommand {
origin,
bitmap,
compression: servicepoint::CompressionCode::try_from(compression as u16)
compression: servicepoint::CompressionCode::try_from(
compression as u16,
)
.unwrap(),
};
Self::internal_new(actual.into())
@ -73,7 +72,7 @@ impl Command {
) -> Arc<Self> {
let origin = Origin::new(offset_x as usize, offset_y as usize);
let grid = grid.actual.read().unwrap().clone();
let actual = BrightnessGridCommand {origin, grid};
let actual = BrightnessGridCommand { origin, grid };
Self::internal_new(actual.into())
}
@ -88,14 +87,18 @@ impl Command {
let actual = BitVecCommand {
offset: offset as usize,
bitvec,
compression: servicepoint::CompressionCode::try_from(compression as u16)
compression: servicepoint::CompressionCode::try_from(
compression as u16,
)
.unwrap(),
operation: match operation {
BinaryOperation::Overwrite => servicepoint::BinaryOperation::Overwrite,
BinaryOperation::Overwrite => {
servicepoint::BinaryOperation::Overwrite
}
BinaryOperation::And => servicepoint::BinaryOperation::And,
BinaryOperation::Or => servicepoint::BinaryOperation::Or,
BinaryOperation::Xor => servicepoint::BinaryOperation::Xor,
}
},
};
Self::internal_new(actual.into())
}
@ -108,7 +111,7 @@ impl Command {
) -> Arc<Self> {
let origin = Origin::new(offset_x as usize, offset_y as usize);
let grid = grid.actual.read().unwrap().clone();
let actual = Cp437GridCommand {origin, grid};
let actual = Cp437GridCommand { origin, grid };
Self::internal_new(actual.into())
}
@ -120,17 +123,12 @@ impl Command {
) -> Arc<Self> {
let origin = Origin::new(offset_x as usize, offset_y as usize);
let grid = grid.actual.read().unwrap().clone();
let actual = CharGridCommand {origin, grid};
let actual = CharGridCommand { origin, grid };
Self::internal_new(actual.into())
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.clone())
}
pub fn equals(&self, other: &Command) -> bool {
self.actual == other.actual
*self.actual.read().unwrap() == *other.actual.read().unwrap()
}
}

3
src/commands/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod command;
pub mod cc_only;

View file

@ -1,12 +1,6 @@
use std::{
net::UdpSocket,
sync::Arc
};
use crate::{commands::command::Command, errors::ServicePointError};
use servicepoint::UdpSocketExt;
use crate::{
command::Command,
errors::ServicePointError
};
use std::{net::UdpSocket, sync::Arc};
#[derive(uniffi::Object)]
pub struct Connection {
@ -25,10 +19,10 @@ impl Connection {
}
pub fn send(&self, command: Arc<Command>) -> Result<(), ServicePointError> {
self.actual.send_command(command.actual.clone()).ok_or_else(|| {
ServicePointError::IoError {
self.actual
.send_command(command.actual.read().unwrap().clone())
.ok_or_else(|| ServicePointError::IoError {
error: "send failed".to_string(),
}
})
}
}

40
src/containers/bitmap.rs Normal file
View file

@ -0,0 +1,40 @@
use crate::macros::*;
use servicepoint::Grid;
use std::{ops::Deref, sync::Arc};
wrap_uniffi_object!(Bitmap);
wrap_width_height!(Bitmap);
wrap_get_set_fill_2d!(Bitmap, bool);
#[uniffi::export]
impl Bitmap {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(
servicepoint::Bitmap::new(width as usize, height as usize).unwrap(),
)
}
#[uniffi::constructor]
pub fn new_max_sized() -> Arc<Self> {
Self::internal_new(servicepoint::Bitmap::max_sized())
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(
servicepoint::Bitmap::load(width as usize, height as usize, &data)
.unwrap(),
)
}
pub fn equals(&self, other: &Bitmap) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual.read().unwrap().deref().into()
}
}

View file

@ -1,34 +1,22 @@
use std::sync::{Arc, RwLock};
use crate::macros::wrap_uniffi_object;
use std::sync::Arc;
#[derive(uniffi::Object)]
pub struct BitVec {
pub(crate) actual: RwLock<servicepoint::DisplayBitVec>,
}
impl BitVec {
fn internal_new(actual: servicepoint::DisplayBitVec) -> Arc<Self> {
Arc::new(Self {
actual: RwLock::new(actual),
})
}
}
wrap_uniffi_object!(DisplayBitVec, BitVec);
#[uniffi::export]
impl BitVec {
#[uniffi::constructor]
pub fn new(size: u64) -> Arc<Self> {
Self::internal_new(servicepoint::DisplayBitVec::repeat(false, size as usize))
Self::internal_new(servicepoint::DisplayBitVec::repeat(
false,
size as usize,
))
}
#[uniffi::constructor]
pub fn load(data: Vec<u8>) -> Arc<Self> {
Self::internal_new(servicepoint::DisplayBitVec::from_slice(&data))
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
pub fn set(&self, index: u64, value: bool) {
self.actual.write().unwrap().set(index as usize, value)
}

View file

@ -0,0 +1,40 @@
use crate::macros::*;
use servicepoint::{Brightness, Grid};
use std::{ops::Deref, sync::Arc};
wrap_uniffi_object!(BrightnessGrid);
wrap_width_height!(BrightnessGrid);
wrap_get_set_fill_2d!(BrightnessGrid, Brightness);
#[uniffi::export]
impl BrightnessGrid {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(servicepoint::BrightnessGrid::new(
width as usize,
height as usize,
))
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(
servicepoint::BrightnessGrid::saturating_load(
width as usize,
height as usize,
&data,
)
.unwrap(),
)
}
pub fn equals(&self, other: &BrightnessGrid) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual.read().unwrap().deref().into()
}
}

View file

@ -1,12 +1,9 @@
use crate::cp437_grid::Cp437Grid;
use crate::{containers::cp437_grid::Cp437Grid, macros::*};
use servicepoint::{Grid, SetValueSeriesError};
use std::convert::Into;
use std::sync::{Arc, RwLock};
use std::{convert::Into, sync::Arc};
#[derive(uniffi::Object)]
pub struct CharGrid {
pub(crate) actual: RwLock<servicepoint::CharGrid>,
}
wrap_uniffi_object!(CharGrid);
wrap_width_height!(CharGrid);
#[derive(uniffi::Error, thiserror::Error, Debug)]
pub enum CharGridError {
@ -33,11 +30,6 @@ impl CharGrid {
Self::internal_new(servicepoint::CharGrid::from(&*data))
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
pub fn set(
&self,
x: u64,
@ -66,14 +58,6 @@ impl CharGrid {
Ok(())
}
pub fn width(&self) -> u64 {
self.actual.read().unwrap().width() as u64
}
pub fn height(&self) -> u64 {
self.actual.read().unwrap().height() as u64
}
pub fn equals(&self, other: &CharGrid) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
@ -133,12 +117,6 @@ impl CharGrid {
}
impl CharGrid {
pub(crate) fn internal_new(actual: servicepoint::CharGrid) -> Arc<Self> {
Arc::new(Self {
actual: RwLock::new(actual),
})
}
fn str_to_char(value: String) -> Result<char, CharGridError> {
if value.len() != 1 {
return Err(CharGridError::StringNotOneChar { value });

View file

@ -0,0 +1,46 @@
use crate::{containers::char_grid::CharGrid, macros::*};
use servicepoint::Grid;
use std::{ops::Deref, sync::Arc};
wrap_uniffi_object!(Cp437Grid);
wrap_width_height!(Cp437Grid);
wrap_get_set_fill_2d!(Cp437Grid, u8);
#[uniffi::export]
impl Cp437Grid {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(servicepoint::Cp437Grid::new(
width as usize,
height as usize,
))
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(
servicepoint::Cp437Grid::load(
width as usize,
height as usize,
&data,
)
.unwrap(),
)
}
pub fn equals(&self, other: &Cp437Grid) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual.read().unwrap().deref().into()
}
pub fn to_utf8(&self) -> Arc<CharGrid> {
CharGrid::internal_new(servicepoint::CharGrid::from(
&*self.actual.read().unwrap(),
))
}
}

5
src/containers/mod.rs Normal file
View file

@ -0,0 +1,5 @@
pub mod bitmap;
pub mod bitvec;
pub mod brightness_grid;
pub mod char_grid;
pub mod cp437_grid;

View file

@ -1,79 +0,0 @@
use crate::char_grid::CharGrid;
use servicepoint::{DataRef, Grid};
use std::sync::{Arc, RwLock};
#[derive(uniffi::Object)]
pub struct Cp437Grid {
pub(crate) actual: RwLock<servicepoint::Cp437Grid>,
}
impl Cp437Grid {
pub(crate) fn internal_new(actual: servicepoint::Cp437Grid) -> Arc<Self> {
Arc::new(Self {
actual: RwLock::new(actual),
})
}
}
#[uniffi::export]
impl Cp437Grid {
#[uniffi::constructor]
pub fn new(width: u64, height: u64) -> Arc<Self> {
Self::internal_new(servicepoint::Cp437Grid::new(
width as usize,
height as usize,
))
}
#[uniffi::constructor]
pub fn load(width: u64, height: u64, data: Vec<u8>) -> Arc<Self> {
Self::internal_new(servicepoint::Cp437Grid::load(
width as usize,
height as usize,
&data,
).unwrap())
}
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
pub fn set(&self, x: u64, y: u64, value: u8) {
self.actual
.write()
.unwrap()
.set(x as usize, y as usize, value)
}
pub fn get(&self, x: u64, y: u64) -> u8 {
self.actual.read().unwrap().get(x as usize, y as usize)
}
pub fn fill(&self, value: u8) {
self.actual.write().unwrap().fill(value)
}
pub fn width(&self) -> u64 {
self.actual.read().unwrap().width() as u64
}
pub fn height(&self) -> u64 {
self.actual.read().unwrap().height() as u64
}
pub fn equals(&self, other: &Cp437Grid) -> bool {
let a = self.actual.read().unwrap();
let b = other.actual.read().unwrap();
*a == *b
}
pub fn copy_raw(&self) -> Vec<u8> {
self.actual.read().unwrap().data_ref().to_vec()
}
pub fn to_utf8(&self) -> Arc<CharGrid> {
CharGrid::internal_new(servicepoint::CharGrid::from(
&*self.actual.read().unwrap(),
))
}
}

View file

@ -1,12 +1,10 @@
uniffi::setup_scaffolding!();
mod bitmap;
mod bitvec;
mod brightness_grid;
mod char_grid;
mod command;
mod brightness;
mod commands;
mod compression_code;
mod connection;
mod constants;
mod cp437_grid;
mod containers;
mod errors;
mod macros;

72
src/macros.rs Normal file
View file

@ -0,0 +1,72 @@
macro_rules! wrap_uniffi_object {
($orig_t:ident, $new_t:ident) => {
#[derive(uniffi::Object)]
pub struct $new_t {
pub(crate) actual: std::sync::RwLock<servicepoint::$orig_t>,
}
impl $new_t {
pub(crate) fn internal_new(
actual: servicepoint::$orig_t,
) -> Arc<Self> {
Arc::new(Self {
actual: std::sync::RwLock::new(actual),
})
}
}
#[uniffi::export]
impl $new_t {
#[uniffi::constructor]
pub fn clone(other: &Arc<Self>) -> Arc<Self> {
Self::internal_new(other.actual.read().unwrap().clone())
}
}
};
($t:ident) => {
wrap_uniffi_object!($t, $t);
};
}
pub(crate) use wrap_uniffi_object;
macro_rules! wrap_width_height {
($t:ident) => {
#[uniffi::export]
impl $t {
pub fn width(&self) -> u64 {
self.actual.read().unwrap().width() as u64
}
pub fn height(&self) -> u64 {
self.actual.read().unwrap().height() as u64
}
}
};
}
pub(crate) use wrap_width_height;
macro_rules! wrap_get_set_fill_2d {
($t:ident, $contained:ident) => {
#[uniffi::export]
impl $t {
pub fn set(&self, x: u64, y: u64, value: $contained) {
self.actual
.write()
.unwrap()
.set(x as usize, y as usize, value)
}
pub fn get(&self, x: u64, y: u64) -> $contained {
self.actual.read().unwrap().get(x as usize, y as usize)
}
pub fn fill(&self, value: $contained) {
self.actual.write().unwrap().fill(value)
}
}
};
}
pub(crate) use wrap_get_set_fill_2d;