pub struct Sk { /* private fields */ }
Expand description
This class contains functions for running the StereoKit library! https://stereokit.net/Pages/StereoKit/SK.html
Implementations§
Source§impl Sk
impl Sk
Sourcepub fn init(settings: &SkSettings) -> Result<Sk, StereoKitError>
pub fn init(settings: &SkSettings) -> Result<Sk, StereoKitError>
Initialize StereoKit with the given settings (here for non Android platform).
Even if this function can be called with the feature event_loop
(for tests) it is more logical to use
init_with_event_loop
.
https://stereokit.net/Pages/StereoKit/SK/Initialize.html
settings
- The settings to use for initialization
It is best to use SkSettings::init
see example with Sk::step
Sourcepub fn step(&self) -> Option<&MainThreadToken>
pub fn step(&self) -> Option<&MainThreadToken>
Steps all StereoKit systems, and inserts user code via callback between the appropriate system updates.
For feature event-loop
you don’t have to call this yourself thanks to SkClosures
.
https://stereokit.net/Pages/StereoKit/SK/Step.html
Returns None
If an exit message is received from the platform, or SK.Quit() is called. Or the MainThreadToken
if a step is to be drawn.
see also sk_step
§Examples
use stereokit_rust::{prelude::*, system::LogLevel};
use stereokit_rust::sk::{Sk, SkSettings, AppMode, QuitReason};
let mut settings = SkSettings::default();
settings
.app_name("Test")
.mode(AppMode::Offscreen);
let sk = Sk::init(&settings).expect("StereoKit should initialize");
let mut iter = 0;
let number_of_steps = 3;
while let Some(token) = sk.step() {
// Main loop where we draw stuff and do things!!
if iter > number_of_steps {sk.quit(None)}
//model.draw(token, transform , None, None);
//mesh.draw(token, &material,transform, None, None);
iter+=1;
}
Sk::shutdown();
Sourcepub fn main_thread_token(&mut self) -> &MainThreadToken
pub fn main_thread_token(&mut self) -> &MainThreadToken
Returns the MainThreadToken that is used to draw stuff.
Sourcepub fn get_active_display_mode(&self) -> DisplayMode
pub fn get_active_display_mode(&self) -> DisplayMode
Since we can fallback to a different DisplayMode, this lets you check to see which Runtime was successfully initialized. https://stereokit.net/Pages/StereoKit/SK/ActiveDisplayMode.html
see also sk_active_display_mode
§Examples
use stereokit_rust::sk::DisplayMode;
let display_mode: DisplayMode = sk.get_active_display_mode();
if cfg!(feature = "test-xr-mode") {
assert_eq!(display_mode, DisplayMode::MixedReality);
} else {
assert_eq!(display_mode, DisplayMode::Flatscreen);
}
Sourcepub fn get_app_focus(&self) -> AppFocus
pub fn get_app_focus(&self) -> AppFocus
This tells about the app’s current focus state, whether it’s active and receiving input, or if it’s backgrounded or hidden. This can be important since apps may still run and render when unfocused, as the app may still be visible behind the app that does have focus. https://stereokit.net/Pages/StereoKit/SK/AppFocus.html
see also sk_app_focus
§Examples
use stereokit_rust::sk::AppFocus;
let display_mode: AppFocus = sk.get_app_focus();
if cfg!(feature = "test-xr-mode") {
// may be AppFocus::Hidden (SteamVR/ALVR) or AppFocus::Active(Monado/Simulator);
} else {
assert_eq!(display_mode, AppFocus::Active);
}
Sourcepub fn get_sk_info_clone(&self) -> Rc<RefCell<SkInfo>>
pub fn get_sk_info_clone(&self) -> Rc<RefCell<SkInfo>>
Return a clone of SkInfo smart pointer https://stereokit.net/Pages/StereoKit/SK.html
see also Sk::get_settings
Sk::get_system
§Examples
use stereokit_rust::sk::{Sk, SkSettings, AppMode, SkInfo};
let sk_info = Some(sk.get_sk_info_clone());
let settings = SkInfo::settings_from(&sk_info);
if cfg!(feature = "test-xr-mode") {
assert_eq!(settings.mode, AppMode::XR);
} else {
assert_eq!(settings.mode, AppMode::Offscreen);
}
let system = SkInfo::system_from(&sk_info);
assert_eq!(system.get_display_width(), 0);
Sourcepub fn get_settings(&self) -> SkSettings
pub fn get_settings(&self) -> SkSettings
This is a copy of the settings that StereoKit was initialized with, so you can refer back to them a little easier. Some of these values will be different than provided, as StereoKit will resolve some default values based on the platform capabilities or internal preference. These are read only, and keep in mind that some settings are only requests! Check SK.System and other properties for the current state of StereoKit. https://stereokit.net/Pages/StereoKit/SK/Settings.html
see also sk_get_settings
§Examples
use stereokit_rust::sk::{Sk, SkSettings, AppMode};
let settings: SkSettings = sk.get_settings();
if cfg!(feature = "test-xr-mode") {
assert_eq!(settings.mode, AppMode::XR);
} else {
assert_eq!(settings.mode, AppMode::Offscreen);
}
Sourcepub fn get_system(&self) -> SystemInfo
pub fn get_system(&self) -> SystemInfo
This structure contains information about the current system and its capabilities. There’s a lot of different MR devices, so it’s nice to have code for systems with particular characteristics! https://stereokit.net/Pages/StereoKit/SK/System.html
see also sk_system_info
§Examples
use stereokit_rust::sk::{Sk, SystemInfo};
let system_info: SystemInfo = sk.get_system();
assert_eq!(system_info.get_display_height(), 0);
Sourcepub fn get_version_id(&self) -> u64
pub fn get_version_id(&self) -> u64
An integer version Id! This is defined using a hex value with this format: 0xMMMMiiiiPPPPrrrr in order of Major.mInor.Patch.pre-Release https://stereokit.net/Pages/StereoKit/SK/VersionId.html
see also sk_version_id
§Examples
assert_ne!(sk.get_version_id(), 0x0);
Sourcepub fn get_version_name(&self) -> &str
pub fn get_version_name(&self) -> &str
Human-readable version name embedded in the StereoKitC library. https://stereokit.net/Pages/StereoKit/SK/VersionName.html
see also sk_version_name
§Examples
assert_ne!(sk.get_version_name(), "3");
Sourcepub fn quit(&self, quit_reason: Option<QuitReason>)
pub fn quit(&self, quit_reason: Option<QuitReason>)
Lets StereoKit know it should quit! It’ll finish the current frame, and after that Step will return that it wants to exit. https://stereokit.net/Pages/StereoKit/SK/Quit.html
quit_reason
- if None has default value of QuitReason::User
see also sk_quit
§Examples
use stereokit_rust::sk::QuitReason;
test_steps!( // !!!! Get a proper main loop !!!!
// Here we can draw some stuff.
//model.draw(token, Matrix::IDENTITY, None, None);
// Quit the app at first step
sk.quit(Some(QuitReason::Error));
);
Sourcepub fn get_quit_reason(&self) -> QuitReason
pub fn get_quit_reason(&self) -> QuitReason
This tells the reason why StereoKit has quit and developer can take appropriate action to debug. https://stereokit.net/Pages/StereoKit/SK/QuitReason.html
§Examples
use stereokit_rust::sk::QuitReason;
// Quit the app before a single step.
sk.quit(Some(QuitReason::User));
// a single step.
sk.step();
assert_eq!(sk.get_quit_reason(), QuitReason::User);
Sourcepub fn shutdown()
pub fn shutdown()
Cleans up all StereoKit initialized systems. Release your own StereoKit created assets before calling this. This
is for cleanup only, and should not be used to exit the application, use Sk::quit
for that instead. Calling
this function is unnecessary if using sk_run_data
`, as it is called automatically there.
https://stereokit.net/Pages/StereoKit/SK/Shutdown.html
see also sk_shutdown
§Examples
use stereokit_rust::sk::QuitReason;
test_steps!( // !!!! Get a proper main loop !!!!
// Here we can draw some stuff.
//model.draw(token, Matrix::IDENTITY, None, None);
// Quit the app at first step
sk.quit(Some(QuitReason::Error));
);
// Shutdown StereoKit
Sk::shutdown();
Source§impl Sk
Sk methods only available for event-loop feature.
impl Sk
Sk methods only available for event-loop feature.
Sourcepub fn init_with_event_loop(
settings: &mut SkSettings,
) -> Result<(Sk, EventLoop<StepperAction>), StereoKitError>
pub fn init_with_event_loop( settings: &mut SkSettings, ) -> Result<(Sk, EventLoop<StepperAction>), StereoKitError>
Initializes StereoKit window, default resources, systems, etc. Here for non Android platforms! https://stereokit.net/Pages/StereoKit/SK/Initialize.html
settings
- The settings to use for initialization.
It is best to use SkSettings::init_with_event_loop
see also sk_init
crate::framework::SkClosures
Sourcepub fn swap_steppers(&mut self, steppers: &mut Steppers)
pub fn swap_steppers(&mut self, steppers: &mut Steppers)
This is a non canonical function that let you swap the current steppers with a new set of steppers https://stereokit.net/Pages/StereoKit.Framework/IStepper.html
steppers
- The new set of steppers to use. This will contain the previous steppers so take care of them.
see example in Steppers
Sourcepub fn execute_on_main<F: FnMut() + 'static>(&mut self, action: F)
pub fn execute_on_main<F: FnMut() + 'static>(&mut self, action: F)
This will queue up some code to be run on StereoKit’s main thread! Immediately after StereoKit’s Step, all callbacks registered here will execute, and then removed from the list. https://stereokit.net/Pages/StereoKit/SK/ExecuteOnMain.html
action
- Some code to run! This Action will persist in a list until after Step, at which point it is removed and dropped.
§Examples
use stereokit_rust::sk::{SkInfo, QuitReason};
let sk_info = Some(sk.get_sk_info_clone());
sk.execute_on_main(move || {
SkInfo::send_event(&sk_info, StepperAction::quit("main", "I'm done!"));
});
test_steps!( // !!!! Get a proper main loop !!!!
// Quit the app after a single step.
);
// 3 steps later we are out
assert_eq!(iter, 3);
Sourcepub fn send_event(&mut self, action: StepperAction)
pub fn send_event(&mut self, action: StepperAction)
Convenient way to push some steppers action.
action
- the action to push
see also SkInfo::send_event
winit::event_loop::EventLoopProxy::send_event
§Examples
use stereokit_rust::{sk::{SkInfo, QuitReason},
tools::{screenshot::{ScreenshotViewer, SHOW_SCREENSHOT_WINDOW},
title::Title}};
sk.send_event(StepperAction::add_default::<ScreenshotViewer>("SCR_ID1"));
sk.send_event(StepperAction::event("main", SHOW_SCREENSHOT_WINDOW, "true"));
let title = Title::new("Title", None, None, None);
sk.send_event(StepperAction::add("TITLE_ID1", title));
test_steps!( // !!!! Get a proper main loop !!!!
if (iter == 1) {
assert_eq!(sk.get_steppers_count(), 2);
// Remove the screenshot viewer after 1 steps.
sk.send_event(StepperAction::remove("SCR_ID1"));
} else if (iter == 2) {
assert_eq!(sk.get_steppers_count(), 1);
// Remove the all the Title ISteppers after 2 steps.
sk.send_event(StepperAction::remove_all(std::any::TypeId::of::<Title>()));
} else if (iter == 3) {
assert_eq!(sk.get_steppers_count(), 0);
sk.send_event(StepperAction::quit("main", "I'm done!"));
}
);
// 6 steps later we are out
assert_eq!(iter, number_of_steps + 3);
Sourcepub fn get_steppers_count(&self) -> usize
pub fn get_steppers_count(&self) -> usize
The number of ISteppers registered in the current Steppers. This does not include Steppers that have been added, but are not yet initialized. Stepper initialization happens at the beginning of the frame, before the app’s Step.
see also Steppers
§Examples
use stereokit_rust::{tools::{screenshot::{ScreenshotViewer, SHOW_SCREENSHOT_WINDOW},
title::Title}};
test_steps!( // !!!! Get a proper main loop !!!!
if iter == 0 {
assert_eq!(sk.get_steppers_count(), 0);
sk.send_event(StepperAction::add_default::<ScreenshotViewer>("SCR_ID1"));
} else if iter == 1 {
assert_eq!(sk.get_steppers_count(), 1);
let title = Title::new("Title", None, None, None);
sk.send_event(StepperAction::add("TITLE_ID1", title));
} else if iter == 2 {
assert_eq!(sk.get_steppers_count(), 2);
sk.send_event(StepperAction::remove("TITLE_ID1"));
} else if iter < number_of_steps + 2 {
assert_eq!(sk.get_steppers_count(), 1);
} else {
assert_eq!(sk.get_steppers_count(), 0);
}
);
// 6 steps later we are out
assert_eq!(iter, number_of_steps + 3);
Sourcepub fn get_steppers(&self) -> &Steppers
pub fn get_steppers(&self) -> &Steppers
Currently active ISteppers registered with Sk
. This does not include Steppers
that have been added, but are not yet initialized. Stepper initialization happens at the beginning of the frame,
before the app’s Step.
§Examples
use stereokit_rust::{tools::{screenshot::{ScreenshotViewer, SHOW_SCREENSHOT_WINDOW},
title::Title}};
sk.send_event(StepperAction::add_default::<ScreenshotViewer>("SCR_ID1"));
let title = Title::new("Title", None, None, None);
sk.send_event(StepperAction::add("TITLE_ID1", title));
let steppers = sk.get_steppers();
assert_eq!(steppers.get_count(), 0);
assert_eq!(sk.get_steppers_count(), 0);
test_steps!( // !!!! Get a proper main loop !!!!
if iter <= number_of_steps + 1 {
let steppers = sk.get_steppers();
assert_eq!(steppers.get_count(), 2);
assert_eq!(sk.get_steppers_count(), 2);
let stepper_list = steppers.get_stepper_handlers();
for (iter, stepper) in stepper_list.iter().enumerate() {
match iter {
0 => assert_eq!(stepper.get_id(), "SCR_ID1"),
1 => assert_eq!(stepper.get_id(), "TITLE_ID1"),
_ => panic!("Only 2 steppers should be present"),
}
}
} else {
let steppers = sk.get_steppers();
assert_eq!(steppers.get_count(), 0);
assert_eq!(sk.get_steppers_count(), 0);
}
);
Sourcepub fn get_event_loop_proxy(&self) -> Option<EventLoopProxy<StepperAction>>
pub fn get_event_loop_proxy(&self) -> Option<EventLoopProxy<StepperAction>>
Get an event_loop_proxy clone to send events
see also SkInfo::event_loop_proxy_from
§Examples
use stereokit_rust::sk::{Sk, SkSettings, AppMode, SkInfo, QuitReason};
use stereokit_rust::framework::SkClosures;
use std::thread;
use std::time::Duration;
let event_loop_proxy = sk.get_event_loop_proxy();
// Spawn a new thread to send an event after a delay
let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(100));
if let Some(proxy) = event_loop_proxy {
proxy.send_event(StepperAction::quit("thread", "I'm done!")).unwrap();
}
});
SkClosures::new(sk, |sk, token| {
// Only the thread can stop this test
// model.draw(token, Matrix::IDENTITY, None, None);
})
.shutdown(|sk| {
assert_eq!(sk.get_quit_reason(), QuitReason::User);
})
.run(event_loop);
// If we are here the thread has finished
handle.join().unwrap();
Sourcepub fn step_looped<F: FnMut(&mut Sk)>(&mut self, on_step: &mut F) -> bool
👎Deprecated since 0.40.0: see [crate::framework::SkClosures] instead
pub fn step_looped<F: FnMut(&mut Sk)>(&mut self, on_step: &mut F) -> bool
Steps all StereoKit systems, and inserts user code via callback between the appropriate system updates. https://stereokit.net/Pages/StereoKit/SK/Step.html
see also sk_step
Sourcepub fn run<U: FnMut(&mut Sk), S: FnMut(&mut Sk)>(
self,
event_loop: EventLoop<StepperAction>,
on_step: U,
on_shutdown: S,
)
👎Deprecated since 0.40.0: see [crate::framework::SkClosures] instead
pub fn run<U: FnMut(&mut Sk), S: FnMut(&mut Sk)>( self, event_loop: EventLoop<StepperAction>, on_step: U, on_shutdown: S, )
This passes application execution over to StereoKit. This continuously steps all StereoKit systems, and inserts user code via callback between the appropriate system updates. Once execution completes, or SK.Quit is called, it properly calls the shutdown callback and shuts down StereoKit for you.
This method is a basic way to handle event_loop. You can, instead, implement this loop in your main thread. https://stereokit.net/Pages/StereoKit/SK/Run.html
see also sk_run_data
Auto Trait Implementations§
impl Freeze for Sk
impl !RefUnwindSafe for Sk
impl !Send for Sk
impl !Sync for Sk
impl Unpin for Sk
impl !UnwindSafe for Sk
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.