separate waking the event loop, from communicating with a compositor

This commit is contained in:
Gregory Terzian 2017-05-28 11:43:49 +08:00
parent eac4f407e2
commit 3a693c7a23
9 changed files with 103 additions and 108 deletions

View file

@ -22,32 +22,46 @@ use style_traits::viewport::ViewportConstraints;
use webrender;
use webrender_traits;
/// Sends messages to the compositor. This is a trait supplied by the port because the method used
/// to communicate with the compositor may have to kick OS event loops awake, communicate cross-
/// process, and so forth.
pub trait CompositorProxy : 'static + Send {
/// Sends a message to the compositor.
fn send(&self, msg: Msg);
/// Clones the compositor proxy.
fn clone_compositor_proxy(&self) -> Box<CompositorProxy + 'static + Send>;
/// Used to wake up the event loop, provided by the servo port/embedder.
pub trait EventLoopWaker : 'static + Send {
fn clone(&self) -> Box<EventLoopWaker + Send>;
fn wake(&self);
}
/// The port that the compositor receives messages on. As above, this is a trait supplied by the
/// Servo port.
pub trait CompositorReceiver : 'static {
/// Receives the next message inbound for the compositor. This must not block.
fn try_recv_compositor_msg(&mut self) -> Option<Msg>;
/// Synchronously waits for, and returns, the next message inbound for the compositor.
fn recv_compositor_msg(&mut self) -> Msg;
/// Sends messages to the compositor.
pub struct CompositorProxy {
pub sender: Sender<Msg>,
pub event_loop_waker: Box<EventLoopWaker>,
}
/// A convenience implementation of `CompositorReceiver` for a plain old Rust `Receiver`.
impl CompositorReceiver for Receiver<Msg> {
fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
self.try_recv().ok()
impl CompositorProxy {
pub fn send(&self, msg: Msg) {
// Send a message and kick the OS event loop awake.
if let Err(err) = self.sender.send(msg) {
warn!("Failed to send response ({}).", err);
}
self.event_loop_waker.wake();
}
fn recv_compositor_msg(&mut self) -> Msg {
self.recv().unwrap()
pub fn clone_compositor_proxy(&self) -> CompositorProxy {
CompositorProxy {
sender: self.sender.clone(),
event_loop_waker: self.event_loop_waker.clone(),
}
}
}
/// The port that the compositor receives messages on.
pub struct CompositorReceiver {
pub receiver: Receiver<Msg>
}
impl CompositorReceiver {
pub fn try_recv_compositor_msg(&mut self) -> Option<Msg> {
self.receiver.try_recv().ok()
}
pub fn recv_compositor_msg(&mut self) -> Msg {
self.receiver.recv().unwrap()
}
}
@ -55,7 +69,7 @@ pub trait RenderListener {
fn recomposite(&mut self, reason: CompositingReason);
}
impl RenderListener for Box<CompositorProxy + 'static> {
impl RenderListener for CompositorProxy {
fn recomposite(&mut self, reason: CompositingReason) {
self.send(Msg::Recomposite(reason));
}
@ -173,9 +187,9 @@ impl Debug for Msg {
/// Data used to construct a compositor.
pub struct InitialCompositorState {
/// A channel to the compositor.
pub sender: Box<CompositorProxy + Send>,
pub sender: CompositorProxy,
/// A port on which messages inbound to the compositor can be received.
pub receiver: Box<CompositorReceiver>,
pub receiver: CompositorReceiver,
/// A channel to the constellation.
pub constellation_chan: Sender<ConstellationMsg>,
/// A channel to the time profiler thread.