DashInterface, DashInterfaceEmulated

This commit is contained in:
Aleksander
2025-12-10 22:11:57 +01:00
parent 171021d6c5
commit 7118cea810
11 changed files with 392 additions and 3 deletions

View File

@@ -0,0 +1,25 @@
use wayvr_ipc::{
packet_client::{WvrDisplayCreateParams, WvrProcessLaunchParams},
packet_server::{
WvrDisplay, WvrDisplayHandle, WvrDisplayWindowLayout, WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle,
},
};
pub trait DashInterface {
fn display_create(&mut self, params: WvrDisplayCreateParams) -> anyhow::Result<WvrDisplayHandle>;
fn display_get(&mut self, handle: WvrDisplayHandle) -> Option<WvrDisplay>;
fn display_list(&mut self) -> anyhow::Result<Vec<WvrDisplay>>;
fn display_remove(&mut self, handle: WvrDisplayHandle) -> anyhow::Result<()>;
fn display_set_visible(&mut self, handle: WvrDisplayHandle, visible: bool) -> anyhow::Result<()>;
fn display_set_window_layout(
&mut self,
handle: WvrDisplayHandle,
layout: WvrDisplayWindowLayout,
) -> anyhow::Result<()>;
fn display_window_list(&mut self, handle: WvrDisplayHandle) -> anyhow::Result<Vec<WvrWindow>>;
fn process_get(&mut self, handle: WvrProcessHandle) -> Option<WvrProcess>;
fn process_launch(&mut self, params: WvrProcessLaunchParams) -> anyhow::Result<WvrProcessHandle>;
fn process_list(&mut self) -> anyhow::Result<Vec<WvrProcess>>;
fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()>;
fn window_set_visible(&mut self, handle: WvrWindowHandle, visible: bool) -> anyhow::Result<()>;
}

View File

@@ -0,0 +1,173 @@
use wayvr_ipc::{
packet_client::{WvrDisplayCreateParams, WvrProcessLaunchParams},
packet_server::{
WvrDisplay, WvrDisplayHandle, WvrDisplayWindowLayout, WvrProcess, WvrProcessHandle, WvrWindow, WvrWindowHandle,
},
};
use crate::{dash_interface::DashInterface, gen_id};
#[derive(Debug)]
pub struct EmuProcess {
display_handle: WvrDisplayHandle,
name: String,
}
impl EmuProcess {
fn to(&self, handle: EmuProcessHandle) -> WvrProcess {
WvrProcess {
display_handle: self.display_handle.clone(),
handle: WvrProcessHandle {
generation: handle.generation,
idx: handle.idx,
},
name: self.name.clone(),
userdata: Default::default(),
}
}
}
#[derive(Debug)]
pub struct EmuDisplay {
width: u16,
height: u16,
name: String,
visible: bool,
layout: WvrDisplayWindowLayout,
}
impl EmuDisplay {
fn to(&self, handle: EmuDisplayHandle) -> WvrDisplay {
WvrDisplay {
width: self.width,
height: self.height,
name: self.name.clone(),
visible: self.visible,
handle: WvrDisplayHandle {
generation: handle.generation,
idx: handle.idx,
},
}
}
}
gen_id!(EmuDisplayVec, EmuDisplay, EmuDisplayCell, EmuDisplayHandle);
gen_id!(EmuProcessVec, EmuProcess, EmuProcessCell, EmuProcessHandle);
pub struct DashInterfaceEmulated {
displays: EmuDisplayVec,
processes: EmuProcessVec,
}
impl DashInterfaceEmulated {
pub fn new() -> Self {
Self {
displays: EmuDisplayVec::new(),
processes: EmuProcessVec::new(),
}
}
}
impl DashInterface for DashInterfaceEmulated {
fn display_create(&mut self, params: WvrDisplayCreateParams) -> anyhow::Result<WvrDisplayHandle> {
let res = self.displays.add(EmuDisplay {
width: params.width,
height: params.height,
name: params.name,
visible: true,
layout: WvrDisplayWindowLayout::Tiling,
});
Ok(WvrDisplayHandle {
generation: res.generation,
idx: res.idx,
})
}
fn display_get(&mut self, handle: WvrDisplayHandle) -> Option<WvrDisplay> {
let emu_handle = EmuDisplayHandle::new(handle.idx, handle.generation);
self.displays.get(&emu_handle).map(|disp| disp.to(emu_handle))
}
fn display_list(&mut self) -> anyhow::Result<Vec<WvrDisplay>> {
Ok(self.displays.iter().map(|(handle, disp)| disp.to(handle)).collect())
}
fn display_remove(&mut self, handle: WvrDisplayHandle) -> anyhow::Result<()> {
self
.displays
.remove(&EmuDisplayHandle::new(handle.idx, handle.generation));
Ok(())
}
fn display_set_visible(&mut self, handle: WvrDisplayHandle, visible: bool) -> anyhow::Result<()> {
let Some(disp) = self
.displays
.get_mut(&EmuDisplayHandle::new(handle.idx, handle.generation))
else {
anyhow::bail!("Display not found");
};
disp.visible = visible;
Ok(())
}
fn display_set_window_layout(
&mut self,
handle: WvrDisplayHandle,
layout: WvrDisplayWindowLayout,
) -> anyhow::Result<()> {
let Some(disp) = self
.displays
.get_mut(&EmuDisplayHandle::new(handle.idx, handle.generation))
else {
anyhow::bail!("Display not found");
};
disp.layout = layout;
Ok(())
}
fn display_window_list(&mut self, _handle: WvrDisplayHandle) -> anyhow::Result<Vec<WvrWindow>> {
// stub!
Ok(Vec::new())
}
fn process_get(&mut self, handle: WvrProcessHandle) -> Option<WvrProcess> {
let emu_handle = EmuProcessHandle::new(handle.idx, handle.generation);
self.processes.get(&emu_handle).map(|process| process.to(emu_handle))
}
fn process_launch(&mut self, params: WvrProcessLaunchParams) -> anyhow::Result<WvrProcessHandle> {
let res = self.processes.add(EmuProcess {
display_handle: params.target_display,
name: params.name,
});
Ok(WvrProcessHandle {
generation: res.generation,
idx: res.idx,
})
}
fn process_list(&mut self) -> anyhow::Result<Vec<WvrProcess>> {
Ok(
self
.processes
.iter()
.map(|(handle, process)| process.to(handle))
.collect(),
)
}
fn process_terminate(&mut self, handle: WvrProcessHandle) -> anyhow::Result<()> {
self
.processes
.remove(&EmuProcessHandle::new(handle.idx, handle.generation));
Ok(())
}
fn window_set_visible(&mut self, _handle: WvrWindowHandle, _visible: bool) -> anyhow::Result<()> {
// stub!
Ok(())
}
}

176
wlx-common/src/handle.rs Normal file
View File

@@ -0,0 +1,176 @@
#[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)
})
})
}
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 {}
*/

View File

@@ -1,6 +1,9 @@
pub mod astr_containers;
pub mod common;
pub mod config;
pub mod dash_interface;
pub mod dash_interface_emulated;
mod handle;
pub mod overlays;
pub mod timestep;
pub mod windowing;