devtools/actors/
framerate.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::mem;
6
7use base::id::PipelineId;
8use devtools_traits::DevtoolScriptControlMsg;
9use ipc_channel::ipc::IpcSender;
10use serde_json::{Map, Value};
11
12use crate::StreamId;
13use crate::actor::{Actor, ActorError, ActorRegistry};
14use crate::actors::timeline::HighResolutionStamp;
15use crate::protocol::ClientRequest;
16
17pub struct FramerateActor {
18    name: String,
19    pipeline_id: PipelineId,
20    script_sender: IpcSender<DevtoolScriptControlMsg>,
21    is_recording: bool,
22    ticks: Vec<HighResolutionStamp>,
23}
24
25impl Actor for FramerateActor {
26    fn name(&self) -> String {
27        self.name.clone()
28    }
29
30    fn handle_message(
31        &self,
32        _request: ClientRequest,
33        _registry: &ActorRegistry,
34        _msg_type: &str,
35        _msg: &Map<String, Value>,
36        _id: StreamId,
37    ) -> Result<(), ActorError> {
38        Err(ActorError::UnrecognizedPacketType)
39    }
40}
41
42impl FramerateActor {
43    /// Return name of actor
44    pub fn create(
45        registry: &ActorRegistry,
46        pipeline_id: PipelineId,
47        script_sender: IpcSender<DevtoolScriptControlMsg>,
48    ) -> String {
49        let actor_name = registry.new_name("framerate");
50        let mut actor = FramerateActor {
51            name: actor_name.clone(),
52            pipeline_id,
53            script_sender,
54            is_recording: false,
55            ticks: Vec::new(),
56        };
57
58        actor.start_recording();
59        registry.register_later(Box::new(actor));
60        actor_name
61    }
62
63    pub fn add_tick(&mut self, tick: f64) {
64        self.ticks.push(HighResolutionStamp::wrap(tick));
65
66        if self.is_recording {
67            let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline_id, self.name());
68            self.script_sender.send(msg).unwrap();
69        }
70    }
71
72    pub fn take_pending_ticks(&mut self) -> Vec<HighResolutionStamp> {
73        mem::take(&mut self.ticks)
74    }
75
76    fn start_recording(&mut self) {
77        if self.is_recording {
78            return;
79        }
80
81        self.is_recording = true;
82
83        let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline_id, self.name());
84        self.script_sender.send(msg).unwrap();
85    }
86
87    fn stop_recording(&mut self) {
88        if !self.is_recording {
89            return;
90        }
91        self.is_recording = false;
92    }
93}
94
95impl Drop for FramerateActor {
96    fn drop(&mut self) {
97        self.stop_recording();
98    }
99}