Get the magicleap immersive demo to respond to new file name arguments
This commit is contained in:
parent
3bd825196e
commit
1c1eaf20d1
|
@ -12,7 +12,7 @@
|
|||
<uses-privilege ml:name="ControllerPose"/>
|
||||
<component
|
||||
ml:name=".universe"
|
||||
ml:visible_name="Pathfinder Landscape Demo"
|
||||
ml:visible_name="PF Landscape Demo"
|
||||
ml:binary_name="bin/PathfinderLandscapeDemo"
|
||||
ml:type="Universe">
|
||||
<icon
|
||||
|
@ -21,7 +21,7 @@
|
|||
</component>
|
||||
<component
|
||||
ml:name=".fullscreen"
|
||||
ml:visible_name="Pathfinder Immersive Demo"
|
||||
ml:visible_name="PF Immersive Demo"
|
||||
ml:binary_name="bin/PathfinderImmersiveDemo"
|
||||
ml:type="Fullscreen">
|
||||
<mime-type ml:name="image/svg"/>
|
||||
|
|
|
@ -45,6 +45,7 @@ use std::ffi::CStr;
|
|||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use usvg::Options as UsvgOptions;
|
||||
use usvg::Tree;
|
||||
|
@ -55,8 +56,14 @@ mod magicleap;
|
|||
#[cfg(feature = "mocked")]
|
||||
mod mocked_c_api;
|
||||
|
||||
struct ImmersiveApp {
|
||||
sender: mpsc::Sender<Event>,
|
||||
receiver: mpsc::Receiver<Event>,
|
||||
demo: DemoApp<MagicLeapWindow>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn magicleap_pathfinder_demo(egl_display: EGLDisplay, egl_context: EGLContext, file_name: *const c_char) {
|
||||
pub unsafe extern "C" fn magicleap_pathfinder_demo_init(egl_display: EGLDisplay, egl_context: EGLContext) -> *mut c_void {
|
||||
unsafe { c_api::MLLoggingLog(c_api::MLLogLevel::Info, &b"Pathfinder Demo\0"[0], &b"Initializing\0"[0]) };
|
||||
|
||||
let tag = CString::new("Pathfinder Demo").unwrap();
|
||||
|
@ -64,7 +71,7 @@ pub unsafe extern "C" fn magicleap_pathfinder_demo(egl_display: EGLDisplay, egl_
|
|||
let logger = MagicLeapLogger::new(tag, level);
|
||||
log::set_boxed_logger(Box::new(logger)).unwrap();
|
||||
log::set_max_level(level);
|
||||
debug!("Initialized logging");
|
||||
info!("Initialized logging");
|
||||
|
||||
let window = MagicLeapWindow::new(egl_display, egl_context);
|
||||
let window_size = window.size();
|
||||
|
@ -75,25 +82,42 @@ pub unsafe extern "C" fn magicleap_pathfinder_demo(egl_display: EGLDisplay, egl_
|
|||
options.mode = Mode::VR;
|
||||
options.jobs = Some(3);
|
||||
options.pipeline = 0;
|
||||
if let Some(file_name) = file_name.as_ref() {
|
||||
let file_name = CStr::from_ptr(file_name).to_string_lossy().into_owned();
|
||||
options.input_path = SVGPath::Resource(file_name);
|
||||
}
|
||||
|
||||
let mut app = DemoApp::new(window, window_size, options);
|
||||
debug!("Initialized app");
|
||||
let demo = DemoApp::new(window, window_size, options);
|
||||
info!("Initialized app");
|
||||
|
||||
while app.window.running() {
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
Box::into_raw(Box::new(ImmersiveApp { sender, receiver, demo })) as *mut c_void
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn magicleap_pathfinder_demo_run(app: *mut c_void) {
|
||||
let app = app as *mut ImmersiveApp;
|
||||
if let Some(app) = app.as_mut() {
|
||||
while app.demo.window.running() {
|
||||
let mut events = Vec::new();
|
||||
while let Some(event) = app.window.try_get_event() {
|
||||
while let Some(event) = app.demo.window.try_get_event() {
|
||||
events.push(event);
|
||||
}
|
||||
|
||||
let scene_count = app.prepare_frame(events);
|
||||
for scene_index in 0..scene_count {
|
||||
app.draw_scene(scene_index);
|
||||
while let Ok(event) = app.receiver.try_recv() {
|
||||
events.push(event);
|
||||
}
|
||||
app.finish_drawing_frame();
|
||||
let scene_count = app.demo.prepare_frame(events);
|
||||
for scene_index in 0..scene_count {
|
||||
app.demo.draw_scene(scene_index);
|
||||
}
|
||||
app.demo.finish_drawing_frame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn magicleap_pathfinder_demo_load(app: *mut c_void, svg_filename: *const c_char) {
|
||||
let app = app as *mut ImmersiveApp;
|
||||
if let Some(app) = app.as_mut() {
|
||||
let svg_filename = CStr::from_ptr(svg_filename).to_string_lossy().into_owned();
|
||||
info!("Loading {}.", svg_filename);
|
||||
let _ = app.sender.send(Event::OpenSVG(SVGPath::Resource(svg_filename)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,10 @@
|
|||
#include <ml_logging.h>
|
||||
#include <ml_privileges.h>
|
||||
|
||||
// Entry point to the Rust code
|
||||
extern "C" MLResult magicleap_pathfinder_demo(EGLDisplay egl_display, EGLContext egl_context, const char* file_name);
|
||||
// Entry points to the Rust code
|
||||
extern "C" void* magicleap_pathfinder_demo_init(EGLDisplay egl_display, EGLContext egl_context);
|
||||
extern "C" void magicleap_pathfinder_demo_load(void* app, const char* file_name);
|
||||
extern "C" void magicleap_pathfinder_demo_run(void* app);
|
||||
|
||||
// Initialization of the scene thread
|
||||
extern "C" void init_scene_thread(uint64_t id) {
|
||||
|
@ -47,10 +49,6 @@ extern "C" void init_scene_thread(uint64_t id) {
|
|||
const char application_name[] = "com.mozilla.pathfinder.demo";
|
||||
|
||||
// Structures
|
||||
struct application_context_t {
|
||||
int dummy_value;
|
||||
};
|
||||
|
||||
struct graphics_context_t {
|
||||
|
||||
EGLDisplay egl_display;
|
||||
|
@ -116,24 +114,72 @@ graphics_context_t::~graphics_context_t() {
|
|||
}
|
||||
|
||||
// Callbacks
|
||||
static void onStop(void* application_context)
|
||||
static void onStop(void* app)
|
||||
{
|
||||
((struct application_context_t*)application_context)->dummy_value = 0;
|
||||
ML_LOG(Info, "%s: On stop called.", application_name);
|
||||
}
|
||||
|
||||
static void onPause(void* application_context)
|
||||
static void onPause(void* app)
|
||||
{
|
||||
((struct application_context_t*)application_context)->dummy_value = 1;
|
||||
ML_LOG(Info, "%s: On pause called.", application_name);
|
||||
}
|
||||
|
||||
static void onResume(void* application_context)
|
||||
static void onResume(void* app)
|
||||
{
|
||||
((struct application_context_t*)application_context)->dummy_value = 2;
|
||||
ML_LOG(Info, "%s: On resume called.", application_name);
|
||||
}
|
||||
|
||||
static void onNewInitArg(void* app)
|
||||
{
|
||||
ML_LOG(Info, "%s: On new init arg called.", application_name);
|
||||
|
||||
// Get the file argument if there is one
|
||||
MLLifecycleInitArgList* arg_list = nullptr;
|
||||
const MLLifecycleInitArg* arg = nullptr;
|
||||
const MLFileInfo* file_info = nullptr;
|
||||
const char* file_name = nullptr;
|
||||
int64_t arg_list_len = 0;
|
||||
int64_t file_list_len = 0;
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgList(&arg_list)) {
|
||||
ML_LOG(Error, "%s: Failed to get init args.", application_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgListLength(arg_list, &arg_list_len)) {
|
||||
ML_LOG(Error, "%s: Failed to get init arg length.", application_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg_list_len) {
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgByIndex(arg_list, 0, &arg)) {
|
||||
ML_LOG(Error, "%s: Failed to get init arg.", application_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetFileInfoListLength(arg, &file_list_len)) {
|
||||
ML_LOG(Error, "%s: Failed to get file list length.", application_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_list_len) {
|
||||
if (MLResult_Ok != MLLifecycleGetFileInfoByIndex(arg, 0, &file_info)) {
|
||||
ML_LOG(Error, "%s: Failed to get file info.", application_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLFileInfoGetFileName(file_info, &file_name)) {
|
||||
ML_LOG(Error, "%s: Failed to get file name.", application_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Tell pathfinder to load the file
|
||||
magicleap_pathfinder_demo_load(app, file_name);
|
||||
MLLifecycleFreeInitArgList(&arg_list);
|
||||
}
|
||||
|
||||
extern "C" void logMessage(MLLogLevel lvl, char* msg) {
|
||||
if (MLLoggingLogLevelIsEnabled(lvl)) {
|
||||
MLLoggingLog(lvl, ML_DEFAULT_LOG_TAG, msg);
|
||||
|
@ -144,20 +190,7 @@ int main() {
|
|||
// set up host-specific graphics surface
|
||||
graphics_context_t graphics_context;
|
||||
|
||||
// let system know our app has started
|
||||
MLLifecycleCallbacks lifecycle_callbacks = {};
|
||||
lifecycle_callbacks.on_stop = onStop;
|
||||
lifecycle_callbacks.on_pause = onPause;
|
||||
lifecycle_callbacks.on_resume = onResume;
|
||||
|
||||
struct application_context_t application_context;
|
||||
application_context.dummy_value = 2;
|
||||
|
||||
if (MLResult_Ok != MLLifecycleInit(&lifecycle_callbacks, (void*)&application_context)) {
|
||||
ML_LOG(Error, "%s: Failed to initialize lifecycle.", application_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check privileges
|
||||
if (MLResult_Ok != MLPrivilegesStartup()) {
|
||||
ML_LOG(Error, "%s: Failed to initialize privileges.", application_name);
|
||||
return -1;
|
||||
|
@ -182,56 +215,31 @@ int main() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Get the file argument if there is one
|
||||
MLLifecycleInitArgList* arg_list = nullptr;
|
||||
const MLLifecycleInitArg* arg = nullptr;
|
||||
const MLFileInfo* file_info = nullptr;
|
||||
const char* file_name = nullptr;
|
||||
int64_t arg_list_len = 0;
|
||||
int64_t file_list_len = 0;
|
||||
// Initialize pathfinder
|
||||
void* app = magicleap_pathfinder_demo_init(graphics_context.egl_display, graphics_context.egl_context);
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgList(&arg_list)) {
|
||||
ML_LOG(Error, "%s: Failed to get init args.", application_name);
|
||||
// let system know our app has started
|
||||
MLLifecycleCallbacks lifecycle_callbacks = {};
|
||||
lifecycle_callbacks.on_stop = onStop;
|
||||
lifecycle_callbacks.on_pause = onPause;
|
||||
lifecycle_callbacks.on_resume = onResume;
|
||||
lifecycle_callbacks.on_new_initarg = onNewInitArg;
|
||||
|
||||
if (MLResult_Ok != MLLifecycleInit(&lifecycle_callbacks, app)) {
|
||||
ML_LOG(Error, "%s: Failed to initialize lifecycle.", application_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgListLength(arg_list, &arg_list_len)) {
|
||||
ML_LOG(Error, "%s: Failed to get init arg length.", application_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (arg_list_len) {
|
||||
if (MLResult_Ok != MLLifecycleGetInitArgByIndex(arg_list, 0, &arg)) {
|
||||
ML_LOG(Error, "%s: Failed to get init arg.", application_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLLifecycleGetFileInfoListLength(arg, &file_list_len)) {
|
||||
ML_LOG(Error, "%s: Failed to get file list length.", application_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_list_len) {
|
||||
if (MLResult_Ok != MLLifecycleGetFileInfoByIndex(arg, 0, &file_info)) {
|
||||
ML_LOG(Error, "%s: Failed to get file info.", application_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (MLResult_Ok != MLFileInfoGetFileName(file_info, &file_name)) {
|
||||
ML_LOG(Error, "%s: Failed to get file name.", application_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Get the initial argument if there is one.
|
||||
onNewInitArg(app);
|
||||
|
||||
// Run the demo!
|
||||
ML_LOG(Info, "%s: Begin demo (%s).", application_name, file_name);
|
||||
MLResult status = magicleap_pathfinder_demo(graphics_context.egl_display, graphics_context.egl_context, file_name);
|
||||
ML_LOG(Info, "%s: End demo (%d).", application_name, status);
|
||||
ML_LOG(Info, "%s: Begin demo.", application_name);
|
||||
magicleap_pathfinder_demo_run(app);
|
||||
ML_LOG(Info, "%s: End demo.", application_name);
|
||||
|
||||
// Shut down
|
||||
MLPerceptionShutdown();
|
||||
MLLifecycleFreeInitArgList(&arg_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue