autocommit 2022-01-06 19:08:32 CET
This commit is contained in:
parent
cbbc41a463
commit
4a939477a2
51 changed files with 3438 additions and 207 deletions
|
|
@ -1,10 +1,13 @@
|
|||
use crate::async_engine::{AsyncError, AsyncFd, SpawnedFuture};
|
||||
use crate::client::objects::Objects;
|
||||
use crate::ifs::wl_buffer::{WlBuffer, WlBufferError, WlBufferId};
|
||||
use crate::ifs::wl_callback::WlCallback;
|
||||
use crate::ifs::wl_compositor::{WlCompositorError, WlCompositorObj};
|
||||
use crate::ifs::wl_display::{WlDisplay, WlDisplayError};
|
||||
use crate::ifs::wl_output::{WlOutputError, WlOutputObj};
|
||||
use crate::ifs::wl_region::{WlRegion, WlRegionError, WlRegionId};
|
||||
use crate::ifs::wl_registry::{WlRegistry, WlRegistryError, WlRegistryId};
|
||||
use crate::ifs::wl_seat::{WlSeatError, WlSeatObj};
|
||||
use crate::ifs::wl_shm::{WlShmError, WlShmObj};
|
||||
use crate::ifs::wl_shm_pool::{WlShmPool, WlShmPoolError};
|
||||
use crate::ifs::wl_subcompositor::{WlSubcompositorError, WlSubcompositorObj};
|
||||
|
|
@ -30,7 +33,6 @@ use std::mem;
|
|||
use std::rc::Rc;
|
||||
use thiserror::Error;
|
||||
use uapi::OwnedFd;
|
||||
use crate::ifs::wl_buffer::{WlBuffer, WlBufferError};
|
||||
|
||||
mod objects;
|
||||
mod tasks;
|
||||
|
|
@ -57,6 +59,8 @@ pub enum ClientError {
|
|||
ClientDoesNotExist(ClientId),
|
||||
#[error("There is no wl_region with id {0}")]
|
||||
RegionDoesNotExist(WlRegionId),
|
||||
#[error("There is no wl_buffer with id {0}")]
|
||||
BufferDoesNotExist(WlBufferId),
|
||||
#[error("There is no wl_surface with id {0}")]
|
||||
SurfaceDoesNotExist(WlSurfaceId),
|
||||
#[error("There is no xdg_surface with id {0}")]
|
||||
|
|
@ -105,6 +109,10 @@ pub enum ClientError {
|
|||
XdgWmBaseError(#[source] Box<XdgWmBaseError>),
|
||||
#[error("An error occurred in a `wl_buffer`")]
|
||||
WlBufferError(#[source] Box<WlBufferError>),
|
||||
#[error("An error occurred in a `wl_output`")]
|
||||
WlOutputError(#[source] Box<WlOutputError>),
|
||||
#[error("An error occurred in a `wl_seat`")]
|
||||
WlSeatError(#[source] Box<WlSeatError>),
|
||||
#[error("Object {0} is not a display")]
|
||||
NotADisplay(ObjectId),
|
||||
}
|
||||
|
|
@ -125,6 +133,8 @@ efrom!(ClientError, XdgWmBaseError, XdgWmBaseError);
|
|||
efrom!(ClientError, XdgToplevelError, XdgToplevelError);
|
||||
efrom!(ClientError, XdgPopupError, XdgPopupError);
|
||||
efrom!(ClientError, WlBufferError, WlBufferError);
|
||||
efrom!(ClientError, WlOutputError, WlOutputError);
|
||||
efrom!(ClientError, WlSeatError, WlSeatError);
|
||||
|
||||
impl ClientError {
|
||||
fn peer_closed(&self) -> bool {
|
||||
|
|
@ -146,7 +156,7 @@ impl Display for ClientId {
|
|||
|
||||
pub struct Clients {
|
||||
next_client_id: NumCell<u64>,
|
||||
clients: RefCell<AHashMap<ClientId, ClientHolder>>,
|
||||
pub clients: RefCell<AHashMap<ClientId, ClientHolder>>,
|
||||
shutdown_clients: RefCell<AHashMap<ClientId, ClientHolder>>,
|
||||
}
|
||||
|
||||
|
|
@ -186,6 +196,7 @@ impl Clients {
|
|||
events: AsyncQueue::new(),
|
||||
shutdown: Cell::new(Some(send)),
|
||||
shutdown_sent: Cell::new(false),
|
||||
dispatch_frame_requests: AsyncQueue::new(),
|
||||
});
|
||||
let display = Rc::new(WlDisplay::new(&data));
|
||||
*data.objects.display.borrow_mut() = Some(display.clone());
|
||||
|
|
@ -234,14 +245,16 @@ impl Drop for Clients {
|
|||
}
|
||||
}
|
||||
|
||||
struct ClientHolder {
|
||||
data: Rc<Client>,
|
||||
pub struct ClientHolder {
|
||||
pub data: Rc<Client>,
|
||||
_handler: SpawnedFuture<()>,
|
||||
}
|
||||
|
||||
impl Drop for ClientHolder {
|
||||
fn drop(&mut self) {
|
||||
self.data.objects.destroy();
|
||||
self.data.events.clear();
|
||||
self.data.dispatch_frame_requests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +269,7 @@ pub trait RequestParser<'a>: Debug + Sized {
|
|||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError>;
|
||||
}
|
||||
|
||||
enum WlEvent {
|
||||
pub enum WlEvent {
|
||||
Flush,
|
||||
Shutdown,
|
||||
Event(Box<dyn EventFormatter>),
|
||||
|
|
@ -266,10 +279,11 @@ pub struct Client {
|
|||
pub id: ClientId,
|
||||
pub state: Rc<State>,
|
||||
socket: AsyncFd,
|
||||
objects: Objects,
|
||||
pub objects: Objects,
|
||||
events: AsyncQueue<WlEvent>,
|
||||
shutdown: Cell<Option<OneshotTx<()>>>,
|
||||
shutdown_sent: Cell<bool>,
|
||||
pub dispatch_frame_requests: AsyncQueue<Rc<WlCallback>>,
|
||||
}
|
||||
|
||||
const MAX_PENDING_EVENTS: usize = 100;
|
||||
|
|
@ -342,11 +356,20 @@ impl Client {
|
|||
self.event2(WlEvent::Event(event)).await
|
||||
}
|
||||
|
||||
pub async fn flush(&self) -> Result<(), ClientError> {
|
||||
self.event2(WlEvent::Flush).await
|
||||
}
|
||||
|
||||
async fn event2(&self, event: WlEvent) -> Result<(), ClientError> {
|
||||
self.events.push(event);
|
||||
self.check_queue_size().await
|
||||
}
|
||||
|
||||
pub fn event2_locked(&self, event: WlEvent) -> bool {
|
||||
self.events.push(event);
|
||||
self.events.size() > MAX_PENDING_EVENTS
|
||||
}
|
||||
|
||||
pub async fn check_queue_size(&self) -> Result<(), ClientError> {
|
||||
if self.events.size() > MAX_PENDING_EVENTS {
|
||||
self.state.eng.yield_now().await;
|
||||
|
|
@ -359,6 +382,13 @@ impl Client {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_buffer(&self, id: WlBufferId) -> Result<Rc<WlBuffer>, ClientError> {
|
||||
match self.objects.buffers.get(&id) {
|
||||
Some(r) => Ok(r),
|
||||
_ => Err(ClientError::BufferDoesNotExist(id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_region(&self, id: WlRegionId) -> Result<Rc<WlRegion>, ClientError> {
|
||||
match self.objects.regions.get(&id) {
|
||||
Some(r) => Ok(r),
|
||||
|
|
@ -453,7 +483,8 @@ simple_add_obj!(WlSubsurface);
|
|||
simple_add_obj!(XdgPositioner);
|
||||
simple_add_obj!(XdgToplevel);
|
||||
simple_add_obj!(XdgPopup);
|
||||
simple_add_obj!(WlBuffer);
|
||||
simple_add_obj!(WlOutputObj);
|
||||
simple_add_obj!(WlSeatObj);
|
||||
|
||||
macro_rules! dedicated_add_obj {
|
||||
($ty:ty, $field:ident) => {
|
||||
|
|
@ -477,3 +508,4 @@ dedicated_add_obj!(WlRegion, regions);
|
|||
dedicated_add_obj!(WlSurface, surfaces);
|
||||
dedicated_add_obj!(XdgWmBaseObj, xdg_wm_bases);
|
||||
dedicated_add_obj!(XdgSurface, xdg_surfaces);
|
||||
dedicated_add_obj!(WlBuffer, buffers);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::client::{Client, ClientError};
|
||||
use crate::ifs::wl_buffer::{WlBuffer, WlBufferId};
|
||||
use crate::ifs::wl_display::WlDisplay;
|
||||
use crate::ifs::wl_region::{WlRegion, WlRegionId};
|
||||
use crate::ifs::wl_registry::{WlRegistry, WlRegistryId};
|
||||
|
|
@ -19,6 +20,7 @@ pub struct Objects {
|
|||
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
||||
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
|
||||
pub regions: CopyHashMap<WlRegionId, Rc<WlRegion>>,
|
||||
pub buffers: CopyHashMap<WlBufferId, Rc<WlBuffer>>,
|
||||
pub xdg_wm_bases: CopyHashMap<XdgWmBaseId, Rc<XdgWmBaseObj>>,
|
||||
ids: RefCell<Vec<usize>>,
|
||||
}
|
||||
|
|
@ -35,6 +37,7 @@ impl Objects {
|
|||
surfaces: Default::default(),
|
||||
xdg_surfaces: Default::default(),
|
||||
regions: Default::default(),
|
||||
buffers: Default::default(),
|
||||
xdg_wm_bases: Default::default(),
|
||||
ids: RefCell::new(vec![]),
|
||||
}
|
||||
|
|
@ -54,6 +57,7 @@ impl Objects {
|
|||
self.surfaces.clear();
|
||||
self.xdg_wm_bases.clear();
|
||||
self.xdg_surfaces.clear();
|
||||
self.buffers.clear();
|
||||
}
|
||||
|
||||
fn id<T>(&self, client_data: &Client) -> Result<T, ClientError>
|
||||
|
|
@ -106,9 +110,10 @@ impl Objects {
|
|||
}
|
||||
|
||||
pub async fn remove_obj(&self, client_data: &Client, id: ObjectId) -> Result<(), ClientError> {
|
||||
if self.registry.remove(&id).is_none() {
|
||||
return Err(ClientError::UnknownId);
|
||||
}
|
||||
let _obj = match self.registry.remove(&id) {
|
||||
Some(o) => o,
|
||||
_ => return Err(ClientError::UnknownId),
|
||||
};
|
||||
if id.raw() >= MIN_SERVER_ID {
|
||||
let offset = (id.raw() - MIN_SERVER_ID) as usize;
|
||||
let pos = offset / SEG_SIZE;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::client::{Client, ClientError, WlEvent};
|
||||
use crate::client::{AddObj, Client, ClientError, WlEvent};
|
||||
use crate::object::ObjectId;
|
||||
use crate::utils::buffd::{BufFdIn, BufFdOut, MsgFormatter, MsgParser};
|
||||
use crate::utils::oneshot::OneshotRx;
|
||||
|
|
@ -10,12 +10,15 @@ use std::rc::Rc;
|
|||
|
||||
pub async fn client(data: Rc<Client>, shutdown: OneshotRx<()>) {
|
||||
let mut recv = data.state.eng.spawn(receive(data.clone())).fuse();
|
||||
let mut dispatch_fr = data.state.eng.spawn(dispatch_fr(data.clone())).fuse();
|
||||
let _send = data.state.eng.spawn(send(data.clone()));
|
||||
select! {
|
||||
_ = recv => { },
|
||||
_ = dispatch_fr => { },
|
||||
_ = shutdown.fuse() => { },
|
||||
}
|
||||
drop(recv);
|
||||
drop(dispatch_fr);
|
||||
if !data.shutdown_sent.get() {
|
||||
data.events.push(WlEvent::Shutdown);
|
||||
}
|
||||
|
|
@ -25,12 +28,36 @@ pub async fn client(data: Rc<Client>, shutdown: OneshotRx<()>) {
|
|||
log::error!("Could not shut down client {} within 5 seconds", data.id.0);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Could not create a timeout: {:#}", e);
|
||||
log::error!("Could not create a timeout: {:#}", anyhow!(e));
|
||||
}
|
||||
}
|
||||
data.state.clients.kill(data.id);
|
||||
}
|
||||
|
||||
async fn dispatch_fr(data: Rc<Client>) {
|
||||
loop {
|
||||
let mut fr = data.dispatch_frame_requests.pop().await;
|
||||
loop {
|
||||
if let Err(e) = data.event(fr.done()).await {
|
||||
log::error!("Could not dispatch frame event: {:#}", anyhow!(e));
|
||||
return;
|
||||
}
|
||||
if let Err(e) = data.remove_obj(&*fr).await {
|
||||
log::error!("Could not remove frame object: {:#}", anyhow!(e));
|
||||
return;
|
||||
}
|
||||
fr = match data.dispatch_frame_requests.try_pop() {
|
||||
Some(f) => f,
|
||||
_ => break,
|
||||
};
|
||||
}
|
||||
if let Err(e) = data.event2(WlEvent::Flush).await {
|
||||
log::error!("Could not dispatch frame event: {:#}", anyhow!(e));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn receive(data: Rc<Client>) {
|
||||
let display = data.display().unwrap();
|
||||
let recv = async {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue