miracle_plugin/
workspace.rs1use super::bindings;
2use super::container::*;
3use super::core::Rectangle;
4use super::host::*;
5use super::output::*;
6
7#[derive(Debug, Clone)]
13pub struct Workspace {
14 pub number: Option<u32>,
16 pub name: Option<String>,
18 pub num_trees: u32,
20 pub rectangle: Rectangle,
22 internal: u64,
23}
24
25impl Workspace {
26 pub fn id(&self) -> u64 {
28 self.internal
29 }
30
31 #[doc(hidden)]
32 pub unsafe fn from_c_with_name(value: &bindings::miracle_workspace_t, name: String) -> Self {
33 Self {
34 number: if value.has_number != 0 {
35 Some(value.number)
36 } else {
37 None
38 },
39 name: if value.has_name != 0 {
40 Some(name)
41 } else {
42 None
43 },
44 num_trees: value.num_trees,
45 internal: value.internal,
46 rectangle: Rectangle {
47 x: value.position.x,
48 y: value.position.y,
49 width: value.size.w,
50 height: value.size.h,
51 },
52 }
53 }
54
55 pub fn output(&self) -> Option<Output> {
57 const NAME_BUF_LEN: usize = 256;
58 let mut output = std::mem::MaybeUninit::<crate::bindings::miracle_output_t>::uninit();
59 let mut name_buf: [u8; NAME_BUF_LEN] = [0; NAME_BUF_LEN];
60
61 unsafe {
62 let result = miracle_workspace_get_output(
63 self.internal as i64,
64 output.as_mut_ptr() as i32,
65 name_buf.as_mut_ptr() as i32,
66 NAME_BUF_LEN as i32,
67 );
68
69 if result != 0 {
70 return None;
71 }
72
73 let output = output.assume_init();
74
75 let name_len = name_buf
77 .iter()
78 .position(|&c| c == 0)
79 .unwrap_or(NAME_BUF_LEN);
80 let name = String::from_utf8_lossy(&name_buf[..name_len]).into_owned();
81
82 Some(Output::from_c_with_name(&output, name))
83 }
84 }
85
86 pub fn tree_at(&self, index: u32) -> Option<Container> {
90 if index >= self.num_trees {
91 return None;
92 }
93
94 let mut container = std::mem::MaybeUninit::<crate::bindings::miracle_container_t>::uninit();
95 unsafe {
96 let result = miracle_workspace_get_tree(
97 self.internal as i64,
98 index,
99 container.as_mut_ptr() as i32,
100 );
101
102 if result != 0 {
103 return None;
104 }
105
106 let container = container.assume_init();
107 Some(Container::from(container))
108 }
109 }
110
111 pub fn trees(&self) -> Vec<Container> {
113 (0..self.num_trees)
114 .filter_map(|i| self.tree_at(i))
115 .collect()
116 }
117}