Come up with an algorithm for play/pauseing a asynchronous process

Here is a short attempt at something that might do what you want. You have a “frame producer” task that is pushing frames into a channel that is being consumed in another task that shows these frames. You have another channel for changing the state of the task showing the frames so that it will stop playing which can be called from “toplevel”.

using Observables

@enum MovieState begin
    PAUSED
    PLAYING
end

const FRAME_CHANNEL = Channel{Float64}() # could buffer frames?
const STATE_CHANNEL = Channel{MovieState}()

function movie_controller()
    state = PLAYING
    while true
        if isready(STATE_CHANNEL)
            state = take!(STATE_CHANNEL)
            while state == PAUSED # wait for someone to unpause us
                state = take!(STATE_CHANNEL)
            end
        end
        if state == PLAYING
            frame = take!(FRAME_CHANNEL)
            println("Showing frame: $frame")
        end
    end
end

function frame_producer()
    while true
        v = rand() # time to produce a frame
        sleep(v)
        push!(FRAME_CHANNEL, v)
    end
end

@async movie_controller()
@async frame_producer()

play = Observable(false)
on(play) do p
    push!(STATE_CHANNEL, p ? PLAYING : PAUSED)
end
2 Likes