Struct TaskPoolHandler

Source
pub struct TaskPoolHandler { /* private fields */ }
Expand description

Asynchronous task handler is used as an executor for async functions (tasks), that in addition to them has a closure, that will be called when a task is finished. The main use case for such tasks is to off-thread a heavy task to one of background threads (from a thread pool on PC, or a microtask on WebAssembly) and when it is done, incorporate its result in your game’s state. A task and its “on-complete” closure could be pretty much anything: procedural world generation + adding a generated scene to the engine, asset loading + its instantiation, etc. It should be noted that a task itself is executed asynchronously (in other thread), while a closure - synchronously, just at the beginning of the next game loop iteration. This means, that you should never put heavy tasks into the closure, otherwise it will result in quite notable stutters.

There are two main methods - TaskPoolHandler::spawn_plugin_task and TaskPoolHandler::spawn_script_task. They are somewhat similar, but the main difference between them is that the first one operates on per plugin basis and the latter operates on scene node basis. This means that in case of TaskPoolHandler::spawn_plugin_task, it will accept an async task and when it is finished, it will give you a result of the task and access to the plugin from which it was called, so you can do some actions with the result. TaskPoolHandler::spawn_script_task does somewhat the same, but on a scene node basis - when a task is done, the “on-complete” closure will be provided with a wide context, allowing you to modify the caller’s node state. See the docs for the respective methods for more info.

Implementations§

Source§

impl TaskPoolHandler

Source

pub fn spawn_plugin_task<F, T, P, C>(&mut self, future: F, on_complete: C)
where F: AsyncTask<T>, T: AsyncTaskResult, P: Plugin, for<'a, 'b> C: Fn(T, &mut P, &mut PluginContext<'a, 'b>) + 'static,

Spawns a task represented by the future, that does something and then adds the result to a plugin it was called from using the on_complete closure.

§Example

#[derive(Visit, Reflect, Debug)]
struct MyGame {
    data: Option<Vec<u8>>,
}

impl MyGame {
    pub fn new(context: PluginContext) -> Self {
        context.task_pool.spawn_plugin_task(
            // Emulate heavy task by reading a potentially large file. The game will be fully
            // responsive while it runs.
            async move {
                let mut file = File::open("some/file.txt").unwrap();
                let mut data = Vec::new();
                file.read_to_end(&mut data).unwrap();
                data
            },
            // This closure is called when the future above has finished, but not immediately - on
            // the next update iteration.
            |data, game: &mut MyGame, _context| {
                // Store the data in the game instance.
                game.data = Some(data);
            },
        );

        // Immediately return the new game instance with empty data.
        Self { data: None }
    }
}

impl Plugin for MyGame {
    fn update(&mut self, _context: &mut PluginContext) {
        // Do something with the data.
        if let Some(data) = self.data.take() {
            println!("The data is: {:?}", data);
        }
    }
}
Source

pub fn spawn_script_task<F, T, C, S>( &mut self, scene_handle: Handle<Scene>, node_handle: Handle<Node>, script_index: usize, future: F, on_complete: C, )
where F: AsyncTask<T>, T: AsyncTaskResult, for<'a, 'b, 'c> C: Fn(T, &mut S, &mut ScriptContext<'a, 'b, 'c>) + 'static, S: ScriptTrait,

Spawns a task represented by the future, that does something and then adds the result to a scene node’s script using the on_complete closure. This method could be used to off-thread some heavy work from usual update routine (for example - pathfinding).

§Examples
#[derive(Reflect, Visit, Default, Debug, Clone)]
struct MyScript;


impl ScriptTrait for MyScript {
    fn on_start(&mut self, ctx: &mut ScriptContext) {
        ctx.task_pool.spawn_script_task(
            ctx.scene_handle,
            ctx.handle,
            ctx.script_index,
            // Request loading of some heavy asset. It does not actually does the loading in the
            // same routine, since asset loading itself is asynchronous, but we can't block the
            // current thread on all support platforms to wait until the loading is done. So we
            // have to use this approach to load assets on demand. Since every asset implements
            // Future trait, it can be used directly as a future. Alternatively, you can use async
            // move { } block here.
            ctx.resource_manager.request::<Model>("path/to/model.fbx"),
            // This closure will executed only when the upper future is done and only on the next
            // update iteration.
            |result, script: &mut MyScript, ctx| {
                if let Ok(model) = result {
                    model.instantiate(&mut ctx.scene);
                }
            },
        );
    }
}
Source

pub fn inner(&self) -> &Arc<TaskPool>

Returns a reference to the underlying, low level task pool, that could be used to for special cases.

Auto Trait Implementations§

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> Downcast for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts self reference as a reference to Any. Could be used to downcast a trait object to a particular type.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts self reference as a reference to Any. Could be used to downcast a trait object to a particular type.
Source§

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

Source§

impl<T> FieldValue for T
where T: 'static,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Casts self to a &dyn Any
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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