A Rust promise for games and immediate mode GUIs

Overview

poll-promise

A Rust promise for games and immediate mode GUIs

Embark Embark Crates.io Docs dependency status Build status

Description

poll-promise is a Rust crate for polling the result of a concurrent (e.g. async) operation. This is in particular useful in games and immediate mode GUI:s, where one often wants to start a background operation and then ask "are we there yet?" on each subsequent frame until the operation completes.

Example:

let promise = poll_promise::Promise::spawn_thread("slow_operation", something_slow);

// Then in the game loop or immediate mode GUI code:
if let Some(result) = promise.ready() {
    // Use/show result
} else {
    // Show a loading icon
}

If you enable the tokio feature you can use poll-promise with the tokio runtime.

Caveat

The crate is primarily useful as a high-level building block in apps.

This crate provides convenience methods to spawn threads and tokio tasks, and methods that block on waiting for a result. This is gererally a bad idea to do in a library, as decisions about execution environments and thread blocking should be left to the app. So we do not recommend using this crate for libraries in its current state.

See also

Similar functionality is provided by:

Contribution

Contributor Covenant

We welcome community contributions to this project.

Please read our Contributor Guide for more information on how to get started. Please also read our Contributor Terms before you make any contributions.

Any contribution intentionally submitted for inclusion in an Embark Studios project, shall comply with the Rust standard licensing model (MIT OR Apache 2.0) and therefore be dual licensed as described below, without any additional terms or conditions:

License

This contribution is dual licensed under EITHER OF

at your option.

For clarity, "your" refers to Embark or any other licensee/user of the contribution.

