mirror of https://github.com/wayvr-org/wayvr.git
get rid of handle.rs in favor of DenseSlotMap
This commit is contained in:
parent
e40b953e5a
commit
c92e27dcf9
|
|
@ -6659,6 +6659,7 @@ dependencies = [
|
|||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"slotmap",
|
||||
"smallvec",
|
||||
"smol",
|
||||
]
|
||||
|
|
@ -7237,6 +7238,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_json5",
|
||||
"slotmap",
|
||||
"smol",
|
||||
"strum",
|
||||
"walkdir",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ bytes.workspace = true
|
|||
interprocess.workspace = true
|
||||
log.workspace = true
|
||||
serde.workspace = true
|
||||
slotmap.workspace = true
|
||||
smallvec.workspace = true
|
||||
|
||||
# client-only deps
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use bytes::BufMut;
|
||||
use interprocess::local_socket::{self, ToNsName};
|
||||
use serde::Serialize;
|
||||
use slotmap::DenseSlotMap;
|
||||
use slotmap::new_key_type;
|
||||
use smallvec::SmallVec;
|
||||
use smol::io::AsyncReadExt;
|
||||
use smol::io::AsyncWriteExt;
|
||||
|
|
@ -9,7 +11,6 @@ use std::os::unix::net::UnixStream as StdUnixStream;
|
|||
use std::sync::{Arc, Weak};
|
||||
|
||||
use crate::{
|
||||
gen_id,
|
||||
ipc::{self, Serial},
|
||||
packet_client::{self, HandsfreeParams, PacketClient},
|
||||
packet_server::{self, PacketServer},
|
||||
|
|
@ -22,12 +23,9 @@ pub struct QueuedPacket {
|
|||
packet: Option<PacketServer>,
|
||||
}
|
||||
|
||||
gen_id!(
|
||||
QueuedPacketVec,
|
||||
QueuedPacket,
|
||||
QueuedPacketCell,
|
||||
QueuedPacketHandle
|
||||
);
|
||||
new_key_type! {
|
||||
pub struct QueuedPacketHandle;
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
pub struct AuthInfo {
|
||||
|
|
@ -41,7 +39,7 @@ pub struct WayVRClient {
|
|||
sender: SenderMutex,
|
||||
cancel_tx: async_channel::Sender<()>,
|
||||
exiting: bool,
|
||||
queued_packets: QueuedPacketVec,
|
||||
queued_packets: DenseSlotMap<QueuedPacketHandle, QueuedPacket>,
|
||||
pub auth: Option<AuthInfo>,
|
||||
pub on_signal: Option<SignalFunc>,
|
||||
}
|
||||
|
|
@ -156,7 +154,7 @@ impl WayVRClient {
|
|||
sender: sender.clone(),
|
||||
cancel_tx,
|
||||
exiting: false,
|
||||
queued_packets: QueuedPacketVec::new(),
|
||||
queued_packets: Default::default(),
|
||||
auth: None,
|
||||
on_signal: None,
|
||||
}));
|
||||
|
|
@ -263,12 +261,7 @@ impl WayVRClient {
|
|||
|
||||
// queue packet to read if it contains a serial response
|
||||
if let Some(serial) = packet.serial() {
|
||||
for qpacket in &mut client.queued_packets.vec {
|
||||
let Some(qpacket) = qpacket else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let qpacket = &mut qpacket.obj;
|
||||
for (_, qpacket) in &mut client.queued_packets {
|
||||
if qpacket.serial != *serial {
|
||||
continue; //skip
|
||||
}
|
||||
|
|
@ -306,7 +299,7 @@ impl WayVRClient {
|
|||
// Send packet to the server
|
||||
let queued_packet_handle = {
|
||||
let mut client = client_mtx.lock().await;
|
||||
let handle = client.queued_packets.add(QueuedPacket {
|
||||
let handle = client.queued_packets.insert(QueuedPacket {
|
||||
notifier: notifier.clone(),
|
||||
packet: None, // will be filled after notify
|
||||
serial,
|
||||
|
|
@ -329,7 +322,7 @@ impl WayVRClient {
|
|||
|
||||
let cell = client
|
||||
.queued_packets
|
||||
.get_mut(&queued_packet_handle)
|
||||
.get_mut(queued_packet_handle)
|
||||
.ok_or(anyhow::anyhow!(
|
||||
"missing packet cell, this shouldn't happen"
|
||||
))?;
|
||||
|
|
@ -338,7 +331,7 @@ impl WayVRClient {
|
|||
anyhow::bail!("packet is None, this shouldn't happen");
|
||||
};
|
||||
|
||||
client.queued_packets.remove(&queued_packet_handle);
|
||||
client.queued_packets.remove(queued_packet_handle);
|
||||
|
||||
Ok(packet)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,14 +21,12 @@ pub struct Disconnect {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||
pub struct WvrProcessHandle {
|
||||
pub idx: u32,
|
||||
pub generation: u64,
|
||||
pub user: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||
pub struct WvrWindowHandle {
|
||||
pub idx: u32,
|
||||
pub generation: u64,
|
||||
pub user: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
|
|
|||
|
|
@ -1,171 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! gen_id {
|
||||
(
|
||||
$container_name:ident,
|
||||
$instance_name:ident,
|
||||
$cell_name:ident,
|
||||
$handle_name:ident) => {
|
||||
//ThingCell
|
||||
pub struct $cell_name {
|
||||
pub obj: $instance_name,
|
||||
pub generation: u64,
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
pub struct $container_name {
|
||||
// Vec<Option<ThingCell>>
|
||||
pub vec: Vec<Option<$cell_name>>,
|
||||
|
||||
cur_generation: u64,
|
||||
}
|
||||
|
||||
//ThingHandle
|
||||
#[derive(Default, Clone, Copy, PartialEq, Hash, Eq)]
|
||||
pub struct $handle_name {
|
||||
idx: u32,
|
||||
generation: u64,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl $handle_name {
|
||||
pub fn reset(&mut self) {
|
||||
self.generation = 0;
|
||||
}
|
||||
|
||||
pub fn is_set(&self) -> bool {
|
||||
self.generation > 0
|
||||
}
|
||||
|
||||
pub fn id(&self) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
|
||||
pub fn new(idx: u32, generation: u64) -> Self {
|
||||
Self { idx, generation }
|
||||
}
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
#[allow(dead_code)]
|
||||
impl $container_name {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
vec: Vec::new(),
|
||||
cur_generation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self, callback: &dyn Fn($handle_name, &$instance_name)) {
|
||||
for (idx, opt_cell) in self.vec.iter().enumerate() {
|
||||
if let Some(cell) = opt_cell {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
callback(handle, &cell.obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self, callback: &mut dyn FnMut($handle_name, &mut $instance_name)) {
|
||||
for (idx, opt_cell) in self.vec.iter_mut().enumerate() {
|
||||
if let Some(cell) = opt_cell {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
callback(handle, &mut cell.obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_handle(cell: &$cell_name, idx: usize) -> $handle_name {
|
||||
$handle_name {
|
||||
idx: idx as u32,
|
||||
generation: cell.generation,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_unused_idx(&mut self) -> Option<u32> {
|
||||
for (num, obj) in self.vec.iter().enumerate() {
|
||||
if obj.is_none() {
|
||||
return Some(num as u32);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn add(&mut self, obj: $instance_name) -> $handle_name {
|
||||
self.cur_generation += 1;
|
||||
let generation = self.cur_generation;
|
||||
|
||||
let unused_idx = self.find_unused_idx();
|
||||
|
||||
let idx = if let Some(idx) = unused_idx {
|
||||
idx
|
||||
} else {
|
||||
self.vec.len() as u32
|
||||
};
|
||||
|
||||
let handle = $handle_name { idx, generation };
|
||||
|
||||
let cell = $cell_name { obj, generation };
|
||||
|
||||
if let Some(idx) = unused_idx {
|
||||
self.vec[idx as usize] = Some(cell);
|
||||
} else {
|
||||
self.vec.push(Some(cell))
|
||||
}
|
||||
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, handle: &$handle_name) {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove only if the generation matches
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
self.vec[handle.idx as usize] = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, handle: &$handle_name) -> Option<&$instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, handle: &$handle_name) -> Option<&mut $instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &mut self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&mut cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Example usage:
|
||||
gen_id!(ThingVec, ThingInstance, ThingCell, ThingHandle);
|
||||
|
||||
struct ThingInstance {}
|
||||
|
||||
impl ThingInstance {}
|
||||
*/
|
||||
|
|
@ -1,4 +1,2 @@
|
|||
pub mod handle;
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
pub mod notifier;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ idmap-derive.workspace = true
|
|||
input = {
|
||||
version = "0.9.1",
|
||||
default-features = false,
|
||||
features = ["libinput_1_19", "udev"],
|
||||
features = ["libinput_1_19", "udev"]
|
||||
}
|
||||
interprocess.workspace = true
|
||||
libc.workspace = true
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use std::{
|
|||
|
||||
use anyhow::Context;
|
||||
use glam::{DVec2, Vec2};
|
||||
use slotmap::DenseSlotMap;
|
||||
use smithay::{
|
||||
backend::input::{Axis, AxisSource, ButtonState, Keycode},
|
||||
input::{
|
||||
|
|
@ -146,7 +147,7 @@ impl WayVRCompositor {
|
|||
fn accept_connection(
|
||||
&mut self,
|
||||
stream: UnixStream,
|
||||
processes: &mut process::ProcessVec,
|
||||
processes: &mut DenseSlotMap<process::ProcessHandle, process::Process>,
|
||||
) -> anyhow::Result<()> {
|
||||
let client = self
|
||||
.display
|
||||
|
|
@ -154,13 +155,13 @@ impl WayVRCompositor {
|
|||
.insert_client(stream, Arc::new(comp::ClientState::default()))
|
||||
.unwrap();
|
||||
|
||||
let creds = client.get_credentials(&self.display.handle())?;
|
||||
let credentials = client.get_credentials(&self.display.handle())?;
|
||||
|
||||
let process_env = get_wayvr_env_from_pid(creds.pid)?;
|
||||
let process_env = get_wayvr_env_from_pid(credentials.pid)?;
|
||||
|
||||
// Find suitable auth key from the process list
|
||||
for p in processes.vec.iter().flatten() {
|
||||
if let process::Process::Managed(process) = &p.obj
|
||||
for (_, process) in processes {
|
||||
if let process::Process::Managed(process) = &process
|
||||
&& let Some(auth_key) = &process_env.display_auth
|
||||
{
|
||||
// Find process with matching auth key
|
||||
|
|
@ -168,7 +169,7 @@ impl WayVRCompositor {
|
|||
// Add client
|
||||
self.add_client(WayVRClient {
|
||||
client,
|
||||
pid: creds.pid as u32,
|
||||
pid: credentials.pid as u32,
|
||||
});
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -179,7 +180,7 @@ impl WayVRCompositor {
|
|||
// Treat external processes exclusively (spawned by the user or external program)
|
||||
log::warn!(
|
||||
"External process ID {} connected to this Wayland server",
|
||||
creds.pid
|
||||
credentials.pid
|
||||
);
|
||||
|
||||
self.state
|
||||
|
|
@ -187,13 +188,16 @@ impl WayVRCompositor {
|
|||
.send(WayVRTask::NewExternalProcess(ExternalProcessRequest {
|
||||
env: process_env,
|
||||
client,
|
||||
pid: creds.pid as u32,
|
||||
pid: credentials.pid as u32,
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn accept_connections(&mut self, processes: &mut process::ProcessVec) -> anyhow::Result<()> {
|
||||
fn accept_connections(
|
||||
&mut self,
|
||||
processes: &mut DenseSlotMap<process::ProcessHandle, process::Process>,
|
||||
) -> anyhow::Result<()> {
|
||||
if let Some(stream) = self.listener.accept()?
|
||||
&& let Err(e) = self.accept_connection(stream, processes)
|
||||
{
|
||||
|
|
@ -203,7 +207,10 @@ impl WayVRCompositor {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn tick_wayland(&mut self, processes: &mut process::ProcessVec) -> anyhow::Result<()> {
|
||||
pub fn tick_wayland(
|
||||
&mut self,
|
||||
processes: &mut DenseSlotMap<process::ProcessHandle, process::Process>,
|
||||
) -> anyhow::Result<()> {
|
||||
if let Err(e) = self.accept_connections(processes) {
|
||||
log::error!("accept_connections failed: {e}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,177 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! gen_id {
|
||||
(
|
||||
$container_name:ident,
|
||||
$instance_name:ident,
|
||||
$cell_name:ident,
|
||||
$handle_name:ident) => {
|
||||
//ThingCell
|
||||
#[derive(Debug)]
|
||||
pub struct $cell_name {
|
||||
pub obj: $instance_name,
|
||||
pub generation: u64,
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
#[derive(Debug)]
|
||||
pub struct $container_name {
|
||||
// Vec<Option<ThingCell>>
|
||||
pub vec: Vec<Option<$cell_name>>,
|
||||
|
||||
cur_generation: u64,
|
||||
}
|
||||
|
||||
//ThingHandle
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Hash, Eq)]
|
||||
pub struct $handle_name {
|
||||
idx: u32,
|
||||
generation: u64,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl $handle_name {
|
||||
pub const fn reset(&mut self) {
|
||||
self.generation = 0;
|
||||
}
|
||||
|
||||
pub const fn is_set(&self) -> bool {
|
||||
self.generation > 0
|
||||
}
|
||||
|
||||
pub const fn id(&self) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
|
||||
pub const fn new(idx: u32, generation: u64) -> Self {
|
||||
Self { idx, generation }
|
||||
}
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
impl $container_name {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
vec: Vec::new(),
|
||||
cur_generation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = ($handle_name, &$instance_name)> {
|
||||
self.vec.iter().enumerate().filter_map(|(idx, opt_cell)| {
|
||||
opt_cell.as_ref().map(|cell| {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
(handle, &cell.obj)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn iter_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = ($handle_name, &mut $instance_name)> {
|
||||
self.vec
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, opt_cell)| {
|
||||
opt_cell.as_mut().map(|cell| {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
(handle, &mut cell.obj)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub const fn get_handle(cell: &$cell_name, idx: usize) -> $handle_name {
|
||||
$handle_name {
|
||||
idx: idx as u32,
|
||||
generation: cell.generation,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_unused_idx(&mut self) -> Option<u32> {
|
||||
for (num, obj) in self.vec.iter().enumerate() {
|
||||
if obj.is_none() {
|
||||
return Some(num as u32);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn add(&mut self, obj: $instance_name) -> $handle_name {
|
||||
self.cur_generation += 1;
|
||||
let generation = self.cur_generation;
|
||||
|
||||
let unused_idx = self.find_unused_idx();
|
||||
|
||||
let idx = if let Some(idx) = unused_idx {
|
||||
idx
|
||||
} else {
|
||||
self.vec.len() as u32
|
||||
};
|
||||
|
||||
let handle = $handle_name { idx, generation };
|
||||
|
||||
let cell = $cell_name { obj, generation };
|
||||
|
||||
if let Some(idx) = unused_idx {
|
||||
self.vec[idx as usize] = Some(cell);
|
||||
} else {
|
||||
self.vec.push(Some(cell))
|
||||
}
|
||||
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, handle: &$handle_name) {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove only if the generation matches
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
self.vec[handle.idx as usize] = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, handle: &$handle_name) -> Option<&$instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, handle: &$handle_name) -> Option<&mut $instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &mut self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&mut cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Example usage:
|
||||
gen_id!(ThingVec, ThingInstance, ThingCell, ThingHandle);
|
||||
|
||||
struct ThingInstance {}
|
||||
|
||||
impl ThingInstance {}
|
||||
*/
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
pub mod client;
|
||||
mod comp;
|
||||
mod handle;
|
||||
pub mod hit_test;
|
||||
mod image_importer;
|
||||
mod input_capture;
|
||||
|
|
@ -11,8 +10,7 @@ pub mod window;
|
|||
use anyhow::Context;
|
||||
use comp::Application;
|
||||
use glam::{DVec2, Vec2};
|
||||
use process::ProcessVec;
|
||||
use slotmap::SecondaryMap;
|
||||
use slotmap::{DenseSlotMap, SecondaryMap};
|
||||
use smallvec::SmallVec;
|
||||
use smithay::{
|
||||
desktop::PopupManager,
|
||||
|
|
@ -136,7 +134,7 @@ pub enum WayVRTask {
|
|||
pub struct WvrServerState {
|
||||
pub manager: client::WayVRCompositor,
|
||||
pub wm: window::WindowManager,
|
||||
pub processes: process::ProcessVec,
|
||||
pub processes: DenseSlotMap<process::ProcessHandle, process::Process>,
|
||||
pub tasks: SyncEventQueue<WayVRTask>,
|
||||
ticks: u64,
|
||||
cur_modifiers: u8,
|
||||
|
|
@ -298,7 +296,7 @@ impl WvrServerState {
|
|||
|
||||
Ok(Self {
|
||||
manager: client::WayVRCompositor::new(state, display, seat_keyboard, seat_pointer)?,
|
||||
processes: ProcessVec::new(),
|
||||
processes: Default::default(),
|
||||
wm: window::WindowManager::new(),
|
||||
ticks: 0,
|
||||
tasks,
|
||||
|
|
@ -341,7 +339,7 @@ impl WvrServerState {
|
|||
}
|
||||
|
||||
for p_handle in &to_remove {
|
||||
wvr_server.processes.remove(p_handle);
|
||||
wvr_server.processes.remove(*p_handle);
|
||||
wvr_server.process_removed(&mut app.tasks, *p_handle);
|
||||
}
|
||||
|
||||
|
|
@ -399,7 +397,7 @@ impl WvrServerState {
|
|||
|
||||
// Size, icon & fallback title comes from process
|
||||
let (fallback_size, pos, fallback_title, icon, is_cage) =
|
||||
match wvr_server.processes.get(&process_handle) {
|
||||
match wvr_server.processes.get(process_handle) {
|
||||
Some(Process::Managed(p)) => {
|
||||
let size: Size<i32, Logical> =
|
||||
Size::new(p.resolution[0] as _, p.resolution[1] as _);
|
||||
|
|
@ -529,7 +527,7 @@ impl WvrServerState {
|
|||
let process_handle = wvr_server
|
||||
.wm
|
||||
.windows
|
||||
.get(&window_handle)
|
||||
.get(window_handle)
|
||||
.map(|window| window.process);
|
||||
|
||||
if let Some(oid) = wvr_server.window_to_overlay.remove(&window_handle) {
|
||||
|
|
@ -601,7 +599,7 @@ impl WvrServerState {
|
|||
}
|
||||
}
|
||||
WayVRTask::ProcessTerminationRequest(process_handle, signal) => {
|
||||
if let Some(process) = wvr_server.processes.get_mut(&process_handle) {
|
||||
if let Some(process) = wvr_server.processes.get_mut(process_handle) {
|
||||
process.kill(signal);
|
||||
}
|
||||
|
||||
|
|
@ -625,7 +623,7 @@ impl WvrServerState {
|
|||
}
|
||||
}
|
||||
WayVRTask::CloseWindowRequest(window_handle) => {
|
||||
if let Some(w) = wvr_server.wm.windows.get(&window_handle) {
|
||||
if let Some(w) = wvr_server.wm.windows.get(window_handle) {
|
||||
log::info!("Sending window close to {window_handle:?}");
|
||||
w.toplevel.send_close();
|
||||
} else {
|
||||
|
|
@ -684,7 +682,7 @@ impl WvrServerState {
|
|||
self.overlay_to_window.insert(oid, window);
|
||||
self.window_to_overlay.insert(window, oid);
|
||||
|
||||
if let Some(process_handle) = self.wm.windows.get(&window).map(|window| window.process) {
|
||||
if let Some(process_handle) = self.wm.windows.get(window).map(|window| window.process) {
|
||||
let overlays = self.process_overlays.entry(process_handle).or_default();
|
||||
overlays.retain(|other| *other != oid);
|
||||
overlays.push(oid);
|
||||
|
|
@ -719,7 +717,7 @@ impl WvrServerState {
|
|||
}
|
||||
|
||||
for hnd in &to_remove {
|
||||
self.wm.windows.remove(hnd);
|
||||
self.wm.windows.remove(*hnd);
|
||||
}
|
||||
|
||||
self.process_overlays.remove(&process);
|
||||
|
|
@ -740,7 +738,7 @@ impl WvrServerState {
|
|||
WvrHitTarget::Toplevel { .. } => self
|
||||
.wm
|
||||
.windows
|
||||
.get(&hover_window)
|
||||
.get(hover_window)
|
||||
.map(|w| {
|
||||
let surface = w.toplevel.wl_surface().clone();
|
||||
PointerFocusTarget::Surface {
|
||||
|
|
@ -966,7 +964,7 @@ impl WvrServerState {
|
|||
break 'mouse_update;
|
||||
};
|
||||
|
||||
let Some(window) = self.wm.windows.get(&hover.hover_window) else {
|
||||
let Some(window) = self.wm.windows.get(hover.hover_window) else {
|
||||
break 'mouse_update;
|
||||
};
|
||||
let toplevel = window.toplevel.wl_surface().clone();
|
||||
|
|
@ -1045,7 +1043,7 @@ impl WvrServerState {
|
|||
let surface = self
|
||||
.wm
|
||||
.windows
|
||||
.get(&hover_window)
|
||||
.get(hover_window)
|
||||
.map(|x| x.toplevel.wl_surface().clone());
|
||||
|
||||
(
|
||||
|
|
@ -1057,7 +1055,7 @@ impl WvrServerState {
|
|||
let surface = self
|
||||
.wm
|
||||
.windows
|
||||
.get(&hover_window)
|
||||
.get(hover_window)
|
||||
.map(|x| x.toplevel.wl_surface().clone());
|
||||
(None, pressed.then_some(surface).flatten())
|
||||
}
|
||||
|
|
@ -1207,7 +1205,7 @@ impl WvrServerState {
|
|||
|
||||
pub fn add_external_process(&mut self, pid: u32) -> process::ProcessHandle {
|
||||
self.processes
|
||||
.add(process::Process::External(process::ExternalProcess { pid }))
|
||||
.insert(process::Process::External(process::ExternalProcess { pid }))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
|
@ -1243,7 +1241,7 @@ impl WvrServerState {
|
|||
|
||||
let handle = self
|
||||
.processes
|
||||
.add(process::Process::Managed(process::WayVRProcess {
|
||||
.insert(process::Process::Managed(process::WayVRProcess {
|
||||
auth_key,
|
||||
child,
|
||||
exec_path: String::from(exec_path),
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use std::{collections::HashMap, io::Read, sync::Arc};
|
||||
|
||||
use slotmap::{DenseSlotMap, new_key_type};
|
||||
use wayvr_ipc::{packet_client, packet_server};
|
||||
|
||||
use crate::gen_id;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct WayVRProcess {
|
||||
|
|
@ -176,24 +175,26 @@ impl ExternalProcess {
|
|||
}
|
||||
}
|
||||
|
||||
gen_id!(ProcessVec, Process, ProcessCell, ProcessHandle);
|
||||
new_key_type! {
|
||||
pub struct ProcessHandle;
|
||||
}
|
||||
|
||||
pub fn find_by_pid(processes: &ProcessVec, pid: u32) -> Option<ProcessHandle> {
|
||||
pub fn find_by_pid(
|
||||
processes: &DenseSlotMap<ProcessHandle, Process>,
|
||||
pid: u32,
|
||||
) -> Option<ProcessHandle> {
|
||||
log::debug!("Finding process with PID {pid}");
|
||||
|
||||
for (idx, cell) in processes.vec.iter().enumerate() {
|
||||
let Some(cell) = cell else {
|
||||
continue;
|
||||
};
|
||||
match &cell.obj {
|
||||
for (handle, process) in processes {
|
||||
match &process {
|
||||
Process::Managed(wayvr_process) => {
|
||||
if wayvr_process.child.id() == pid {
|
||||
return Some(ProcessVec::get_handle(cell, idx));
|
||||
return Some(handle);
|
||||
}
|
||||
}
|
||||
Process::External(external_process) => {
|
||||
if external_process.pid == pid {
|
||||
return Some(ProcessVec::get_handle(cell, idx));
|
||||
return Some(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -202,14 +203,11 @@ pub fn find_by_pid(processes: &ProcessVec, pid: u32) -> Option<ProcessHandle> {
|
|||
log::debug!("Finding by PID failed, trying WAYVR_DISPLAY_AUTH...");
|
||||
|
||||
if let Ok(Some(value)) = get_process_env_value(pid as i32, "WAYVR_DISPLAY_AUTH") {
|
||||
for (idx, cell) in processes.vec.iter().enumerate() {
|
||||
let Some(cell) = cell else {
|
||||
continue;
|
||||
};
|
||||
if let Process::Managed(wayvr_process) = &cell.obj
|
||||
for (handle, process) in processes {
|
||||
if let Process::Managed(wayvr_process) = &process
|
||||
&& wayvr_process.auth_key == value
|
||||
{
|
||||
return Some(ProcessVec::get_handle(cell, idx));
|
||||
return Some(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,17 +217,13 @@ pub fn find_by_pid(processes: &ProcessVec, pid: u32) -> Option<ProcessHandle> {
|
|||
}
|
||||
|
||||
impl ProcessHandle {
|
||||
pub const fn from_packet(handle: packet_server::WvrProcessHandle) -> Self {
|
||||
Self {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
}
|
||||
pub fn from_packet(handle: packet_server::WvrProcessHandle) -> Self {
|
||||
Self::from(slotmap::KeyData::from_ffi(handle.user))
|
||||
}
|
||||
|
||||
pub const fn as_packet(&self) -> packet_server::WvrProcessHandle {
|
||||
pub fn as_packet(&self) -> packet_server::WvrProcessHandle {
|
||||
packet_server::WvrProcessHandle {
|
||||
idx: self.idx,
|
||||
generation: self.generation,
|
||||
user: self.0.as_ffi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use glam::DVec2;
|
||||
use slotmap::{DenseSlotMap, new_key_type};
|
||||
use smithay::utils::{Logical, Size};
|
||||
use smithay::wayland::shell::xdg::ToplevelSurface;
|
||||
use wayvr_ipc::packet_server;
|
||||
|
||||
use crate::{backend::wayvr::process, gen_id};
|
||||
use crate::backend::wayvr::process;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Window {
|
||||
|
|
@ -113,27 +114,24 @@ pub struct MouseState {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct WindowManager {
|
||||
pub windows: WindowVec,
|
||||
pub windows: DenseSlotMap<WindowHandle, Window>,
|
||||
pub mouse: Option<MouseState>,
|
||||
pub keyboard_focus: Option<WindowHandle>,
|
||||
}
|
||||
|
||||
impl WindowManager {
|
||||
pub const fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
windows: WindowVec::new(),
|
||||
windows: Default::default(),
|
||||
mouse: None,
|
||||
keyboard_focus: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_window_handle(&self, toplevel: &ToplevelSurface) -> Option<WindowHandle> {
|
||||
for (idx, cell) in self.windows.vec.iter().enumerate() {
|
||||
if let Some(cell) = cell {
|
||||
let window = &cell.obj;
|
||||
if *window.toplevel == *toplevel {
|
||||
return Some(WindowVec::get_handle(cell, idx));
|
||||
}
|
||||
for (handle, window) in &self.windows {
|
||||
if *window.toplevel == *toplevel {
|
||||
return Some(handle);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
@ -151,28 +149,26 @@ impl WindowManager {
|
|||
) -> WindowHandle {
|
||||
let mut window = Window::new(toplevel, process, bounds, min_size, max_size);
|
||||
window.remember_committed_size(Size::new(size_x as i32, size_y as i32));
|
||||
self.windows.add(window)
|
||||
self.windows.insert(window)
|
||||
}
|
||||
|
||||
pub fn remove_window(&mut self, window_handle: WindowHandle) {
|
||||
self.windows.remove(&window_handle);
|
||||
self.windows.remove(window_handle);
|
||||
}
|
||||
}
|
||||
|
||||
gen_id!(WindowVec, Window, WindowCell, WindowHandle);
|
||||
new_key_type! {
|
||||
pub struct WindowHandle;
|
||||
}
|
||||
|
||||
impl WindowHandle {
|
||||
pub const fn from_packet(handle: packet_server::WvrWindowHandle) -> Self {
|
||||
Self {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
}
|
||||
pub fn from_packet(handle: packet_server::WvrWindowHandle) -> Self {
|
||||
Self::from(slotmap::KeyData::from_ffi(handle.user))
|
||||
}
|
||||
|
||||
pub const fn as_packet(&self) -> packet_server::WvrWindowHandle {
|
||||
pub fn as_packet(&self) -> packet_server::WvrWindowHandle {
|
||||
packet_server::WvrWindowHandle {
|
||||
idx: self.idx,
|
||||
generation: self.generation,
|
||||
user: self.0.as_ffi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ impl Connection {
|
|||
.wvr_server
|
||||
.wm
|
||||
.windows
|
||||
.get_mut(&wayvr::window::WindowHandle::from_packet(handle))
|
||||
.get_mut(wayvr::window::WindowHandle::from_packet(handle))
|
||||
{
|
||||
window.visible = visible;
|
||||
}
|
||||
|
|
@ -272,19 +272,8 @@ impl Connection {
|
|||
let list: Vec<packet_server::WvrProcess> = params
|
||||
.wvr_server
|
||||
.processes
|
||||
.vec
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, opt_cell)| {
|
||||
let Some(cell) = opt_cell else {
|
||||
return None;
|
||||
};
|
||||
let process = &cell.obj;
|
||||
Some(process.to_packet(wayvr::process::ProcessHandle::new(
|
||||
idx as u32,
|
||||
cell.generation,
|
||||
)))
|
||||
})
|
||||
.map(|(handle, process)| process.to_packet(handle))
|
||||
.collect();
|
||||
|
||||
send_packet(
|
||||
|
|
@ -306,7 +295,7 @@ impl Connection {
|
|||
use crate::backend::wayvr::process::KillSignal;
|
||||
|
||||
let native_handle = &wayvr::process::ProcessHandle::from_packet(process_handle);
|
||||
let process = params.wvr_server.processes.get_mut(native_handle);
|
||||
let process = params.wvr_server.processes.get_mut(*native_handle);
|
||||
|
||||
let Some(process) = process else {
|
||||
return;
|
||||
|
|
@ -325,7 +314,7 @@ impl Connection {
|
|||
let process = params
|
||||
.wvr_server
|
||||
.processes
|
||||
.get(native_handle)
|
||||
.get(*native_handle)
|
||||
.map(|process| process.to_packet(*native_handle));
|
||||
|
||||
send_packet(
|
||||
|
|
|
|||
|
|
@ -427,7 +427,7 @@ impl DashInterface<AppState> for DashInterfaceLive {
|
|||
let handle = ProcessHandle::from_packet(handle);
|
||||
wvr_server
|
||||
.processes
|
||||
.get(&handle)
|
||||
.get(handle)
|
||||
.map(|x| x.to_packet(handle))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ pub fn create_wl_window_overlay(
|
|||
let resizable = app
|
||||
.wvr_server
|
||||
.as_mut()
|
||||
.and_then(|wvr| wvr.wm.windows.get(&window))
|
||||
.and_then(|wvr| wvr.wm.windows.get(window))
|
||||
.map(|w| w.resizable())
|
||||
.unwrap_or(false);
|
||||
|
||||
|
|
@ -284,7 +284,7 @@ impl WvrWindowBackend {
|
|||
self.resizable = app
|
||||
.wvr_server
|
||||
.as_mut()
|
||||
.and_then(|wvr| wvr.wm.windows.get(&self.window))
|
||||
.and_then(|wvr| wvr.wm.windows.get(self.window))
|
||||
.map(|w| w.resizable())
|
||||
.unwrap_or(false);
|
||||
|
||||
|
|
@ -475,7 +475,7 @@ impl WvrWindowBackend {
|
|||
|
||||
let committed = Size::new(inner_extent[0].max(1) as i32, inner_extent[1].max(1) as i32);
|
||||
|
||||
let Some(window) = wvr_server.wm.windows.get_mut(&self.window) else {
|
||||
let Some(window) = wvr_server.wm.windows.get_mut(self.window) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
|
|
@ -516,7 +516,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
let Some(toplevel) = app
|
||||
.wvr_server
|
||||
.as_ref()
|
||||
.and_then(|sv| sv.wm.windows.get(&self.window))
|
||||
.and_then(|sv| sv.wm.windows.get(self.window))
|
||||
.map(|win| win.toplevel.clone())
|
||||
else {
|
||||
log::debug!(
|
||||
|
|
@ -742,7 +742,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(window) = wvr_server.wm.windows.get(&self.window) {
|
||||
if let Some(window) = wvr_server.wm.windows.get(self.window) {
|
||||
let surface_id = window.toplevel.wl_surface().id();
|
||||
state.send_frame_callbacks_for_surface_id(&surface_id);
|
||||
}
|
||||
|
|
@ -774,7 +774,7 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
}
|
||||
OverlayEventData::WvrCommand(WvrCommand::ReloadTitle) => {
|
||||
let wvr_server = app.wvr_server.as_mut().unwrap(); //never None
|
||||
if let Some(window) = wvr_server.wm.windows.get(&self.window) {
|
||||
if let Some(window) = wvr_server.wm.windows.get(self.window) {
|
||||
let title = with_states(window.toplevel.wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
|
|
@ -795,14 +795,14 @@ impl OverlayBackend for WvrWindowBackend {
|
|||
}
|
||||
OverlayEventData::WvrCommand(WvrCommand::KillProcess(signal)) => {
|
||||
let wvr_server = app.wvr_server.as_mut().unwrap();
|
||||
let Some(p) = wvr_server.wm.windows.get(&self.window) else {
|
||||
let Some(p) = wvr_server.wm.windows.get(self.window) else {
|
||||
return Ok(());
|
||||
};
|
||||
wvr_server.terminate_process(p.process, signal);
|
||||
}
|
||||
OverlayEventData::ResizeRequest(new_size) => {
|
||||
let wvr_server = app.wvr_server.as_mut().unwrap();
|
||||
let Some(win) = wvr_server.wm.windows.get_mut(&self.window) else {
|
||||
let Some(win) = wvr_server.wm.windows.get_mut(self.window) else {
|
||||
log::warn!("Could not process resize request: window not found");
|
||||
return Ok(());
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ log.workspace = true
|
|||
serde = { workspace = true, features = ["rc"] }
|
||||
serde_json.workspace = true
|
||||
serde_json5.workspace = true
|
||||
slotmap.workspace = true
|
||||
smol.workspace = true
|
||||
strum.workspace = true
|
||||
xdg.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use slotmap::{DenseSlotMap, new_key_type};
|
||||
use wayvr_ipc::{
|
||||
packet_client::WvrProcessLaunchParams,
|
||||
packet_server::{WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle},
|
||||
|
|
@ -7,25 +8,19 @@ use crate::{
|
|||
config::GeneralConfig,
|
||||
dash_interface::{self, ConfigChangeKind, DashInterface, DashPlayspaceTask},
|
||||
desktop_finder::DesktopFinder,
|
||||
gen_id,
|
||||
};
|
||||
|
||||
new_key_type! {
|
||||
pub struct EmuProcessHandle;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EmuProcess {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl EmuProcess {
|
||||
fn to(&self, handle: EmuProcessHandle) -> WvrProcess {
|
||||
WvrProcess {
|
||||
handle: WvrProcessHandle {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
},
|
||||
name: self.name.clone(),
|
||||
userdata: Default::default(),
|
||||
}
|
||||
}
|
||||
new_key_type! {
|
||||
pub struct EmuWindowHandle;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -34,6 +29,18 @@ pub struct EmuWindow {
|
|||
process_handle: EmuProcessHandle,
|
||||
}
|
||||
|
||||
impl EmuProcess {
|
||||
fn to(&self, handle: EmuProcessHandle) -> WvrProcess {
|
||||
WvrProcess {
|
||||
handle: WvrProcessHandle {
|
||||
user: handle.0.as_ffi(),
|
||||
},
|
||||
name: self.name.clone(),
|
||||
userdata: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmuWindow {
|
||||
fn to(&self, handle: EmuWindowHandle) -> WvrWindow {
|
||||
WvrWindow {
|
||||
|
|
@ -41,24 +48,18 @@ impl EmuWindow {
|
|||
size_y: 720, /* stub */
|
||||
visible: true,
|
||||
handle: WvrWindowHandle {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
user: handle.0.as_ffi(),
|
||||
},
|
||||
process_handle: WvrProcessHandle {
|
||||
generation: self.process_handle.generation,
|
||||
idx: self.process_handle.idx,
|
||||
user: self.process_handle.0.as_ffi(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gen_id!(EmuWindowVec, EmuWindow, EmuWindowCell, EmuWindowHandle);
|
||||
|
||||
gen_id!(EmuProcessVec, EmuProcess, EmuProcessCell, EmuProcessHandle);
|
||||
|
||||
pub struct DashInterfaceEmulated {
|
||||
processes: EmuProcessVec,
|
||||
windows: EmuWindowVec,
|
||||
windows: DenseSlotMap<EmuWindowHandle, EmuWindow>,
|
||||
processes: DenseSlotMap<EmuProcessHandle, EmuProcess>,
|
||||
desktop_finder: DesktopFinder,
|
||||
general_config: GeneralConfig,
|
||||
monado_clients: Vec<dash_interface::MonadoClient>,
|
||||
|
|
@ -69,13 +70,13 @@ pub struct DashInterfaceEmulated {
|
|||
|
||||
impl DashInterfaceEmulated {
|
||||
pub fn new() -> Self {
|
||||
let mut processes = EmuProcessVec::new();
|
||||
let process_handle = processes.add(EmuProcess {
|
||||
let mut processes = DenseSlotMap::<EmuProcessHandle, EmuProcess>::default();
|
||||
let process_handle = processes.insert(EmuProcess {
|
||||
name: String::from("My app"),
|
||||
});
|
||||
|
||||
let mut windows = EmuWindowVec::new();
|
||||
windows.add(EmuWindow {
|
||||
let mut windows = DenseSlotMap::<EmuWindowHandle, EmuWindow>::default();
|
||||
windows.insert(EmuWindow {
|
||||
process_handle,
|
||||
visible: true,
|
||||
});
|
||||
|
|
@ -144,16 +145,15 @@ impl DashInterface<()> for DashInterfaceEmulated {
|
|||
}
|
||||
|
||||
fn window_request_close(&mut self, _: &mut (), handle: WvrWindowHandle) -> anyhow::Result<()> {
|
||||
self.windows.remove(&EmuWindowHandle {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
});
|
||||
self
|
||||
.windows
|
||||
.remove(EmuWindowHandle::from(slotmap::KeyData::from_ffi(handle.user)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_get(&mut self, _: &mut (), handle: WvrProcessHandle) -> Option<WvrProcess> {
|
||||
let emu_handle = EmuProcessHandle::new(handle.idx, handle.generation);
|
||||
self.processes.get(&emu_handle).map(|process| process.to(emu_handle))
|
||||
let emu_handle = EmuProcessHandle::from(slotmap::KeyData::from_ffi(handle.user));
|
||||
self.processes.get(emu_handle).map(|process| process.to(emu_handle))
|
||||
}
|
||||
|
||||
fn process_launch(
|
||||
|
|
@ -162,17 +162,14 @@ impl DashInterface<()> for DashInterfaceEmulated {
|
|||
_: bool,
|
||||
params: WvrProcessLaunchParams,
|
||||
) -> anyhow::Result<WvrProcessHandle> {
|
||||
let res = self.processes.add(EmuProcess { name: params.name });
|
||||
let res = self.processes.insert(EmuProcess { name: params.name });
|
||||
|
||||
self.windows.add(EmuWindow {
|
||||
self.windows.insert(EmuWindow {
|
||||
process_handle: res,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
Ok(WvrProcessHandle {
|
||||
generation: res.generation,
|
||||
idx: res.idx,
|
||||
})
|
||||
Ok(WvrProcessHandle { user: res.0.as_ffi() })
|
||||
}
|
||||
|
||||
fn process_list(&mut self, _: &mut ()) -> anyhow::Result<Vec<WvrProcess>> {
|
||||
|
|
@ -189,26 +186,26 @@ impl DashInterface<()> for DashInterfaceEmulated {
|
|||
let mut to_remove = None;
|
||||
|
||||
for (wh, w) in self.windows.iter() {
|
||||
if w.process_handle == EmuProcessHandle::new(handle.idx, handle.generation) {
|
||||
if w.process_handle == EmuProcessHandle::from(slotmap::KeyData::from_ffi(handle.user)) {
|
||||
to_remove = Some(wh);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(wh) = to_remove {
|
||||
self.windows.remove(&wh);
|
||||
self.windows.remove(wh);
|
||||
}
|
||||
|
||||
self
|
||||
.processes
|
||||
.remove(&EmuProcessHandle::new(handle.idx, handle.generation));
|
||||
.remove(EmuProcessHandle::from(slotmap::KeyData::from_ffi(handle.user)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn window_set_visible(&mut self, _: &mut (), handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()> {
|
||||
match self.windows.get_mut(&EmuWindowHandle {
|
||||
generation: handle.generation,
|
||||
idx: handle.idx,
|
||||
}) {
|
||||
match self
|
||||
.windows
|
||||
.get_mut(EmuWindowHandle::from(slotmap::KeyData::from_ffi(handle.user)))
|
||||
{
|
||||
Some(w) => {
|
||||
w.visible = visible;
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,172 +0,0 @@
|
|||
#[macro_export]
|
||||
macro_rules! gen_id {
|
||||
(
|
||||
$container_name:ident,
|
||||
$instance_name:ident,
|
||||
$cell_name:ident,
|
||||
$handle_name:ident) => {
|
||||
//ThingCell
|
||||
#[derive(Debug)]
|
||||
pub struct $cell_name {
|
||||
pub obj: $instance_name,
|
||||
pub generation: u64,
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
#[derive(Debug)]
|
||||
pub struct $container_name {
|
||||
// Vec<Option<ThingCell>>
|
||||
pub vec: Vec<Option<$cell_name>>,
|
||||
|
||||
cur_generation: u64,
|
||||
}
|
||||
|
||||
//ThingHandle
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Hash, Eq)]
|
||||
pub struct $handle_name {
|
||||
idx: u32,
|
||||
generation: u64,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl $handle_name {
|
||||
pub const fn reset(&mut self) {
|
||||
self.generation = 0;
|
||||
}
|
||||
|
||||
pub const fn is_set(&self) -> bool {
|
||||
self.generation > 0
|
||||
}
|
||||
|
||||
pub const fn id(&self) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
|
||||
pub const fn new(idx: u32, generation: u64) -> Self {
|
||||
Self { idx, generation }
|
||||
}
|
||||
}
|
||||
|
||||
//ThingVec
|
||||
impl $container_name {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
vec: Vec::new(),
|
||||
cur_generation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = ($handle_name, &$instance_name)> {
|
||||
self.vec.iter().enumerate().filter_map(|(idx, opt_cell)| {
|
||||
opt_cell.as_ref().map(|cell| {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
(handle, &cell.obj)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = ($handle_name, &mut $instance_name)> {
|
||||
self.vec.iter_mut().enumerate().filter_map(|(idx, opt_cell)| {
|
||||
opt_cell.as_mut().map(|cell| {
|
||||
let handle = $container_name::get_handle(&cell, idx);
|
||||
(handle, &mut cell.obj)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub const fn get_handle(cell: &$cell_name, idx: usize) -> $handle_name {
|
||||
$handle_name {
|
||||
idx: idx as u32,
|
||||
generation: cell.generation,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_unused_idx(&mut self) -> Option<u32> {
|
||||
for (num, obj) in self.vec.iter().enumerate() {
|
||||
if obj.is_none() {
|
||||
return Some(num as u32);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn add(&mut self, obj: $instance_name) -> $handle_name {
|
||||
self.cur_generation += 1;
|
||||
let generation = self.cur_generation;
|
||||
|
||||
let unused_idx = self.find_unused_idx();
|
||||
|
||||
let idx = if let Some(idx) = unused_idx {
|
||||
idx
|
||||
} else {
|
||||
self.vec.len() as u32
|
||||
};
|
||||
|
||||
let handle = $handle_name { idx, generation };
|
||||
|
||||
let cell = $cell_name { obj, generation };
|
||||
|
||||
if let Some(idx) = unused_idx {
|
||||
self.vec[idx as usize] = Some(cell);
|
||||
} else {
|
||||
self.vec.push(Some(cell))
|
||||
}
|
||||
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, handle: &$handle_name) {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove only if the generation matches
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
self.vec[handle.idx as usize] = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, handle: &$handle_name) -> Option<&$instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, handle: &$handle_name) -> Option<&mut $instance_name> {
|
||||
// Out of bounds, ignore
|
||||
if handle.idx as usize >= self.vec.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(cell) = &mut self.vec[handle.idx as usize] {
|
||||
if cell.generation == handle.generation {
|
||||
return Some(&mut cell.obj);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* Example usage:
|
||||
gen_id!(ThingVec, ThingInstance, ThingCell, ThingHandle);
|
||||
|
||||
struct ThingInstance {}
|
||||
|
||||
impl ThingInstance {}
|
||||
*/
|
||||
|
|
@ -9,7 +9,6 @@ pub mod dash_interface;
|
|||
pub mod dash_interface_emulated;
|
||||
pub mod data_dir;
|
||||
pub mod desktop_finder;
|
||||
mod handle;
|
||||
pub mod locale;
|
||||
pub mod openxr_actions;
|
||||
pub mod openxr_bindings_schema;
|
||||
|
|
|
|||
Loading…
Reference in New Issue