Fix message loop handling and improve BrowserProcessHandler (#15)
* add: implement MessagePumpChecker for message loop management * update: refactor message loop handling and improve MessagePumpChecker * update: refactor message loop handling to use MessageLoopTimer and improve BrowserProcessHandler * update: reorganize imports and enhance browser process handler integration * update: support Bevy 0.18 and improve message loop handling * update: remove unused FpsOverlayPlugin and clean up dependencies * update: simplify cef and cef-dll-sys version specifications in Cargo.toml --------- Co-authored-by: not-elm <elmgameinfo@gmail.com>
This commit is contained in:
@@ -5,6 +5,7 @@ mod client_handler;
|
||||
mod context_menu_handler;
|
||||
mod display_handler;
|
||||
mod localhost;
|
||||
mod message_pump;
|
||||
mod renderer_handler;
|
||||
mod request_context_handler;
|
||||
|
||||
@@ -14,5 +15,6 @@ pub use browsers::*;
|
||||
pub use client_handler::*;
|
||||
pub use context_menu_handler::*;
|
||||
pub use localhost::*;
|
||||
pub use message_pump::*;
|
||||
pub use renderer_handler::*;
|
||||
pub use request_context_handler::*;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::browser_process::MessageLoopTimer;
|
||||
use crate::browser_process::browser_process_handler::BrowserProcessHandlerBuilder;
|
||||
use crate::util::{SCHEME_CEF, cef_scheme_flags};
|
||||
use cef::rc::{Rc, RcImpl};
|
||||
@@ -6,19 +7,21 @@ use cef::{
|
||||
SchemeRegistrar, WrapApp,
|
||||
};
|
||||
use cef_dll_sys::{_cef_app_t, cef_base_ref_counted_t};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
/// ## Reference
|
||||
///
|
||||
/// - [`CefApp Class Reference`](https://cef-builds.spotifycdn.com/docs/106.1/classCefApp.html)
|
||||
#[derive(Default)]
|
||||
pub struct BrowserProcessAppBuilder {
|
||||
object: *mut RcImpl<_cef_app_t, Self>,
|
||||
message_loop_working_requester: Sender<MessageLoopTimer>,
|
||||
}
|
||||
|
||||
impl BrowserProcessAppBuilder {
|
||||
pub fn build() -> cef::App {
|
||||
pub fn build(message_loop_working_requester: Sender<MessageLoopTimer>) -> cef::App {
|
||||
cef::App::new(Self {
|
||||
object: core::ptr::null_mut(),
|
||||
message_loop_working_requester,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -30,7 +33,10 @@ impl Clone for BrowserProcessAppBuilder {
|
||||
rc_impl.interface.add_ref();
|
||||
self.object
|
||||
};
|
||||
Self { object }
|
||||
Self {
|
||||
object,
|
||||
message_loop_working_requester: self.message_loop_working_requester.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,16 +64,18 @@ impl ImplApp for BrowserProcessAppBuilder {
|
||||
// command_line.append_switch(Some(&" disable-gpu-shader-disk-cache".into()));
|
||||
}
|
||||
|
||||
fn browser_process_handler(&self) -> Option<BrowserProcessHandler> {
|
||||
Some(BrowserProcessHandlerBuilder::build())
|
||||
}
|
||||
|
||||
fn on_register_custom_schemes(&self, registrar: Option<&mut SchemeRegistrar>) {
|
||||
if let Some(registrar) = registrar {
|
||||
registrar.add_custom_scheme(Some(&SCHEME_CEF.into()), cef_scheme_flags() as _);
|
||||
}
|
||||
}
|
||||
|
||||
fn browser_process_handler(&self) -> Option<BrowserProcessHandler> {
|
||||
Some(BrowserProcessHandlerBuilder::build(
|
||||
self.message_loop_working_requester.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_raw(&self) -> *mut _cef_app_t {
|
||||
self.object as *mut cef::sys::_cef_app_t
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
use crate::prelude::MessageLoopTimer;
|
||||
use cef::rc::{Rc, RcImpl};
|
||||
use cef::*;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
/// ## Reference
|
||||
///
|
||||
/// - [`CefBrowserProcessHandler Class Reference`](https://cef-builds.spotifycdn.com/docs/106.1/classCefBrowserProcessHandler.html)
|
||||
pub struct BrowserProcessHandlerBuilder {
|
||||
object: *mut RcImpl<cef_dll_sys::cef_browser_process_handler_t, Self>,
|
||||
message_loop_working_requester: Sender<MessageLoopTimer>,
|
||||
}
|
||||
|
||||
impl BrowserProcessHandlerBuilder {
|
||||
pub fn build() -> BrowserProcessHandler {
|
||||
pub fn build(
|
||||
message_loop_working_requester: Sender<MessageLoopTimer>,
|
||||
) -> BrowserProcessHandler {
|
||||
BrowserProcessHandler::new(Self {
|
||||
object: core::ptr::null_mut(),
|
||||
message_loop_working_requester,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -39,7 +45,10 @@ impl Clone for BrowserProcessHandlerBuilder {
|
||||
rc_impl
|
||||
};
|
||||
|
||||
Self { object }
|
||||
Self {
|
||||
object,
|
||||
message_loop_working_requester: self.message_loop_working_requester.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +65,13 @@ impl ImplBrowserProcessHandler for BrowserProcessHandlerBuilder {
|
||||
command_line.append_switch(Some(&"ignore-ssl-errors".into()));
|
||||
command_line.append_switch(Some(&"enable-logging=stderr".into()));
|
||||
}
|
||||
|
||||
fn on_schedule_message_pump_work(&self, delay_ms: i64) {
|
||||
let _ = self
|
||||
.message_loop_working_requester
|
||||
.send(MessageLoopTimer::new(delay_ms));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_raw(&self) -> *mut cef_dll_sys::_cef_browser_process_handler_t {
|
||||
self.object.cast()
|
||||
|
||||
39
crates/bevy_cef_core/src/browser_process/message_pump.rs
Normal file
39
crates/bevy_cef_core/src/browser_process/message_pump.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use bevy::prelude::Deref;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Maximum delay between message loop iterations (~30fps).
|
||||
/// Following CEF's official cefclient pattern (`kMaxTimerDelay = 1000/30`).
|
||||
const MAX_TIMER_DELAY_MS: u64 = 1000 / 30;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Deref)]
|
||||
pub struct MessageLoopWorkingReceiver(pub Receiver<MessageLoopTimer>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MessageLoopTimer(Instant);
|
||||
|
||||
impl MessageLoopTimer {
|
||||
pub fn new(delay_ms: i64) -> Self {
|
||||
let fire_time = if delay_ms <= 0 {
|
||||
Instant::now()
|
||||
} else {
|
||||
Instant::now() + Duration::from_millis(delay_ms as u64)
|
||||
};
|
||||
Self(fire_time)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_finished(&self) -> bool {
|
||||
self.0 <= Instant::now()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deref)]
|
||||
pub struct MessageLoopWorkingMaxDelayTimer(MessageLoopTimer);
|
||||
|
||||
impl Default for MessageLoopWorkingMaxDelayTimer {
|
||||
fn default() -> Self {
|
||||
Self(MessageLoopTimer::new(MAX_TIMER_DELAY_MS as i64))
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
mod browser_process;
|
||||
#[cfg(target_os = "macos")]
|
||||
mod debug;
|
||||
|
||||
mod render_process;
|
||||
mod util;
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ impl ImplApp for RenderProcessAppBuilder {
|
||||
}
|
||||
|
||||
impl WrapApp for RenderProcessAppBuilder {
|
||||
#[inline]
|
||||
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_app_t, Self>) {
|
||||
self.object = object;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user