Compare commits
10 commits
05f047ec63
...
c7d324b3f4
| Author | SHA1 | Date | |
|---|---|---|---|
| c7d324b3f4 | |||
| 8f4acac7b3 | |||
| 8a903cd735 | |||
| c547773570 | |||
| a8b40e6101 | |||
|
|
9db094a774 | ||
|
|
453117d0bb | ||
| 132c87b0bf | |||
| ff458116b7 | |||
|
|
dd5ccf5502 |
10 changed files with 521 additions and 555 deletions
23
.github/workflows/build_nix.yml
vendored
23
.github/workflows/build_nix.yml
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
name: "build nix"
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
jobs:
|
|
||||||
check_flurry_package:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: nix flake check -L --all-systems
|
|
||||||
build_flurry_package:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: nix build -L
|
|
||||||
build_flurry_shell:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: nix shell -L --command echo 'it works'
|
|
||||||
45
.github/workflows/rust.yml
vendored
45
.github/workflows/rust.yml
vendored
|
|
@ -1,45 +0,0 @@
|
||||||
name: rust build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
name: cargo check
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: nightly
|
|
||||||
- run: cargo check
|
|
||||||
|
|
||||||
test:
|
|
||||||
name: cargo test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: check
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: nightly
|
|
||||||
- run: cargo test --features all
|
|
||||||
|
|
||||||
|
|
||||||
clippy:
|
|
||||||
name: Clippy
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
timeout-minutes: 45
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: nightly
|
|
||||||
components: clippy
|
|
||||||
- run: cargo clippy --features all --tests -- -Dclippy::all
|
|
||||||
26
.github/workflows/update.yml
vendored
26
.github/workflows/update.yml
vendored
|
|
@ -1,26 +0,0 @@
|
||||||
name: update dependencies
|
|
||||||
on:
|
|
||||||
workflow_dispatch: # allows manual triggering
|
|
||||||
schedule:
|
|
||||||
- cron: '0 4 * * *' # at 04:00 every day
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update:
|
|
||||||
name: Update dependencies
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: nix shell -L nixpkgs#cargo --command cargo update
|
|
||||||
- run: nix shell -L nixpkgs#git --command git add Cargo.lock
|
|
||||||
- name: Check flake
|
|
||||||
uses: DeterminateSystems/flake-checker-action@main
|
|
||||||
- run: nix build -L
|
|
||||||
- name: Update Nix Flake Lock
|
|
||||||
uses: DeterminateSystems/update-flake-lock@main
|
|
||||||
with:
|
|
||||||
pr-title: "flake: update flake.lock"
|
|
||||||
pr-labels: |
|
|
||||||
dependencies
|
|
||||||
automated
|
|
||||||
token: ${{ secrets.GH_TOKEN_FOR_UPDATES }}
|
|
||||||
917
Cargo.lock
generated
917
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
24
flake.lock
generated
24
flake.lock
generated
|
|
@ -3,11 +3,11 @@
|
||||||
"advisory-db": {
|
"advisory-db": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745915470,
|
"lastModified": 1758521157,
|
||||||
"narHash": "sha256-jmfA08xkDtjy9pT6YC5sL4iRtW4TlCSaURSaUnpc4/g=",
|
"narHash": "sha256-cDl1Qf/bTILEwq6DzMaTsrv6gWYZ47TO4sy7+NOA8Ok=",
|
||||||
"owner": "rustsec",
|
"owner": "rustsec",
|
||||||
"repo": "advisory-db",
|
"repo": "advisory-db",
|
||||||
"rev": "d63efe8c21f28b0690df6dc0a9879856bc0ffd88",
|
"rev": "fb0d06e8e2cc04c9aa359e51ffa0a09e3bf58822",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -34,11 +34,11 @@
|
||||||
},
|
},
|
||||||
"crane": {
|
"crane": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745454774,
|
"lastModified": 1758758545,
|
||||||
"narHash": "sha256-oLvmxOnsEKGtwczxp/CwhrfmQUG2ym24OMWowcoRhH8=",
|
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
|
||||||
"owner": "ipetkov",
|
"owner": "ipetkov",
|
||||||
"repo": "crane",
|
"repo": "crane",
|
||||||
"rev": "efd36682371678e2b6da3f108fdb5c613b3ec598",
|
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -70,11 +70,11 @@
|
||||||
"rust-analyzer-src": []
|
"rust-analyzer-src": []
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745908826,
|
"lastModified": 1758695884,
|
||||||
"narHash": "sha256-LNElDnQlQXiSGfJiPu4IJJ3PzHnoM31qEWElhz2VyH0=",
|
"narHash": "sha256-rnHjtBRkcwRkrUZxg0RqN1qWTG+QC/gj4vn9uzEkBww=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "fenix",
|
"repo": "fenix",
|
||||||
"rev": "6d93c0f68d080e6f5b42d2958708955c8ab8acd9",
|
"rev": "9cdb79384d02234fb2868eba6c7d390253ef6f83",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -145,11 +145,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1745900683,
|
"lastModified": 1758446476,
|
||||||
"narHash": "sha256-ZGi2gjgPtmPmplCVz7dNufqkBr00g6EeAloX3GrFQls=",
|
"narHash": "sha256-5rdAi7CTvM/kSs6fHe1bREIva5W3TbImsto+dxG4mBo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ffa0bb043c25cfc79ff3bc20ba2e44c3724499b1",
|
"rev": "a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ pub enum Color {
|
||||||
impl Display for Color {
|
impl Display for Color {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Color::RGB24(r, g, b) => write!(f, "#{:02X}{:02X}{:02X}FF", r, g, b),
|
Color::RGB24(r, g, b) => write!(f, "#{r:02X}{g:02X}{b:02X}FF"),
|
||||||
Color::RGBA32(r, g, b, a) => write!(f, "#{:02X}{:02X}{:02X}{:02X}", r, g, b, a),
|
Color::RGBA32(r, g, b, a) => write!(f, "#{r:02X}{g:02X}{b:02X}{a:02X}"),
|
||||||
Color::W8(w) => write!(f, "#{:02X}{:02X}{:02X}FF", w, w, w),
|
Color::W8(w) => write!(f, "#{w:02X}{w:02X}{w:02X}FF"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
src/grid.rs
25
src/grid.rs
|
|
@ -18,7 +18,7 @@ pub trait Grid<I, V> {
|
||||||
pub struct Flut<T> {
|
pub struct Flut<T> {
|
||||||
size_x: usize,
|
size_x: usize,
|
||||||
size_y: usize,
|
size_y: usize,
|
||||||
cells: SyncUnsafeCell<Vec<T>>,
|
cells: SyncUnsafeCell<Box<[T]>>,
|
||||||
last_hash: SyncUnsafeCell<u64>,
|
last_hash: SyncUnsafeCell<u64>,
|
||||||
jpgbuf: RwLock<Vec<u8>>,
|
jpgbuf: RwLock<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ impl<T: Clone> Flut<T> {
|
||||||
Flut {
|
Flut {
|
||||||
size_x,
|
size_x,
|
||||||
size_y,
|
size_y,
|
||||||
cells: vec.into(),
|
cells: vec.into_boxed_slice().into(),
|
||||||
last_hash: 0.into(),
|
last_hash: 0.into(),
|
||||||
jpgbuf: RwLock::new(Vec::new()),
|
jpgbuf: RwLock::new(Vec::new()),
|
||||||
}
|
}
|
||||||
|
|
@ -60,19 +60,19 @@ impl<T> Flut<T> {
|
||||||
impl<T> Grid<Coordinate, T> for Flut<T> {
|
impl<T> Grid<Coordinate, T> for Flut<T> {
|
||||||
fn get(&self, x: Coordinate, y: Coordinate) -> Option<&T> {
|
fn get(&self, x: Coordinate, y: Coordinate) -> Option<&T> {
|
||||||
self.index(x, y)
|
self.index(x, y)
|
||||||
.map(|idx| unsafe { &(*self.cells.get())[idx] })
|
.map(|idx| unsafe { &(&(*self.cells.get()))[idx] })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set(&self, x: Coordinate, y: Coordinate, value: T) {
|
fn set(&self, x: Coordinate, y: Coordinate, value: T) {
|
||||||
match self.index(x, y) {
|
match self.index(x, y) {
|
||||||
None => (),
|
None => (),
|
||||||
Some(idx) => unsafe { (*self.cells.get())[idx] = value },
|
Some(idx) => unsafe { (&mut (*self.cells.get()))[idx] = value },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_unchecked(&self, x: Coordinate, y: Coordinate) -> &T {
|
fn get_unchecked(&self, x: Coordinate, y: Coordinate) -> &T {
|
||||||
let idx = y as usize * self.size_x + x as usize;
|
let idx = y as usize * self.size_x + x as usize;
|
||||||
unsafe { &(*self.cells.get())[idx] }
|
unsafe { &(&(*self.cells.get()))[idx] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,7 +128,10 @@ mod tests {
|
||||||
async fn test_grid_init_values() {
|
async fn test_grid_init_values() {
|
||||||
let grid = Flut::init(3, 3, 0);
|
let grid = Flut::init(3, 3, 0);
|
||||||
|
|
||||||
assert_eq!(grid.cells.into_inner(), vec![0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
assert_eq!(
|
||||||
|
grid.cells.into_inner(),
|
||||||
|
vec![0, 0, 0, 0, 0, 0, 0, 0, 0].into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
@ -144,7 +147,10 @@ mod tests {
|
||||||
let grid = Flut::init(3, 3, 0);
|
let grid = Flut::init(3, 3, 0);
|
||||||
grid.set(1, 1, 255);
|
grid.set(1, 1, 255);
|
||||||
grid.set(2, 1, 256);
|
grid.set(2, 1, 256);
|
||||||
assert_eq!(grid.cells.into_inner(), vec![0, 0, 0, 0, 255, 256, 0, 0, 0]);
|
assert_eq!(
|
||||||
|
grid.cells.into_inner(),
|
||||||
|
vec![0, 0, 0, 0, 255, 256, 0, 0, 0].into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
@ -152,7 +158,10 @@ mod tests {
|
||||||
let grid = Flut::init(3, 3, 0);
|
let grid = Flut::init(3, 3, 0);
|
||||||
grid.set(1, 1, 255);
|
grid.set(1, 1, 255);
|
||||||
grid.set(3, 1, 256);
|
grid.set(3, 1, 256);
|
||||||
assert_eq!(grid.cells.into_inner(), vec![0, 0, 0, 0, 255, 0, 0, 0, 0]);
|
assert_eq!(
|
||||||
|
grid.cells.into_inner(),
|
||||||
|
vec![0, 0, 0, 0, 255, 0, 0, 0, 0].into()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
|
||||||
|
|
@ -113,12 +113,12 @@ To set a pixel using RGB, use ({SET_PX_RGB_BIN:02X}) (u8 canvas) (x as u16_le) (
|
||||||
match protocol {
|
match protocol {
|
||||||
crate::ProtocolStatus::Enabled(proto) => {
|
crate::ProtocolStatus::Enabled(proto) => {
|
||||||
writer
|
writer
|
||||||
.write_all(format!("Enabled: {}\n", proto).as_bytes())
|
.write_all(format!("Enabled: {proto}\n").as_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
crate::ProtocolStatus::Disabled(proto) => {
|
crate::ProtocolStatus::Disabled(proto) => {
|
||||||
writer
|
writer
|
||||||
.write_all(format!("Disabled: {}\n", proto).as_bytes())
|
.write_all(format!("Disabled: {proto}\n").as_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,12 +153,12 @@ impl<W: AsyncWriteExt + std::marker::Unpin> Responder<W> for TextParser {
|
||||||
match protocol {
|
match protocol {
|
||||||
crate::ProtocolStatus::Enabled(proto) => {
|
crate::ProtocolStatus::Enabled(proto) => {
|
||||||
writer
|
writer
|
||||||
.write_all(format!("Enabled: {}\n", proto).as_bytes())
|
.write_all(format!("Enabled: {proto}\n").as_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
crate::ProtocolStatus::Disabled(proto) => {
|
crate::ProtocolStatus::Disabled(proto) => {
|
||||||
writer
|
writer
|
||||||
.write_all(format!("Disabled: {}\n", proto).as_bytes())
|
.write_all(format!("Disabled: {proto}\n").as_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ fn make_image_stream(
|
||||||
fn make_stats() -> Message {
|
fn make_stats() -> Message {
|
||||||
let pixels: u64 = COUNTER.load(std::sync::atomic::Ordering::Relaxed);
|
let pixels: u64 = COUNTER.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
let clients: u64 = CLIENTS.load(std::sync::atomic::Ordering::Relaxed);
|
let clients: u64 = CLIENTS.load(std::sync::atomic::Ordering::Relaxed);
|
||||||
format!("{{\"c\":{}, \"p\":{}}}", clients, pixels).into()
|
format!("{{\"c\":{clients}, \"p\":{pixels}}}").into()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stats_stream(ws: WebSocketUpgrade) -> Response {
|
async fn stats_stream(ws: WebSocketUpgrade) -> Response {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue