feat: basic client
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -149,6 +149,7 @@ dependencies = [
|
||||
"flatbuffers",
|
||||
"flexbuffers",
|
||||
"mint",
|
||||
"mio",
|
||||
"nanoid",
|
||||
"schemas",
|
||||
"thiserror",
|
||||
@@ -347,6 +348,7 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
name = "stardust-xr"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libstardustxr",
|
||||
"mio",
|
||||
"slab",
|
||||
|
||||
@@ -7,5 +7,6 @@ version = "0.9.0"
|
||||
|
||||
[dependencies]
|
||||
libstardustxr = {path = "../libstardustxr-rs"}
|
||||
mio = {version = "0.8.3", features = ["net", "os-poll"]}
|
||||
anyhow = "1.0.57"
|
||||
mio = {version = "0.8.3", features = ["net", "os-poll", "os-ext"]}
|
||||
slab = "0.4.6"
|
||||
25
src/core/client.rs
Normal file
25
src/core/client.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use libstardustxr::fusion::scenegraph::Scenegraph;
|
||||
use libstardustxr::messenger::Messenger;
|
||||
use mio::net::UnixStream;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
pub struct Client<'a> {
|
||||
pub messenger: Rc<Messenger<'a>>,
|
||||
pub scenegraph: Scenegraph<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Client<'a> {
|
||||
pub fn from_connection(connection: UnixStream) -> Self {
|
||||
Client {
|
||||
scenegraph: Scenegraph::new(),
|
||||
messenger: Rc::new(Messenger::new(connection)),
|
||||
}
|
||||
}
|
||||
pub fn dispatch(&self) -> Result<(), std::io::Error> {
|
||||
self.messenger.dispatch(&self.scenegraph)
|
||||
}
|
||||
|
||||
pub fn get_weak_messenger(&self) -> Weak<Messenger<'a>> {
|
||||
Rc::downgrade(&self.messenger)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,81 @@
|
||||
use libstardustxr::fusion::client::Client;
|
||||
use super::client::Client;
|
||||
use libstardustxr::server;
|
||||
use mio::net::UnixListener;
|
||||
use mio::unix::pipe;
|
||||
use mio::{Events, Interest, Poll, Token};
|
||||
use slab::Slab;
|
||||
use std::io::Write;
|
||||
use std::thread::{self, JoinHandle};
|
||||
|
||||
pub struct EventLoop<'a> {
|
||||
use anyhow::Result;
|
||||
|
||||
pub struct EventLoop {
|
||||
pub socket_path: String,
|
||||
listener: UnixListener,
|
||||
clients: Slab<Client<'a>>,
|
||||
join_handle: Option<JoinHandle<Result<()>>>,
|
||||
stop_write: pipe::Sender,
|
||||
}
|
||||
|
||||
impl<'a> EventLoop<'a> {
|
||||
pub fn new() -> Option<Self> {
|
||||
let socket_path = server::get_free_socket_path()?;
|
||||
Some(EventLoop {
|
||||
listener: UnixListener::bind(socket_path.clone()).ok()?,
|
||||
impl EventLoop {
|
||||
pub fn new(timeout: Option<core::time::Duration>) -> Result<Self> {
|
||||
let socket_path = server::get_free_socket_path()
|
||||
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?;
|
||||
let mut socket = UnixListener::bind(socket_path.clone())?;
|
||||
let (sender, mut receiver) = pipe::new()?;
|
||||
let join_handle = Some(thread::spawn(move || -> Result<()> {
|
||||
let mut clients: Slab<Client> = Slab::new();
|
||||
let mut poll = Poll::new()?;
|
||||
let mut events = Events::with_capacity(1024);
|
||||
const LISTENER: Token = Token(usize::MAX - 1);
|
||||
poll.registry()
|
||||
.register(&mut socket, LISTENER, Interest::READABLE)?;
|
||||
const STOP: Token = Token(usize::MAX);
|
||||
poll.registry()
|
||||
.register(&mut receiver, STOP, Interest::READABLE)?;
|
||||
loop {
|
||||
poll.poll(&mut events, timeout)?;
|
||||
for event in &events {
|
||||
match event.token() {
|
||||
LISTENER => loop {
|
||||
match socket.accept() {
|
||||
Ok((socket, _)) => {
|
||||
clients.insert(Client::from_connection(socket));
|
||||
}
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::WouldBlock {
|
||||
break;
|
||||
}
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
},
|
||||
STOP => return Ok(()),
|
||||
token => loop {
|
||||
match clients.get(token.0).unwrap().dispatch() {
|
||||
Ok(_) => continue,
|
||||
Err(e) => {
|
||||
if e.kind() == std::io::ErrorKind::WouldBlock {
|
||||
break;
|
||||
}
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
Ok(EventLoop {
|
||||
socket_path,
|
||||
clients: Slab::new(),
|
||||
join_handle,
|
||||
stop_write: sender,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EventLoop {
|
||||
fn drop(&mut self) {
|
||||
let buf: [u8; 1] = [1; 1];
|
||||
let _ = self.stop_write.write(buf.as_slice());
|
||||
let _ = self.join_handle.take().unwrap().join();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod client;
|
||||
pub mod eventloop;
|
||||
|
||||
@@ -3,6 +3,6 @@ use self::core::eventloop::EventLoop;
|
||||
|
||||
fn main() {
|
||||
println!("Setting up Stardust socket...");
|
||||
let event_loop = EventLoop::new().expect("Couldn't create server socket");
|
||||
let event_loop = EventLoop::new(None).expect("Couldn't create server socket");
|
||||
println!("Stardust socket created at {}", event_loop.socket_path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user