ferroui_browser/
js_object_control_handle.rs1use crate::interop::JsObject;
2use ferroui_controls::platform::{INativeControlHostDestroyableControlHandle, IPlatformHandle};
3use std::any::Any;
4use std::cell::RefCell;
5use std::sync::atomic::{AtomicIsize, Ordering};
6
7pub(crate) const ELEMENT_REFERENCE_DESCRIPTOR: &str = "JSObject";
9
10static NEXT_HANDLE: AtomicIsize = AtomicIsize::new(1);
11
12pub 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 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
46pub struct JsObjectControlHandle {
49 base: JsObjectPlatformHandle,
50}
51
52impl JsObjectControlHandle {
53 pub fn new(reference: JsObject) -> Self {
55 Self { base: JsObjectPlatformHandle::new(reference) }
56 }
57
58 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}