examples: Set up a runloop on macOS

This commit is contained in:
Sebastian Dröge 2017-11-12 19:07:02 +01:00
parent 10151b9f0d
commit a01f1385ec
14 changed files with 156 additions and 13 deletions

View file

@ -19,6 +19,9 @@ use failure::Error;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[path = "../examples-common.rs"]
mod examples_common;
#[derive(Debug, Fail)] #[derive(Debug, Fail)]
#[fail(display = "Missing element {}", _0)] #[fail(display = "Missing element {}", _0)]
struct MissingElement(&'static str); struct MissingElement(&'static str);
@ -152,9 +155,15 @@ fn main_loop(pipeline: gst::Pipeline) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn main() { fn example_main() {
match create_pipeline().and_then(main_loop) { match create_pipeline().and_then(main_loop) {
Ok(r) => r, Ok(r) => r,
Err(e) => eprintln!("Error! {}", e), Err(e) => eprintln!("Error! {}", e),
} }
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -15,6 +15,9 @@ use failure::Error;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[path = "../examples-common.rs"]
mod examples_common;
#[derive(Debug, Fail)] #[derive(Debug, Fail)]
#[fail(display = "Missing element {}", _0)] #[fail(display = "Missing element {}", _0)]
struct MissingElement(&'static str); struct MissingElement(&'static str);
@ -123,9 +126,15 @@ fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Err
Ok(()) Ok(())
} }
fn main() { fn example_main() {
match create_pipeline().and_then(|(pipeline, appsrc)| main_loop(pipeline, appsrc)) { match create_pipeline().and_then(|(pipeline, appsrc)| main_loop(pipeline, appsrc)) {
Ok(r) => r, Ok(r) => r,
Err(e) => eprintln!("Error! {}", e), Err(e) => eprintln!("Error! {}", e),
} }
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -5,7 +5,10 @@ extern crate glib;
use std::env; use std::env;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let args: Vec<_> = env::args().collect(); let args: Vec<_> = env::args().collect();
@ -113,3 +116,9 @@ fn main() {
gst::StateChangeReturn::Failure gst::StateChangeReturn::Failure
); );
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -3,7 +3,10 @@ use gst::prelude::*;
extern crate glib; extern crate glib;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let main_loop = glib::MainLoop::new(None, false); let main_loop = glib::MainLoop::new(None, false);
@ -59,3 +62,9 @@ fn main() {
let ret = pipeline.set_state(gst::State::Null); let ret = pipeline.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -1,7 +1,10 @@
extern crate gstreamer as gst; extern crate gstreamer as gst;
use gst::prelude::*; use gst::prelude::*;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let identity = gst::ElementFactory::make("identity", None).unwrap(); let identity = gst::ElementFactory::make("identity", None).unwrap();
@ -20,3 +23,9 @@ fn main() {
} }
} }
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -4,7 +4,10 @@ use gst::prelude::*;
use std::env; use std::env;
use std::process; use std::process;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" "); let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" ");
gst::init().unwrap(); gst::init().unwrap();
@ -49,3 +52,9 @@ fn main() {
let ret = pipeline.set_state(gst::State::Null); let ret = pipeline.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -5,7 +5,10 @@ extern crate glib;
use std::env; use std::env;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" "); let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" ");
gst::init().unwrap(); gst::init().unwrap();
@ -48,3 +51,9 @@ fn main() {
let ret = pipeline.set_state(gst::State::Null); let ret = pipeline.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -7,7 +7,10 @@ use byte_slice_cast::*;
use std::i16; use std::i16;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let pipeline = gst::parse_launch(&format!( let pipeline = gst::parse_launch(&format!(
@ -71,3 +74,9 @@ fn main() {
let ret = pipeline.set_state(gst::State::Null); let ret = pipeline.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -5,7 +5,10 @@ extern crate glib;
use std::env; use std::env;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let args: Vec<_> = env::args().collect(); let args: Vec<_> = env::args().collect();
@ -86,3 +89,9 @@ fn main() {
let ret = playbin.set_state(gst::State::Null); let ret = playbin.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -17,6 +17,10 @@ extern crate failure;
#[allow(unused_imports)] #[allow(unused_imports)]
use failure::Error; use failure::Error;
#[allow(unused_imports)]
#[path = "../examples-common.rs"]
mod examples_common;
#[cfg(feature = "gst-player")] #[cfg(feature = "gst-player")]
fn main_loop(uri: &str) -> Result<(), Error> { fn main_loop(uri: &str) -> Result<(), Error> {
gst::init()?; gst::init()?;
@ -65,7 +69,7 @@ fn main_loop(uri: &str) -> Result<(), Error> {
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn main() { fn example_main() {
let args: Vec<_> = env::args().collect(); let args: Vec<_> = env::args().collect();
let uri: &str = if args.len() == 2 { let uri: &str = if args.len() == 2 {
args[1].as_ref() args[1].as_ref()
@ -86,3 +90,9 @@ fn main() {
Err(e) => eprintln!("Error! {}", e), Err(e) => eprintln!("Error! {}", e),
} }
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -5,7 +5,10 @@ extern crate glib;
use std::env; use std::env;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" "); let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" ");
gst::init().unwrap(); gst::init().unwrap();
@ -87,3 +90,9 @@ fn main() {
let ret = pipeline.set_state(gst::State::Null); let ret = pipeline.set_state(gst::State::Null);
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -5,7 +5,10 @@ extern crate glib;
use std::env; use std::env;
fn main() { #[path = "../examples-common.rs"]
mod examples_common;
fn example_main() {
gst::init().unwrap(); gst::init().unwrap();
let args: Vec<_> = env::args().collect(); let args: Vec<_> = env::args().collect();
@ -112,3 +115,9 @@ fn main() {
gst::StateChangeReturn::Failure gst::StateChangeReturn::Failure
); );
} }
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}

View file

@ -15,8 +15,12 @@ use tokio_core::reactor::Core;
#[cfg(feature = "tokio")] #[cfg(feature = "tokio")]
use std::env; use std::env;
#[allow(unused_imports)]
#[path = "../examples-common.rs"]
mod examples_common;
#[cfg(feature = "tokio")] #[cfg(feature = "tokio")]
fn main() { fn example_main() {
let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" "); let pipeline_str = env::args().collect::<Vec<String>>()[1..].join(" ");
gst::init().unwrap(); gst::init().unwrap();
@ -59,6 +63,13 @@ fn main() {
assert_ne!(ret, gst::StateChangeReturn::Failure); assert_ne!(ret, gst::StateChangeReturn::Failure);
} }
#[cfg(feature = "tokio")]
fn main() {
// tutorials_common::run is only required to set up the application environent on macOS
// (but not necessary in normal Cocoa applications where this is set up autmatically)
examples_common::run(example_main);
}
#[cfg(not(feature = "tokio"))] #[cfg(not(feature = "tokio"))]
fn main() { fn main() {
println!("Please compile with --features tokio"); println!("Please compile with --features tokio");

View file

@ -0,0 +1,23 @@
/// macOS has a specific requirement that there must be a run loop running
/// on the main thread in order to open windows and use OpenGL.
#[cfg(target_os = "macos")]
#[link(name = "foundation", kind = "framework")]
extern "C" {
fn CFRunLoopRun();
}
/// On macOS this launches the callback function on a thread.
/// On other platforms it's just executed immediately.
#[cfg(not(target_os = "macos"))]
pub fn run<F: FnOnce() + Send + 'static>(main: F) {
main();
}
#[cfg(target_os = "macos")]
pub fn run<F: FnOnce() + Send + 'static>(main: F) {
::std::thread::spawn(main);
unsafe {
CFRunLoopRun();
}
}