NAME

Tk::Task - allow multiple "tasks" to proceed at once

SYNOPSIS

use Tk::Task;

$mw = MainWindow->new;
...
$task = $mw->Task(
    [
        sub {
           OpenCursor();
        }
    ],
    [
        [
            sub {
                my $task = shift;
                if (FetchFromCursor()) {
                    AddToTree;
                } else {
                    $task->break;
                }
            }
        ],
    ],
    [
        sub {
            CloseCursor();
        }
    ]
);

$task->start;

DESCRIPTION

Tk::Task is a module to allow a lengthy operation to be subdivided into smaller pieces, with time to process events between pieces. For example, a program that loaded a large number of records from a database could make the load process a task, allowing the program to remain responsive to events--for example, to handle a Stop button!

The steps of each task are executed at idle time, one step each time, while "normal" processing (handling the event loop) continues. You might use a task to do simple animations such as turning cards over in a game, or for other purposes. For example, the Tk::TriangleTree widget uses a Tk::Task to animate the disclosure triangle.

A Task is not the same as a thread. It is more like a "poor man's" version of threading. However, this is often quite good enough.

Each step of the task is a reference to an array which can contain one of the following:

[ \&subroutine, @args ]

A reference to a subroutine causes that subroutine to be called with the rest of the elements of the array as parameters.

[ 'method' => $object, @args ]

A string is treated as a method; the class or object associated with the method must be the second element of the array, and any other elements are passed as parameters.

[ [ ... ], [ ... ], ... ]

A reference to an array indicates a loop. The steps within the outer array are repeated until one of them calls the break method, at which time the first step after the outer array is executed.

For example, the task structure shown in the "SYNOPSIS" shows a task that opens a database cursor, fetches each row and adds it to a tree, and then closes the cursor and ends the task when there are no more rows to be fetched.

There are three pseudo-arguments that can be specified when defining task steps. These are exported by default.

TASK

This is replaced with a reference to the task object itself when the task step runs. This is necessary to allow the step to call the break or repeat methods.

TASKPARM($name)

This is replaced by the named parameter when the task step runs. Parameters are set when the task is started, or can be added later using the parameter method.

TASKQUEUE

This is replaced by a reference to the queue containing the currently executing task.

Queues

Tasks are useful enough by themselves, but it is also possible to make a queue of tasks. Tasks can be added dynamically to the end of the queue, and will execute when all tasks in front of them have executed.

METHODS

Task Methods

$task = $mw->Task(@specifications);

Creates a new task with the given steps. This method is actually added to the MainWindow class.

$instance = $task->start(parm1 => $value1, ...);

Starts $task executing from the beginning. The given parameters are made available to the steps of the task by use of the TASKPARM pseudo-argument. Any existing instance of $task is unaffected.

$instance = $task->queue($queue, parm1 => $value1, ...);

Same as start, but also sets the queue that the instance is on. This is meant to be called only by the Tk::Task::Queue methods.

Instance Methods

A task instance is created automatically when you start a task. This allows each task to be executing multiple copies at the same time, without interfering with one another.

$instance->repeat;

Prevents the instance from advancing to the next step; when the task is due to run again, it will repeat the current step.

$instance->break;

Causes the instance to exit from the innermost loop; the next step executed will be the one after the end of the loop. If the current step is not part of a loop, nothing happens.

$instance->cancel;

Causes the instance to stop after the end of the current step. No further steps will be executed. If called from "outside" the task, between steps, then the next step will never fire.

$instance->delay($milliseconds);

Causes a delay of $milliseconds between the time the current step finishes and the next step begins. Behavior if called from other than within a task step is undefined.

$value = $instance->parameter(parm_name);

Returns the value of the particular parameter set when the instance was started, or changed later.

$instance->parameter(parm_name => $value);

Sets the value of the named parameter. This can be either a change to an existing parameter or the creation of a new parameter.

Queue Methods

$queue = new Tk::Task::Queue %options;

Creates a new queue. The following options are supported:

-finish

A callback that is called when all tasks in the queue have been completed.

-init

A callback that is called whenever a task starts when no task was running before.

The most common use for these two callbacks is to do something like calling Busy on the main window when a lengthy task begins, and Unbusy when it ends.

Each callback can be either a reference to a subroutine, which is simply called with a reference to the queue as its only parameter, or in the form of a task step. In the latter case, the TASKQUEUE pseudo-argument must be used to get a reference to the queue.

$queue->queue($task, parm1 => $value1, ...);

Adds $task to the end of $queue, with the given parameters. $task will execute when all tasks in front of it have completed; if there are no tasks in the queue when this method is called, the task will start executing immediately.

$queue->pause;

Pauses execution of the queue after the current task is complete. The next task will not begin until the resume method is called.

$queue->resume;

Resumes execution of the queue. Nothing happens if the queue isn't paused.

$queue->cancel;

Cancels execution of all tasks in the queue after the current one completes.

$queue->abort;

Cancels execution of all tasks in the queue after the current step of the current task completes.

$boolean = $queue->is_empty;

Returns true if there is nothing currently in the queue. Note that this method will also return true if called from the last task that was in the queue.

$queue->notify($instance);

Notifies the queue that the task instance specified by $instance has completed. This is called automatically by $instance when it finishes; you shouldn't ever have to call it directly. If $instance isn't the instance that's currently executing, nothing happens.

DIAGNOSTICS

invalid -finish callback for Tk::Task::Queue

The -finish callback must be either a code reference or an array reference.

invalid reference type in task step definition - must be CODE or ARRAY

A task step that was neither a reference to a subroutine nor a reference to an array was encountered.

odd number of options passed to class::new

Self-explanatory.

invalid option to class::new: 'name'

Self-explanatory.

SEE ALSO

Tk::after

MODULES USED

Tie::StrictHash

CHANGES

1.0

First release.

1.1

Allow a Task to be created off of any widget, not just a MainWindow.

COPYRIGHT

Copyright 2002 Kevin Michael Vail. All rights reserved.

This program is free software. You may redistribute and/or modify it under the same terms as Perl itself.

AUTHOR

Kevin Michael Vail <kevin@vaildc.net>