Comments
  • Fix undefined behavior by introducing use of  `UnsafeCell`

    Fix undefined behavior by introducing use of `UnsafeCell`

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Mutating through a shared reference without an UnsafeCell is UB. From the UnsafeCell docs:

    If you have a reference &T, then normally in Rust the compiler performs optimizations based on the knowledge that &T points to immutable data. Mutating that data, for example through an alias or by transmuting an &T into an &mut T, is considered undefined behavior.

    unsafe {
          let myself = self as *const Self as *mut Self;
          *myself = Self::Ready(value);
    }
    

    ^ is thus UB

    opened by Nehliin 2
  • Support smol as an executor and add Promise::spawn_local

    Support smol as an executor and add Promise::spawn_local

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Smol is now a supported executor. With it comes two new functions:

    // Ticks the smol thread executor
    poll_promise::tick();
    // Ticks the thread local smol executor
    poll_promise::tick_local();
    

    They should be used in an update loop when not using the tick-poll feature.

    loop {
      // game logic code here
    
      // push a frame
    
      // tick executor
      poll_promise::tick();
    }
    
    • These tick static variables provided by the crate EXECUTOR and LOCAL_EXECUTOR resepectively
    • Blocking on promises now loops and constantly polls them instead of waiting on the receiver
    • Blocking also automatically ticks for you
    • The tick-poll feature automatically ticks the executors when polling promises like when blocking

    Promises now have a field called task_type which stores the type of task the promise is running (TaskType::Local for local tasks, TaskType::Async for async tasks, etc) They are used primarily for determining what executor to tick when blocking (or polling)

    There are now tests in lib.rs

        fn it_spawns_threads() {
            let promise = Promise::spawn_thread("test", || {
                std::thread::sleep(std::time::Duration::from_secs(1));
                0
            });
    
            assert_eq!(0, promise.block_and_take());
        }
    
    • Promise::spawn_async has been split into Promise::spawn_local to run futures locally
    • Promise::spawn_async is no longer usable on wasm and spawn_local must be used instead

    Tokio does not play very well with spawn_local though, there doesn't seem to be much this library could do about that without forcing a Send bound onto spawn_local

    Related Issues

    Helps further resolve #8 and makes poll_promise more usable on the web and on native

    opened by Speak2Erase 2
  • web feature not on crates.io

    web feature not on crates.io

    The version published to crates.io doesn't have the web feature, so you can't use poll-promise in WASM unless you directly add the Git repository as a dependency.

    bug 
    opened by NotNite 1
  • Release 0.2.0

    Release 0.2.0

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below
    opened by emilk 0
  • Release 0.1.1

    Release 0.1.1

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Prepare for 0.1.1 release

    opened by emilk 0
  • Add Unicode-DFS-2016 to deny.toml

    Add Unicode-DFS-2016 to deny.toml

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Fix cargo deny check problem seen in https://github.com/EmbarkStudios/poll-promise/pull/9

    opened by emilk 0
  • Allow non Send futures on wasm

    Allow non Send futures on wasm

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Added attributes in the function parameters for Promise::spawn_async to enable/disable the Send trait bound

    Without this patch calling an async function like this one using poll promise would not compile

    #[wasm_bindgen(module = "/assets/filesystem.js")]
    extern "C" {
        #[wasm_bindgen(catch)]
        async fn js_open_project() -> Result<JsValue, JsValue>;
        #[wasm_bindgen(catch)]
        async fn js_read_file(handle: JsValue, _path: String) -> Result<JsValue, JsValue>;
        fn js_filesystem_supported() -> bool;
    }
    
    /* ... */
    
    pub async fn try_open_project(&self, cache: Arc<DataCache>) -> Result<(), String> {
        let handle = js_open_project()
            .await
            .map_err(|_| "No project loaded".to_string())?;
    
        self.load_project(handle, cache)
    }
    

    image

    It'd make sense to remove the Send limitation specifically for web since I'd imagine people using this crate for wasm are likely operating with async JS functions

    https://github.com/Speak2Erase/poll-promise/blob/bfc32879452afea0f2eec6355e40ec4de05c8c92/src/promise.rs#L112-L113

    Related Issues

    Fixes #8

    opened by Speak2Erase 0
  • wasm futures should not be Send

    wasm futures should not be Send

    https://github.com/EmbarkStudios/poll-promise/blob/089c99062e289808b8077457f84b01f5c347aa28/src/promise.rs#L108

    From what I understand Send on this line is not necessary with wasm futures since the spawn_local does not require that trait. https://github.com/EmbarkStudios/poll-promise/blob/089c99062e289808b8077457f84b01f5c347aa28/src/promise.rs#L121 This actually poses a problem when doing anything with JsValues in a future since it violates that future being Send.

    bug 
    opened by Speak2Erase 0
  • Add links to similar projects

    Add links to similar projects

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    I added links to these two similar types:

    These are similar to poll_promise::Promise and may be more suitable in some cases.

    opened by emilk 0
  • Run CI

    Run CI

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Turn on the CI. It is more useful that way.

    opened by emilk 0
  • Add 'web' feature to spawn tasks using wasm_bndget_futures::spawn_local

    Add 'web' feature to spawn tasks using wasm_bndget_futures::spawn_local

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    This enables spawn_async ~and spawn_blocking~ when compiling for web.

    Related Issues

    opened by emilk 0
  • Show feature labels in generated docs

    Show feature labels in generated docs

    Checklist

    • [x] I have read the Contributor Guide
    • [x] I have read and agree to the Code of Conduct
    • [x] I have added a description of my changes and why I'd like them included in the section below

    Description of Changes

    Adds #[cfg_attr(docsrs, doc(cfg(any(feature = "..."))))] to required features are highlighted in the standard rustdoc way.

    Before: Screen Shot 2022-01-11 at 09 58 55

    After: Screen Shot 2022-01-11 at 10 08 01

    Related Issues

    None.

    documentation 
    opened by davidpdrsn 6
Releases(0.2.0)
Owner
Embark
The future belongs to the curious
Embark
A framework for modding and instrumenting games.

me3 A framework for modifying and instrumenting games. Explore the docs » Report Bug · Request Feature About The Project Built With Getting Started Pr

Gary Tierney 13 Dec 18, 2022
A single-threaded polling-based Rust async executor suitable for use in games, embedded systems or WASM.

simple async local executor An Enlightware® software. Overview A single-threaded polling-based executor suitable for use in games, embedded systems or

Enlightware GmbH 16 Nov 15, 2022
Wein2D.js bindings for creating browser games in Rust using WebAssembly.

Wein2D.js-WASM Wein2D.js bindings for creating browser games in Rust using WebAssembly. Wein2D.js-WASM requires Wein2d.js to be loaded in the same doc

