1Padre::Task(3) User Contributed Perl Documentation Padre::Task(3)
2
3
4
6 Padre::Task - Padre Background Task API
7
9 Create a subclass of Padre::Task which implements your background task:
10
11 package Padre::Task::Foo;
12
13 use base 'Padre::Task';
14
15 # This is run in the main thread before being handed
16 # off to a worker (background) thread. The Wx GUI can be
17 # polled for information here.
18 # If you don't need it, just inherit the default no-op.
19 sub prepare {
20 my $self = shift;
21 if ( condition_for_not_running_the_task ) {
22 return "BREAK";
23 }
24
25 return 1;
26 }
27
28 # This is run in a worker thread and may take a long-ish
29 # time to finish. It must not touch the GUI, except through
30 # Wx events. TO DO: explain how this works
31 sub run {
32 my $self = shift;
33 # Do something that takes a long time!
34 # optionally print to the output window
35 $self->print("Background thread says hi!\n");
36 return 1;
37 }
38
39 # This is run in the main thread after the task is done.
40 # It can update the GUI and do cleanup.
41 # You don't have to implement this if you don't need it.
42 sub finish {
43 my $self = shift;
44 my $main = shift;
45 # cleanup!
46 return 1;
47 }
48
49 1;
50
51 From your code, you can then use this new background task class as
52 follows. ("new" and "schedule" are inherited.)
53
54 require Padre::Task::Foo;
55 my $task = Padre::Task::Foo->new(some => 'data');
56 $task->schedule; # hand off to the task manager
57
58 As a special case, any (arbitrarily nested and complex) data structure
59 you put into your object under the magic "main_thread_only" hash slot
60 will not be passed to the worker thread but become available again when
61 "finish" is called in the main thread. You can use this to pass
62 references to GUI objects and similar things to the finish event
63 handler since these must not be accessed from worker threads.
64
65 However, you should be cautious when keeping references to GUI elements
66 in your tasks, in case the GUI wants to destroy them before your task
67 returns.
68
69 Instead, it is better if your "finish" method knows how to relocate the
70 GUI element from scratch (and can safely handle the situation when the
71 GUI element is gone, or has changed enough to make the task response
72 irrelevent).
73
75 This is the base class of all background operations in Padre. The
76 SYNOPSIS explains the basic usage, but in a nutshell, you create a
77 subclass, implement your own custom "run" method, create a new
78 instance, and call "schedule" on it to run it in a worker thread. When
79 the scheduler has a free worker thread for your task, the following
80 steps happen:
81
82 The scheduler calls "prepare" on your object.
83 If your prepare method returns the string 'break', all further
84 processing is stopped immediately.
85 The scheduler serializes your object with "Storable".
86 Your object is handed to the worker thread.
87 The thread deserializes the task object and calls "run()" on it.
88 After "run()" is done, the thread serializes the object again and hands
89 it back to the main thread.
90 In the main thread, the scheduler calls "finish" on your object with
91 the Padre main window object as argument for cleanup.
92
93 During all this time, the state of your task object is retained! So
94 anything you store in the task object while in the worker thread is
95 still there when "finish" runs in the main thread. (Confer the CAVEATS
96 section below!)
97
99 new
100 "Padre::Task" provides a basic constructor for you to inherit. It
101 simply stores all provided data in the internal hash reference.
102
103 schedule
104 "Padre::Task" implements the scheduling logic for your subclass. Simply
105 call the "schedule" method to have your task processed by the task
106 manager.
107
108 Calling this multiple times will submit multiple jobs.
109
110 run
111 This is the method that will be called in the worker thread. You must
112 implement this in your subclass.
113
114 You must not interact with the Wx GUI directly from the worker thread.
115 You may use Wx thread events only. TO DO: Experiment with this and
116 document it.
117
118 prepare
119 In case you need to set up things in the main thread, you can implement
120 a "prepare" method which will be called right before serialization for
121 transfer to the assigned worker thread.
122
123 If "prepare" returns the string "break" (case insensitive), all further
124 processing of the task will be stopped and neither "run" nor "finish"
125 will be called. Any other return values are generally ignored.
126
127 You do not have to implement this method in the subclass.
128
129 finish
130 Quite likely, you need to actually use the results of your background
131 task somehow. Since you cannot directly communicate with the Wx GUI
132 from the worker thread, this method is called from the main thread
133 after the task object has been transferred back to the main thread.
134
135 The first and only argument to "finish" is the Padre main window
136 object.
137
138 You do not have to implement this method in the subclass.
139
140 task_print
141 $task->task_print("Hi this is immediately sent to the Padre output window\n");
142
143 Sends an event to the main Padre thread and displays a message in the
144 Padre output window.
145
146 task_warn
147 $task->task_warn("Hi this is immediately sent to the Padre output window\n");
148
149 Sends an event to the main Padre thread and displays a message in the
150 Padre output window with style "bad".
151
152 post_event
153 This method allows you to easily post a Wx event to the main thread.
154 First argument must be the event ID, second argument the data you want
155 to pass to the event handler.
156
157 For a complete example, please check the code of
158 "Padre::Task::Example::WxEvent".
159
160 You can set up a new event ID in your Padre::Task subclass like this:
161
162 our $FUN_EVENT_TYPE : shared;
163 BEGIN { $FUN_EVENT_TYPE = Wx::NewEventType(); }
164
165 Then you have to setup the event handler (for example in the
166 "prepare()" method. This should happen in the main thread!
167
168 But watch out: You should not declare the same handler multiple times.
169
170 Wx::Event::EVT_COMMAND(
171 Padre->ide->wx->main,
172 -1,
173 $FUN_EVENT,
174 \&update_gui_with_fun
175 );
176
177 sub update_gui_with_fun {
178 my ($main, $event) = @_; @_=(); # hack to avoid "Scalars leaked"
179 my $data = $event->GetData();
180 }
181
182 After that, you can dispatch events of type $FUN_EVENT_TYPE by simply
183 running:
184
185 $self->post_event($FUN_EVENT_TYPE, $data);
186
188 Since the task objects are transferred to the worker threads via
189 "Storable::freeze()" / "Storable::thaw()", you cannot put any data into
190 the objects that cannot be serialized by "Storable". To the best of my
191 knowledge, that includes file handles and code references.
192
194 The management of worker threads is implemented in the
195 Padre::TaskManager class.
196
197 The transfer of the objects to and from the worker threads is
198 implemented with Storable.
199
201 Steffen Mueller "smueller@cpan.org"
202
204 Copyright 2008-2010 The Padre development team as listed in Padre.pm.
205
206 This program is free software; you can redistribute it and/or modify it
207 under the same terms as Perl 5 itself.
208
209
210
211perl v5.12.1 2010-06-11 Padre::Task(3)