Skip to main content

ferroui_browser/
js_object_control_handle.rs

1use crate::interop::JsObject;
2use ferroui_controls::platform::{INativeControlHostDestroyableControlHandle, IPlatformHandle};
3use std::any::Any;
4use std::cell::RefCell;
5use std::sync::atomic::{AtomicIsize, Ordering};
6
7/// The descriptor of handles that wrap an object of the page.
8pub(crate) const ELEMENT_REFERENCE_DESCRIPTOR: &str = "JSObject";
9
10static NEXT_HANDLE: AtomicIsize = AtomicIsize::new(1);
11
12/// A platform handle that wraps an object of the page.
13///
14/// The numeric handle only identifies the wrapper; the object itself is
15/// reached through [`object`](Self::object).
16pub struct JsObjectPlatformHandle {
17    handle: isize,
18    object: RefCell<Option<JsObject>>,
19}
20
21impl JsObjectPlatformHandle {
22    pub(crate) fn new(reference: JsObject) -> Self {
23        Self { handle: NEXT_HANDLE.fetch_add(1, Ordering::Relaxed), object: RefCell::new(Some(reference)) }
24    }
25
26    /// The object of the page; `None` once the handle has been destroyed.
27    pub fn object(&self) -> Option<JsObject> {
28        self.object.borrow().clone()
29    }
30}
31
32impl IPlatformHandle for JsObjectPlatformHandle {
33    fn handle(&self) -> isize {
34        self.handle
35    }
36
37    fn handle_descriptor(&self) -> Option<&str> {
38        Some(ELEMENT_REFERENCE_DESCRIPTOR)
39    }
40
41    fn as_any(&self) -> &dyn Any {
42        self
43    }
44}
45
46/// The handle of a control of the page that the framework hosts and may
47/// destroy.
48pub struct JsObjectControlHandle {
49    base: JsObjectPlatformHandle,
50}
51
52impl JsObjectControlHandle {
53    /// Wraps an object of the page.
54    pub fn new(reference: JsObject) -> Self {
55        Self { base: JsObjectPlatformHandle::new(reference) }
56    }
57
58    /// The object of the page; `None` once the handle has been destroyed.
59    pub fn object(&self) -> Option<JsObject> {
60        self.base.object()
61    }
62}
63
64impl IPlatformHandle for JsObjectControlHandle {
65    fn handle(&self) -> isize {
66        self.base.handle
67    }
68
69    fn handle_descriptor(&self) -> Option<&str> {
70        Some(ELEMENT_REFERENCE_DESCRIPTOR)
71    }
72
73    fn as_any(&self) -> &dyn Any {
74        self
75    }
76
77    fn as_native_control_host_destroyable_control_handle(
78        &self,
79    ) -> Option<&dyn INativeControlHostDestroyableControlHandle> {
80        Some(self)
81    }
82}
83
84impl INativeControlHostDestroyableControlHandle for JsObjectControlHandle {
85    fn destroy(&self) {
86        self.base.object.borrow_mut().take();
87    }
88}