DevTaube 1 Apr 14, 2022
Cross-platform (including wasm) persistent key value store plugin for rust games/apps

bevy_pkv bevy_pkv is a cross-platform persistent key value store for rust apps. Use it for storing things like settings, save games etc. Currently, it

Johan Klokkhammer Helsing 25 Jan 9, 2023
An ergonomic physics API for bevy games.

Heron An ergonomic physics API for 2d and 3d bevy games. (powered by rapier) How it looks like fn main() { App::build() .add_plugins(DefaultPlug

Jonathan Cornaz 313 Dec 16, 2022
A frontend to Assets purchased on Epic Games Store

Epic-Asset-Manager A frontend to Assets purchased on Epic Games Store Current Screenshot Install Arch Linux Use the AUR package Build flatpak meson _b

Acheta Games 202 Jan 3, 2023
A framework for making games using Macroquad.

Omegaquad A framework for making games using Macroquad. After writing maybe 5 games and finding myself always going to the previous project to copy-pa

null 14 Oct 13, 2022
Synchronize games from other platforms into your Steam library

BoilR Description This little tool will synchronize games from other platforms into your Steam library, using the Steam Shortcuts feature. The goal is

Philip Kristoffersen 823 Jan 9, 2023
A simple camera for properly displaying tile-based low resolution pixel perfect 2D games in bevy.

Bevy Tiled Camera A simple camera for properly displaying low resolution pixel perfect 2D games in bevy. The camera will adjust the viewport to scale

sark 10 Oct 5, 2022
A single-threaded executor for deferred async code for games.

This crate provides a single-threaded, sequential, parameterized async runtime. In other words, this creates coroutines, specifically targeting video game logic, though cosync is suitable for creating any sequences of directions which take time.

Jonathan Spira 49 Dec 9, 2022
Using USBPcap to side-step anticheat in games, in order to reroute rumble packets to sex toys via The Buttplug Sex Toy Control Library

Using USBPcap to side-step anticheat in games, in order to reroute rumble packets to sex toys via The Buttplug Sex Toy Control Library.

qDot 23 Jan 3, 2023
A sandbox library for making FAST voxel games

voxelize WIP A well-optimized web-based voxel engine. Development Before starting, make sure to install the following: rust node.js cargo-watch # clon

Ian Huang (Shaoru) 146 Dec 30, 2022
A framework for building adventure games in Bevy.

Bevy_adventure A framework for building 3d adventure games in Bevy. preview.mp4 Features Interactive trait is the backbone of the framework, allowing

Hank Jordan 9 Jan 5, 2023
Bevy virtual Joystick for mobile games (Works with mouse on desktop)

Bevy Virtual Joystick Create and use a Virtual Joystick in a UI for bevy Game Engine. Versions Aviable and compatible versions bevy VirtualJoystick 0.

Sergio Alejandro Ribera Costa 7 Apr 16, 2023
Explicitly set sprite layers for sprites in Bevy games.

extol_sprite_layer lets you specify the drawing order for sprites in your Bevy game using a separate component rather than via the z-coordinate of you

Ash 5 May 2, 2023
Highly customizable splash screen library for Bevy games.

bevy_intro_screen This is a versatile Bevy library designed to create engaging and customizable introductory screens for your game. Initially conceive

Aarav Shah 4 Aug 13, 2024
Hierarchical Task Network Planning deeply integrated with bevy, which I use in my games :P

Note that CI currently tests against a matrix of (windows, mac, linux) * (toolchain stable, nightly) * (cargo build, test, clippy), which ensures vali

null 29 Oct 16, 2024
Victorem - easy UDP game server and client framework for creating simple 2D and 3D online game prototype in Rust.

Victorem Easy UDP game server and client framework for creating simple 2D and 3D online game prototype in Rust. Example Cargo.toml [dependencies] vict

Victor Winbringer 27 Jan 7, 2023
Abstreet - Transportation planning and traffic simulation software for creating cities friendlier to walking, biking, and public transit

A/B Street Ever been stuck in traffic on a bus, wondering why is there legal street parking instead of a dedicated bus lane? A/B Street is a project t

A/B Street 6.8k Jan 9, 2023