Sk

Struct Sk 

Source
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

Source

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

Source

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();
Source

pub fn main_thread_token(&mut self) -> &MainThreadToken

Returns the MainThreadToken that is used to draw stuff.

Source

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);
}
Source

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);
}
Source

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);
Source

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);
}
Source

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);
Source

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);
Source

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");
Source

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));
);
Source

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);
Source

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.

Source

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

Source

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

Source

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);
Source

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);
Source

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);
Source

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);
    }
);
Source

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();
Source

pub fn step_looped<F: FnMut(&mut Sk)>(&mut self, on_step: &mut F) -> bool

👎Deprecated since 0.40.0: see [crate::framework::SkClosures] instead

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

Source

pub 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

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more