feat: basic client
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -149,6 +149,7 @@ dependencies = [
|
|||||||
"flatbuffers",
|
"flatbuffers",
|
||||||
"flexbuffers",
|
"flexbuffers",
|
||||||
"mint",
|
"mint",
|
||||||
|
"mio",
|
||||||
"nanoid",
|
"nanoid",
|
||||||
"schemas",
|
"schemas",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -347,6 +348,7 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
|||||||
name = "stardust-xr"
|
name = "stardust-xr"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"libstardustxr",
|
"libstardustxr",
|
||||||
"mio",
|
"mio",
|
||||||
"slab",
|
"slab",
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ version = "0.9.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libstardustxr = {path = "../libstardustxr-rs"}
|
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"
|
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 libstardustxr::server;
|
||||||
use mio::net::UnixListener;
|
use mio::net::UnixListener;
|
||||||
|
use mio::unix::pipe;
|
||||||
|
use mio::{Events, Interest, Poll, Token};
|
||||||
use slab::Slab;
|
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,
|
pub socket_path: String,
|
||||||
listener: UnixListener,
|
join_handle: Option<JoinHandle<Result<()>>>,
|
||||||
clients: Slab<Client<'a>>,
|
stop_write: pipe::Sender,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventLoop<'a> {
|
impl EventLoop {
|
||||||
pub fn new() -> Option<Self> {
|
pub fn new(timeout: Option<core::time::Duration>) -> Result<Self> {
|
||||||
let socket_path = server::get_free_socket_path()?;
|
let socket_path = server::get_free_socket_path()
|
||||||
Some(EventLoop {
|
.ok_or_else(|| std::io::Error::from(std::io::ErrorKind::Other))?;
|
||||||
listener: UnixListener::bind(socket_path.clone()).ok()?,
|
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,
|
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;
|
pub mod eventloop;
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ use self::core::eventloop::EventLoop;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Setting up Stardust socket...");
|
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);
|
println!("Stardust socket created at {}", event_loop.socket_path);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user