Skript icon indicating copy to clipboard operation
Skript copied to clipboard

Tasks (Prototype 1)

Open Moderocky opened this issue 1 year ago • 1 comments

The Basics

A task is like a little function.

set {cool task} to a task:
    broadcast "Hello!"

run {cool task}

However, there are two important differences:

  1. tasks can't be reused
set {task} to a task:
    broadcast "Hello!"

run {task}

run {task} # does nothing :(
  1. the completion of a task can be waited for
set {monitor me} to false
set {task} to a task:
    wait 5 seconds
    set {monitor me} to true
    complete the current task

run {task}
{monitor me} is false

wait for {task}
{monitor me} is true

Importantly, this is a safe and low-overhead wait, which should be much more efficient than a busy-waiting while <...>: wait 1 tick. The trigger will sleep until the task reports as finished (or cancelled). Other triggers are not affected: Skript can process everything else while that trigger is sleeping.

Waiting

A task can be waited for. The wait will automatically end if:

  1. The task is marked as complete,
    • either by itself
    • or by another trigger.
    • or by the auto-completion flag
  2. The task is forcibly cancelled.
  3. The task is already complete/cancelled.
set {task} to a task:
    wait 5 seconds
    complete the current task

run {task}
wait for {task} # waits

wait for {task} # doesn't wait, task is already done
set {task} to a task:
    wait 5 seconds
    complete the current task

run {task}
cancel {task}
wait for {task} # doesn't wait, task is cancelled

If a task does not mark itself 'complete' at the end, it will be waited for indefinitely.

set {task} to a task:
    broadcast "hello"

run {task}
wait for {task} # Uh oh... we will wait forever!

This is by design: a task can be completed and/or cancelled from another trigger. You can use this to set up safe delays of indeterminate time.

function timer_thing():
    set {_start} to now

    set {task} to a task:
        do nothing
        # This task won't complete by itself

    run {task}
    broadcast "Quick! Step on stone!"

    wait for {task}
    # Waits until the task is completed remotely
    broadcast "That took %time since {_start}%!"

    {task} is completed # by the event below!

on step on stone:
    complete {task} # Complete the task we started

Auto-completion

A task can be set to auto-complete when it reaches the end of its trigger.

Please note: this completion will occur the first time the task is delayed, stopped or suspended, rather than necessarily at the end of the section. It is just a safety measure for non-delayed tasks.

set {task} to an automatic task:
    broadcast "hello"

run {task}
wait for {task} # Task completes itself

Cancellation

Like events, tasks can be 'cancelled'. This will wake up any trigger currently awaiting the task. Triggers will never wait for a cancelled task.

set {monitor me} to false
set {task} to a task:
    wait 5 seconds
    set {monitor me} to true
    complete the current task

run {task}
{monitor me} is false

cancel {task}
{monitor me} is false

wait for {task} # Task is already 'cancelled', it will not be waited for!
{monitor me} is false

Cancellation will also attempt to stop the actual running of the task at a safe point.

set {task} to a task:
    wait 5 seconds
    kill {isaac}
    complete the current task

run {task}

cancel {task} # Noo.. don't kill isaac!
{task} is cancelled
{isaac} is alive

Safe cancellation points currently include: delays, loops.

Cancellation and completion are the same, except that cancellation attempts to stop the task itself. You can check for cancellation and completion individually.


Related Issues: #6230, #5563

Moderocky avatar Jan 17 '25 10:01 Moderocky

Do you still intend to work on this?

sovdeeth avatar Jun 03 '25 05:06 sovdeeth