Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

host integration: SharedMessageQueue or similar #22

Open
Jamesernator opened this issue Jan 27, 2024 · 1 comment
Open

host integration: SharedMessageQueue or similar #22

Jamesernator opened this issue Jan 27, 2024 · 1 comment

Comments

@Jamesernator
Copy link

Jamesernator commented Jan 27, 2024

So shared structs work well if you restrict yourself to only shared objects in communications, the problem is a lot of host types aren't sharable but are serializable and/or transferable. It would be nice if we could integrate cleanly with such types within a shared object.

As a simple proposal for such behaviour I'd propose that there should be a host type SharedMessageQueue that itself is a shared object, but can enqueue/dequeue serializable and transferable objects.

As a simple toy example, this is how one could make simple shared canvas that can be written from any thread:

shared struct SharedCanvas {
    static async #listenToQueue(commandQueue: SharedMessageQueue, canvas: OffscreenCanvas) {
         const ctx = canvas.getContext("bitmaprenderer");
         while (true) {
             const { kind, ...data } = await commandQueue.dequeue();
             if (kind === "display") {
                 ctx.transferFromImageBitmap(data.imageBitmap);
             }
         }
    }

    #commandQueue = new SharedMessageQueue();
    
    constructor(canvas: OffscreenCanvas) {
        SharedCanvas.#listenToQueue(this.#commandQueue, canvas);
    }

    display(imageBitmap: ImageBitmap): void {
        this.#commandQueue.enqueue({ kind: "display", imageBitmap }, [imageBitmap]);
    }
}
@Jamesernator
Copy link
Author

A simpler alternative API would be making available a shared wrapper around a single serialized value. i.e. Something like:

shared struct SharedSerializedValue<T> {
     constructor(value: T, transferList: Iterable<Transferable>);

     // Deserializes the value on the current thread, effectively transfering it into the current thread, throws if already been called (even on another thread)
     get(): Promise<T>;
}

One could then just put such wrappers in any queue, or such, that they so desire.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant