Skip to content

Commit 062bb03

Browse files
authored
fix(ipc): use v8 object to store callbacks (#211)
1 parent 00ed7d8 commit 062bb03

2 files changed

Lines changed: 188 additions & 128 deletions

File tree

crates/cef_app/src/render_process.rs

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use crate::ipc_contract::{
1616
ROUTE_IPC_DATA_GODOT_TO_RENDERER, ROUTE_IPC_GODOT_TO_RENDERER, ROUTE_TRIGGER_IME,
1717
};
1818
use crate::v8_handlers::{
19-
IpcListenerSet, OsrImeCaretHandler, OsrImeCaretHandlerBuilder, OsrIpcBinaryHandler,
20-
OsrIpcBinaryHandlerBuilder, OsrIpcDataHandler, OsrIpcDataHandlerBuilder, OsrIpcHandler,
21-
OsrIpcHandlerBuilder, cbor_bytes_to_v8_value, v8_prop_default,
19+
OsrImeCaretHandler, OsrImeCaretHandlerBuilder, OsrIpcBinaryHandler, OsrIpcBinaryHandlerBuilder,
20+
OsrIpcDataHandler, OsrIpcDataHandlerBuilder, OsrIpcHandler, OsrIpcHandlerBuilder,
21+
build_ipc_listener_object, cbor_bytes_to_v8_value, emit_ipc_listener, v8_prop_default,
2222
};
2323

2424
fn send_browser_bool_message(frame: Option<&mut Frame>, route: &str, value: bool) {
@@ -78,19 +78,11 @@ fn eval_preload_script(context: &mut V8Context, script: &str) {
7878
}
7979

8080
#[derive(Clone)]
81-
pub(crate) struct OsrRenderProcessHandler {
82-
string_listeners: IpcListenerSet,
83-
binary_listeners: IpcListenerSet,
84-
data_listeners: IpcListenerSet,
85-
}
81+
pub(crate) struct OsrRenderProcessHandler;
8682

8783
impl OsrRenderProcessHandler {
8884
pub fn new() -> Self {
89-
Self {
90-
string_listeners: IpcListenerSet::new(),
91-
binary_listeners: IpcListenerSet::new(),
92-
data_listeners: IpcListenerSet::new(),
93-
}
85+
Self
9486
}
9587
}
9688

@@ -142,7 +134,6 @@ wrap_render_process_handler! {
142134
let Some(frame) = frame else {
143135
return;
144136
};
145-
146137
let frame_arc = Arc::new(Mutex::new(frame.clone()));
147138

148139
register_v8_function(&global, "sendIpcMessage",
@@ -152,12 +143,8 @@ wrap_render_process_handler! {
152143
register_v8_function(&global, "sendIpcData",
153144
&mut OsrIpcDataHandlerBuilder::build(OsrIpcDataHandler::new(Some(frame_arc.clone()))));
154145

155-
for (name, listeners) in [
156-
("ipcMessage", &self.handler.string_listeners),
157-
("ipcBinaryMessage", &self.handler.binary_listeners),
158-
("ipcDataMessage", &self.handler.data_listeners),
159-
] {
160-
if let Some(mut obj) = listeners.build_api_object() {
146+
for name in ["ipcMessage", "ipcBinaryMessage", "ipcDataMessage"] {
147+
if let Some(mut obj) = build_ipc_listener_object() {
161148
register_v8_value(&global, name, &mut obj);
162149
}
163150
}
@@ -197,19 +184,6 @@ wrap_render_process_handler! {
197184
}
198185
}
199186

200-
fn on_context_released(
201-
&self,
202-
_browser: Option<&mut Browser>,
203-
_frame: Option<&mut Frame>,
204-
_context: Option<&mut V8Context>,
205-
) {
206-
// Listener callbacks hold V8 function references. Clear them when
207-
// a V8 context is released so we don't retain stale callbacks.
208-
self.handler.string_listeners.clear();
209-
self.handler.binary_listeners.clear();
210-
self.handler.data_listeners.clear();
211-
}
212-
213187
fn on_focused_node_changed(&self, _browser: Option<&mut Browser>, frame: Option<&mut Frame>, node: Option<&mut Domnode>) {
214188
if let Some(node) = node
215189
&& node.is_editable() == 1 {
@@ -247,7 +221,7 @@ wrap_render_process_handler! {
247221
{
248222
let msg_cef = args.string(0);
249223
let msg_str = CefStringUtf16::from(&msg_cef);
250-
invoke_js_callback(frame, "onIpcMessage", Some(&self.handler.string_listeners), |_| {
224+
invoke_js_callback(frame, "onIpcMessage", "ipcMessage", |_| {
251225
v8_value_create_string(Some(&msg_str))
252226
});
253227
}
@@ -257,7 +231,7 @@ wrap_render_process_handler! {
257231
if let Some(buffer) = extract_binary_payload(message)
258232
&& let Some(frame) = frame
259233
{
260-
invoke_js_callback(frame, "onIpcBinaryMessage", Some(&self.handler.binary_listeners), |_| {
234+
invoke_js_callback(frame, "onIpcBinaryMessage", "ipcBinaryMessage", |_| {
261235
let mut copy = buffer.clone();
262236
v8_value_create_array_buffer_with_copy(copy.as_mut_ptr(), copy.len())
263237
});
@@ -268,7 +242,7 @@ wrap_render_process_handler! {
268242
if let Some(buffer) = extract_binary_payload(message)
269243
&& let Some(frame) = frame
270244
{
271-
invoke_js_callback(frame, "onIpcDataMessage", Some(&self.handler.data_listeners), |_| {
245+
invoke_js_callback(frame, "onIpcDataMessage", "ipcDataMessage", |_| {
272246
cbor_bytes_to_v8_value(&buffer).ok()
273247
});
274248
}
@@ -315,7 +289,7 @@ fn extract_binary_payload(message: &mut ProcessMessage) -> Option<Vec<u8>> {
315289
fn invoke_js_callback(
316290
frame: &mut Frame,
317291
callback_name: &str,
318-
listeners: Option<&IpcListenerSet>,
292+
listener_api_name: &str,
319293
create_value: impl FnOnce(&mut V8Value) -> Option<V8Value>,
320294
) {
321295
if let Some(context) = frame.v8_context()
@@ -331,8 +305,9 @@ fn invoke_js_callback(
331305
let args = [Some(value.clone())];
332306
let _ = callback.execute_function(Some(&mut global), Some(&args));
333307
}
334-
if let Some(listeners) = listeners {
335-
listeners.emit(&value);
308+
let listener_api_key: CefStringUtf16 = listener_api_name.into();
309+
if let Some(mut listener_api) = global.value_bykey(Some(&listener_api_key)) {
310+
emit_ipc_listener(&mut listener_api, &mut global, &value);
336311
}
337312
}
338313
context.exit();

0 commit comments

Comments
 (0)