Compare commits
2 Commits
jojo/impro
...
e4fe5472aa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4fe5472aa | ||
|
|
b92231a88b |
@@ -7,4 +7,6 @@ edition = "2021"
|
||||
address = "0.11.0"
|
||||
clap = { version = "4.5.23", features = ["derive"] }
|
||||
image = "0.25.5"
|
||||
io-uring = "0.7.3"
|
||||
libc = "0.2.169"
|
||||
tokio = "1.42.0"
|
||||
|
||||
BIN
breakwater.png
Normal file
BIN
breakwater.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
61
src/flutr.rs
61
src/flutr.rs
@@ -1,26 +1,67 @@
|
||||
use crate::pixelmsgs::PixelMsgs;
|
||||
use crate::pixelmsgs::PixelStringMsgs;
|
||||
use address::Host;
|
||||
use std::{io::Write, net::TcpStream};
|
||||
use io_uring::{opcode, types, IoUring, Submitter};
|
||||
use libc::c_void;
|
||||
use libc::iovec;
|
||||
use std::{io::Write, net::TcpStream, os::fd::AsRawFd};
|
||||
|
||||
pub struct FlutR {
|
||||
stream: TcpStream,
|
||||
msgs: PixelMsgs,
|
||||
stream_fd: i32,
|
||||
msgs: PixelStringMsgs,
|
||||
}
|
||||
|
||||
impl FlutR {
|
||||
pub fn new(host: Host, port: u16, msgs: PixelMsgs) -> Result<Self, std::io::Error> {
|
||||
pub fn new(host: Host, port: u16, msgs: PixelStringMsgs) -> Result<Self, std::io::Error> {
|
||||
let stream = TcpStream::connect(format!("{host}:{port}"))?;
|
||||
Ok(FlutR { stream, msgs })
|
||||
let stream_fd = stream.as_raw_fd();
|
||||
Ok(FlutR {
|
||||
stream,
|
||||
stream_fd,
|
||||
msgs,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn flut(&mut self) {
|
||||
for msg in self.msgs.clone() {
|
||||
let result = self.stream.write(&msg);
|
||||
match result {
|
||||
Ok(_) => (),
|
||||
Err(err) => eprintln!("{err}"),
|
||||
unsafe {
|
||||
self.write_io_uring();
|
||||
//self.write_sequential();
|
||||
}
|
||||
}
|
||||
|
||||
fn write_sequential(&mut self) {
|
||||
loop {
|
||||
for msg in self.msgs.clone() {
|
||||
let _ = self.stream.write(&msg);
|
||||
}
|
||||
let _ = self.stream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn write_io_uring(&mut self) {
|
||||
let mut ring = IoUring::new(8).unwrap();
|
||||
|
||||
let buffer_len: usize = self.msgs.len() * 11;
|
||||
let buffer: iovec = iovec {
|
||||
iov_base: self.msgs.as_mut_ptr() as *mut c_void,
|
||||
iov_len: buffer_len,
|
||||
};
|
||||
ring.submitter().register_buffers(&[buffer]);
|
||||
|
||||
let write_op = opcode::WriteFixed::new(
|
||||
io_uring::types::Fd(self.stream_fd),
|
||||
buffer.iov_base as *const u8,
|
||||
buffer_len as u32,
|
||||
0,
|
||||
)
|
||||
.build();
|
||||
|
||||
loop {
|
||||
while ring.submission().is_full() {
|
||||
ring.submission().sync();
|
||||
}
|
||||
ring.submission().push(&write_op).unwrap();
|
||||
ring.submit().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
pub mod flutr;
|
||||
@@ -5,11 +5,12 @@ use image::ImageReader;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
mod flutr;
|
||||
mod pixelmsgs;
|
||||
|
||||
use flutr::FlutR;
|
||||
use pixelmsgs::Add;
|
||||
use pixelmsgs::PixelMsgs;
|
||||
use pixelmsgs::PixelStringMsgs;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about, long_about = None)]
|
||||
@@ -30,9 +31,7 @@ fn main() {
|
||||
flutr.flut();
|
||||
}
|
||||
|
||||
fn parse_image_to_msgs(path: &PathBuf) -> PixelMsgs {
|
||||
let mut result = PixelMsgs::default();
|
||||
|
||||
fn parse_image_to_msgs(path: &PathBuf) -> PixelStringMsgs {
|
||||
let image_result = parse_image(path);
|
||||
|
||||
let image = match image_result {
|
||||
@@ -41,6 +40,7 @@ fn parse_image_to_msgs(path: &PathBuf) -> PixelMsgs {
|
||||
};
|
||||
|
||||
let rgb_image = image.into_rgb8();
|
||||
let mut result = PixelStringMsgs::with_capacity(rgb_image.len());
|
||||
for pixel in rgb_image.enumerate_pixels() {
|
||||
result.add(pixel);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use image::Rgb;
|
||||
|
||||
pub type PixelMsg = [u8; 10];
|
||||
pub type PixelMsgs = Vec<PixelMsg>;
|
||||
pub type PixelBinaryMsg = [u8; 11];
|
||||
pub type PixelBinaryMsgs = Vec<PixelBinaryMsg>;
|
||||
pub type PixelStringMsg = Box<[u8]>;
|
||||
pub type PixelStringMsgs = Vec<PixelStringMsg>;
|
||||
|
||||
pub trait Add {
|
||||
fn add(&mut self, item: (u32, u32, &Rgb<u8>));
|
||||
}
|
||||
|
||||
impl Add for PixelMsgs {
|
||||
impl Add for PixelBinaryMsgs {
|
||||
fn add(&mut self, item: (u32, u32, &Rgb<u8>)) {
|
||||
let pb: &[u8] = &[80, 66];
|
||||
let x = (item.0 as u16).to_le_bytes();
|
||||
@@ -22,3 +24,17 @@ impl Add for PixelMsgs {
|
||||
self.push(msg.try_into().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for PixelStringMsgs {
|
||||
fn add(&mut self, item: (u32, u32, &Rgb<u8>)) {
|
||||
let color: &Rgb<u8> = item.2;
|
||||
let r = color.0[0];
|
||||
let g = color.0[1];
|
||||
let b = color.0[2];
|
||||
let msg = format!("PX {} {} {r:02x}{g:02x}{b:02x}\n", item.0, item.1)
|
||||
.as_bytes()
|
||||
.to_vec()
|
||||
.into_boxed_slice();
|
||||
self.push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
use std::{
|
||||
net::TcpListener,
|
||||
io::Read,
|
||||
thread,
|
||||
};
|
||||
|
||||
use flutr::FlutR;
|
||||
|
||||
fn receive_bytes() -> [u8; 128]{
|
||||
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
|
||||
|
||||
let mut stream = listener.accept().unwrap().0;
|
||||
|
||||
let mut buf: [u8; 128] = [0; 128];
|
||||
stream.read(&mut buf).unwrap();
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let receive_thread = thread::spawn(move || {return receive_bytes();});
|
||||
|
||||
let flutr_server = Flutr::new();
|
||||
|
||||
|
||||
let buf = receive_thread.join();
|
||||
for x in buf.unwrap() {
|
||||
print!("{x}, ");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user