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::PropertyExt;
use std::fmt;
#[derive(Debug)]
pub struct GPSAppInner {
pub window: gtk::ApplicationWindow,
@ -53,6 +53,21 @@ pub struct GPSAppInner {
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.
#[derive(Debug, Clone)]
pub struct GPSApp(Rc<GPSAppInner>);
@ -120,6 +135,8 @@ impl GPSApp {
plugin_list_initialized: OnceCell::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);
Ok(app)
}
@ -336,6 +353,14 @@ impl GPSApp {
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) {
let drawing_area_window: Viewport = self
.builder
@ -363,12 +388,7 @@ impl GPSApp {
let window = &self.window;
window.show();
let status_bar: Statusbar = self
.builder
.object("status_bar")
.expect("Couldn't get status_bar");
status_bar.push(status_bar.context_id("Description"), "GPS is ready");
self.set_app_state(AppState::Ready);
self.setup_app_actions(application);
let pop_menu: PopoverMenu = self

View file

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