From a01f1385ece06637a8df0e5b2de50fa31b03903d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 12 Nov 2017 19:07:02 +0100 Subject: [PATCH] examples: Set up a runloop on macOS --- examples/src/bin/appsink.rs | 11 ++++++++++- examples/src/bin/appsrc.rs | 11 ++++++++++- examples/src/bin/decodebin.rs | 11 ++++++++++- examples/src/bin/events.rs | 11 ++++++++++- examples/src/bin/iterator.rs | 11 ++++++++++- examples/src/bin/launch.rs | 11 ++++++++++- examples/src/bin/launch_glib_main.rs | 11 ++++++++++- examples/src/bin/pad_probes.rs | 11 ++++++++++- examples/src/bin/playbin.rs | 11 ++++++++++- examples/src/bin/player.rs | 12 +++++++++++- examples/src/bin/queries.rs | 11 ++++++++++- examples/src/bin/toc.rs | 11 ++++++++++- examples/src/bin/tokio.rs | 13 ++++++++++++- examples/src/examples-common.rs | 23 +++++++++++++++++++++++ 14 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 examples/src/examples-common.rs diff --git a/examples/src/bin/appsink.rs b/examples/src/bin/appsink.rs index 2c6ec7131..f6f6d7f41 100644 --- a/examples/src/bin/appsink.rs +++ b/examples/src/bin/appsink.rs @@ -19,6 +19,9 @@ use failure::Error; #[macro_use] extern crate failure_derive; +#[path = "../examples-common.rs"] +mod examples_common; + #[derive(Debug, Fail)] #[fail(display = "Missing element {}", _0)] struct MissingElement(&'static str); @@ -152,9 +155,15 @@ fn main_loop(pipeline: gst::Pipeline) -> Result<(), Error> { Ok(()) } -fn main() { +fn example_main() { match create_pipeline().and_then(main_loop) { Ok(r) => r, 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); +} diff --git a/examples/src/bin/appsrc.rs b/examples/src/bin/appsrc.rs index f632ed8c3..c95978a3a 100644 --- a/examples/src/bin/appsrc.rs +++ b/examples/src/bin/appsrc.rs @@ -15,6 +15,9 @@ use failure::Error; #[macro_use] extern crate failure_derive; +#[path = "../examples-common.rs"] +mod examples_common; + #[derive(Debug, Fail)] #[fail(display = "Missing element {}", _0)] struct MissingElement(&'static str); @@ -123,9 +126,15 @@ fn main_loop(pipeline: gst::Pipeline, appsrc: gst_app::AppSrc) -> Result<(), Err Ok(()) } -fn main() { +fn example_main() { match create_pipeline().and_then(|(pipeline, appsrc)| main_loop(pipeline, appsrc)) { Ok(r) => r, 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); +} diff --git a/examples/src/bin/decodebin.rs b/examples/src/bin/decodebin.rs index 42f2e6e2e..0efcd413d 100644 --- a/examples/src/bin/decodebin.rs +++ b/examples/src/bin/decodebin.rs @@ -5,7 +5,10 @@ extern crate glib; use std::env; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().unwrap(); let args: Vec<_> = env::args().collect(); @@ -113,3 +116,9 @@ fn main() { 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); +} diff --git a/examples/src/bin/events.rs b/examples/src/bin/events.rs index 1f4c79581..584e051b9 100644 --- a/examples/src/bin/events.rs +++ b/examples/src/bin/events.rs @@ -3,7 +3,10 @@ use gst::prelude::*; extern crate glib; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().unwrap(); let main_loop = glib::MainLoop::new(None, false); @@ -59,3 +62,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/iterator.rs b/examples/src/bin/iterator.rs index 37164f289..8175b560f 100644 --- a/examples/src/bin/iterator.rs +++ b/examples/src/bin/iterator.rs @@ -1,7 +1,10 @@ extern crate gstreamer as gst; use gst::prelude::*; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().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); +} diff --git a/examples/src/bin/launch.rs b/examples/src/bin/launch.rs index 54760923e..1b6a4dce7 100644 --- a/examples/src/bin/launch.rs +++ b/examples/src/bin/launch.rs @@ -4,7 +4,10 @@ use gst::prelude::*; use std::env; use std::process; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { let pipeline_str = env::args().collect::>()[1..].join(" "); gst::init().unwrap(); @@ -49,3 +52,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/launch_glib_main.rs b/examples/src/bin/launch_glib_main.rs index 06db2c71e..cf6f5db5d 100644 --- a/examples/src/bin/launch_glib_main.rs +++ b/examples/src/bin/launch_glib_main.rs @@ -5,7 +5,10 @@ extern crate glib; use std::env; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { let pipeline_str = env::args().collect::>()[1..].join(" "); gst::init().unwrap(); @@ -48,3 +51,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/pad_probes.rs b/examples/src/bin/pad_probes.rs index 0ab29546b..927488b0b 100644 --- a/examples/src/bin/pad_probes.rs +++ b/examples/src/bin/pad_probes.rs @@ -7,7 +7,10 @@ use byte_slice_cast::*; use std::i16; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().unwrap(); let pipeline = gst::parse_launch(&format!( @@ -71,3 +74,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/playbin.rs b/examples/src/bin/playbin.rs index 01b8b0881..4be959652 100644 --- a/examples/src/bin/playbin.rs +++ b/examples/src/bin/playbin.rs @@ -5,7 +5,10 @@ extern crate glib; use std::env; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().unwrap(); let args: Vec<_> = env::args().collect(); @@ -86,3 +89,9 @@ fn main() { let ret = playbin.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/player.rs b/examples/src/bin/player.rs index 6807cd24a..ecbab7180 100644 --- a/examples/src/bin/player.rs +++ b/examples/src/bin/player.rs @@ -17,6 +17,10 @@ extern crate failure; #[allow(unused_imports)] use failure::Error; +#[allow(unused_imports)] +#[path = "../examples-common.rs"] +mod examples_common; + #[cfg(feature = "gst-player")] fn main_loop(uri: &str) -> Result<(), Error> { gst::init()?; @@ -65,7 +69,7 @@ fn main_loop(uri: &str) -> Result<(), Error> { } #[allow(unused_variables)] -fn main() { +fn example_main() { let args: Vec<_> = env::args().collect(); let uri: &str = if args.len() == 2 { args[1].as_ref() @@ -86,3 +90,9 @@ fn main() { 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); +} diff --git a/examples/src/bin/queries.rs b/examples/src/bin/queries.rs index e283f24fb..2bb02e695 100644 --- a/examples/src/bin/queries.rs +++ b/examples/src/bin/queries.rs @@ -5,7 +5,10 @@ extern crate glib; use std::env; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { let pipeline_str = env::args().collect::>()[1..].join(" "); gst::init().unwrap(); @@ -87,3 +90,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); 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); +} diff --git a/examples/src/bin/toc.rs b/examples/src/bin/toc.rs index 71b30a25e..18bbb8d3f 100644 --- a/examples/src/bin/toc.rs +++ b/examples/src/bin/toc.rs @@ -5,7 +5,10 @@ extern crate glib; use std::env; -fn main() { +#[path = "../examples-common.rs"] +mod examples_common; + +fn example_main() { gst::init().unwrap(); let args: Vec<_> = env::args().collect(); @@ -112,3 +115,9 @@ fn main() { 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); +} diff --git a/examples/src/bin/tokio.rs b/examples/src/bin/tokio.rs index 82f7b9158..36f570803 100644 --- a/examples/src/bin/tokio.rs +++ b/examples/src/bin/tokio.rs @@ -15,8 +15,12 @@ use tokio_core::reactor::Core; #[cfg(feature = "tokio")] use std::env; +#[allow(unused_imports)] +#[path = "../examples-common.rs"] +mod examples_common; + #[cfg(feature = "tokio")] -fn main() { +fn example_main() { let pipeline_str = env::args().collect::>()[1..].join(" "); gst::init().unwrap(); @@ -59,6 +63,13 @@ fn main() { 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"))] fn main() { println!("Please compile with --features tokio"); diff --git a/examples/src/examples-common.rs b/examples/src/examples-common.rs new file mode 100644 index 000000000..715cf5151 --- /dev/null +++ b/examples/src/examples-common.rs @@ -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(main: F) { + main(); +} + +#[cfg(target_os = "macos")] +pub fn run(main: F) { + ::std::thread::spawn(main); + unsafe { + CFRunLoopRun(); + } +}