/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::mem; use std::net::TcpStream; use base::id::PipelineId; use devtools_traits::DevtoolScriptControlMsg; use ipc_channel::ipc::IpcSender; use serde_json::{Map, Value}; use crate::actor::{Actor, ActorMessageStatus, ActorRegistry}; use crate::actors::timeline::HighResolutionStamp; use crate::StreamId; pub struct FramerateActor { name: String, pipeline: PipelineId, script_sender: IpcSender, is_recording: bool, ticks: Vec, } impl Actor for FramerateActor { fn name(&self) -> String { self.name.clone() } fn handle_message( &self, _registry: &ActorRegistry, _msg_type: &str, _msg: &Map, _stream: &mut TcpStream, _id: StreamId, ) -> Result { Ok(ActorMessageStatus::Ignored) } } impl FramerateActor { /// Return name of actor pub fn create( registry: &ActorRegistry, pipeline_id: PipelineId, script_sender: IpcSender, ) -> String { let actor_name = registry.new_name("framerate"); let mut actor = FramerateActor { name: actor_name.clone(), pipeline: pipeline_id, script_sender, is_recording: false, ticks: Vec::new(), }; actor.start_recording(); registry.register_later(Box::new(actor)); actor_name } pub fn add_tick(&mut self, tick: f64) { self.ticks.push(HighResolutionStamp::wrap(tick)); if self.is_recording { let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, self.name()); self.script_sender.send(msg).unwrap(); } } pub fn take_pending_ticks(&mut self) -> Vec { mem::take(&mut self.ticks) } fn start_recording(&mut self) { if self.is_recording { return; } self.is_recording = true; let msg = DevtoolScriptControlMsg::RequestAnimationFrame(self.pipeline, self.name()); self.script_sender.send(msg).unwrap(); } fn stop_recording(&mut self) { if !self.is_recording { return; } self.is_recording = false; } } impl Drop for FramerateActor { fn drop(&mut self) { self.stop_recording(); } }