Async/Coroutine events

Started by JMteam09, Nov 01, 2018, 01:46 pm

Previous topic - Next topic

JMteam09

Hi,
I know that there has been talked about this topic on the old forums.
In that thread someone requested to make os.pullEvent() a function that returns a table with events that have occured instead of holding up the PC. I think i have a better proposal for people who want to do better multitasking without having to lock up their main coroutine to yield for an event or use os.startTimer tricks.
Add this to computercraft: have a value which tells if the event queue is empty or not.
This way we can decide wether to check for an event or not. this way we can easily write programs that dont need to be held up unless we tell them specificly to hold and let other coroutines run.

(Yes i know this is more a suggestion than Ask a Pro but where else can i post it realy?)

Best regards, Jordi vd Molen.

KingofGamesYami

You do know each computer is a coroutine, right?  So if one computer executes for 30 seconds without yielding, no other computer will be able to execute or process input.
I'm a ComputerCraft veteran with over 3k posts on the old ComputerCraft Forum.  I'm mostly inactive in CC having moved on to bigger, more interesting projects but still contribute to the community.

Sewbacca

I don't think this would be a suitable solution. Like KingofGamesYami said, the coroutine would just hold on all existing computers. Here is an solution for your problem:

Code Select
local tEventArgs;
local filter;

--# Returns whether there are events or not and the events
local function continue()
    local tim = os.startTimer(0)
    local tEventArgs = { os.pullEvent() }
    if tEventArgs[1] == "timer" then
        return true
    end

    return false, table.unpack(tEventArgs)
end

--# Main chunk (you could run a file with os.run and pass the continue function, the shell and multishell into the environment)
local function main()
    local var, foo, var143, pi = 2.1, 3.7, 1000, 1

    for i=1,math.huge do
        local complicatedValue = ((var * foo / var143 - pi)^2)^0.439
        print(complicatedValue)

        local go, event, key = continue()
        if not go and event == "key" then
            if key == keys.e then
                return
            end
        end
    end
end

--# Handles coroutine for you
local function start(func)
    local co = coroutine.create( func )

    while coroutine.status( co ) == "suspended" do
        tEventArgs = { coroutine.yield() }
        if filter == tEventArgs[1] or filter == nil or tEventArgs[1] == "terminate" then
            local ok, err = coroutine.resume( co, table.unpack(tEventArgs) )
            if not ok then error(err, 2) end
            filter = err
        end
    end
end

--# Start the main function
start(main)

The parallel do something similair: http://www.computercraft.info/wiki/Parallel_(API)

EveryOS

Honestly, it would be neat if we could simply yield to not the parent program but CC itself and not mess with the queue. That could be a useful feature.

What I like to do is:
Code Select
os.queueEvent("")
os.pullEvent()
But then you cannot get any other event.

I'm not sure how plausible checking the queue would be - b/c the parent program does not have to report the queue accurately
~Google