pipeline: can now communicate with app

Tell the status of pipeline in the status bar.
This commit is contained in:
Stéphane Cerveau 2022-01-25 18:13:29 +01:00
parent ee66f53171
commit a8e7b039a0
2 changed files with 52 additions and 10 deletions

View file

@ -42,7 +42,7 @@ use crate::{GPS_DEBUG, GPS_ERROR, GPS_INFO, GPS_TRACE, GPS_WARN};
use crate::graphmanager as GM; use crate::graphmanager as GM;
use crate::graphmanager::PropertyExt; use crate::graphmanager::PropertyExt;
use std::fmt;
#[derive(Debug)] #[derive(Debug)]
pub struct GPSAppInner { pub struct GPSAppInner {
pub window: gtk::ApplicationWindow, pub window: gtk::ApplicationWindow,
@ -53,6 +53,21 @@ pub struct GPSAppInner {
pub menu_signal_handlers: RefCell<HashMap<String, SignalHandlerId>>, pub menu_signal_handlers: RefCell<HashMap<String, SignalHandlerId>>,
} }
#[derive(Debug)]
pub enum AppState {
Ready,
Playing,
Paused,
Stopped,
Error,
}
impl fmt::Display for AppState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
// This represents our main application window. // This represents our main application window.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GPSApp(Rc<GPSAppInner>); pub struct GPSApp(Rc<GPSAppInner>);
@ -120,6 +135,8 @@ impl GPSApp {
plugin_list_initialized: OnceCell::new(), plugin_list_initialized: OnceCell::new(),
menu_signal_handlers: RefCell::new(HashMap::new()), menu_signal_handlers: RefCell::new(HashMap::new()),
})); }));
let app_weak = app.downgrade();
app.pipeline.borrow().set_app(app_weak);
app.graphview.borrow_mut().set_id(0); app.graphview.borrow_mut().set_id(0);
Ok(app) Ok(app)
} }
@ -336,6 +353,14 @@ impl GPSApp {
file_chooser.show(); file_chooser.show();
} }
pub fn set_app_state(&self, state: AppState) {
let status_bar: Statusbar = self
.builder
.object("status_bar")
.expect("Couldn't get status_bar");
status_bar.push(status_bar.context_id("Description"), &state.to_string());
}
pub fn build_ui(&self, application: &Application) { pub fn build_ui(&self, application: &Application) {
let drawing_area_window: Viewport = self let drawing_area_window: Viewport = self
.builder .builder
@ -363,12 +388,7 @@ impl GPSApp {
let window = &self.window; let window = &self.window;
window.show(); window.show();
let status_bar: Statusbar = self self.set_app_state(AppState::Ready);
.builder
.object("status_bar")
.expect("Couldn't get status_bar");
status_bar.push(status_bar.context_id("Description"), "GPS is ready");
self.setup_app_actions(application); self.setup_app_actions(application);
let pop_menu: PopoverMenu = self let pop_menu: PopoverMenu = self

View file

@ -17,6 +17,7 @@
// //
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::app::{AppState, GPSApp, GPSAppWeak};
use crate::graphmanager::{GraphView, Node, NodeType, PortDirection, PropertyExt}; use crate::graphmanager::{GraphView, Node, NodeType, PortDirection, PropertyExt};
use crate::logger; use crate::logger;
use crate::GPS_INFO; use crate::GPS_INFO;
@ -35,6 +36,7 @@ pub enum PipelineState {
Playing, Playing,
Paused, Paused,
Stopped, Stopped,
Error,
} }
impl fmt::Display for PipelineState { impl fmt::Display for PipelineState {
@ -66,6 +68,7 @@ impl PipelineWeak {
#[derive(Debug)] #[derive(Debug)]
pub struct PipelineInner { pub struct PipelineInner {
app: RefCell<Option<GPSApp>>,
pipeline: RefCell<Option<gst::Pipeline>>, pipeline: RefCell<Option<gst::Pipeline>>,
current_state: Cell<PipelineState>, current_state: Cell<PipelineState>,
} }
@ -73,6 +76,7 @@ pub struct PipelineInner {
impl Pipeline { impl Pipeline {
pub fn new() -> anyhow::Result<Self> { pub fn new() -> anyhow::Result<Self> {
let pipeline = Pipeline(Rc::new(PipelineInner { let pipeline = Pipeline(Rc::new(PipelineInner {
app: RefCell::new(None),
pipeline: RefCell::new(None), pipeline: RefCell::new(None),
current_state: Cell::new(PipelineState::Stopped), current_state: Cell::new(PipelineState::Stopped),
})); }));
@ -80,6 +84,10 @@ impl Pipeline {
Ok(pipeline) Ok(pipeline)
} }
pub fn set_app(&self, app: GPSAppWeak) {
*self.app.borrow_mut() = Some(app.upgrade().unwrap());
}
pub fn create_pipeline(&self, description: &str) -> anyhow::Result<gstreamer::Pipeline> { pub fn create_pipeline(&self, description: &str) -> anyhow::Result<gstreamer::Pipeline> {
GPS_INFO!("Creating pipeline {}", description); GPS_INFO!("Creating pipeline {}", description);
@ -101,7 +109,7 @@ impl Pipeline {
graphview: &GraphView, graphview: &GraphView,
new_state: PipelineState, new_state: PipelineState,
) -> anyhow::Result<PipelineState> { ) -> anyhow::Result<PipelineState> {
if self.state() == PipelineState::Stopped { if self.state() == PipelineState::Stopped || self.state() == PipelineState::Error {
let pipeline = self let pipeline = self
.create_pipeline(&self.render_gst_launch(graphview)) .create_pipeline(&self.render_gst_launch(graphview))
.map_err(|err| { .map_err(|err| {
@ -132,12 +140,17 @@ impl Pipeline {
match new_state { match new_state {
PipelineState::Playing => pipeline.set_state(gst::State::Playing)?, PipelineState::Playing => pipeline.set_state(gst::State::Playing)?,
PipelineState::Paused => pipeline.set_state(gst::State::Paused)?, PipelineState::Paused => pipeline.set_state(gst::State::Paused)?,
PipelineState::Stopped => { PipelineState::Stopped | PipelineState::Error => {
pipeline.set_state(gst::State::Null)?; pipeline.set_state(gst::State::Null)?;
gst::StateChangeSuccess::Success gst::StateChangeSuccess::Success
} }
}; };
self.current_state.set(new_state); self.current_state.set(new_state);
self.app
.borrow()
.as_ref()
.expect("App should be available")
.set_app_state(Pipeline::state_to_app_state(new_state));
} }
Ok(new_state) Ok(new_state)
} }
@ -146,6 +159,15 @@ impl Pipeline {
self.current_state.get() self.current_state.get()
} }
fn state_to_app_state(state: PipelineState) -> AppState {
match state {
PipelineState::Playing => AppState::Playing,
PipelineState::Paused => AppState::Paused,
PipelineState::Stopped => AppState::Stopped,
PipelineState::Error => AppState::Error,
}
}
pub fn downgrade(&self) -> PipelineWeak { pub fn downgrade(&self) -> PipelineWeak {
PipelineWeak(Rc::downgrade(&self.0)) PipelineWeak(Rc::downgrade(&self.0))
} }
@ -160,7 +182,7 @@ impl Pipeline {
err.error(), err.error(),
err.debug() err.debug()
); );
self.set_state(PipelineState::Stopped) self.set_state(PipelineState::Error)
.expect("Unable to set state to stopped"); .expect("Unable to set state to stopped");
} }
MessageView::Application(msg) => match msg.structure() { MessageView::Application(msg) => match msg.structure() {