line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package ProgressMonitor;
|
2
|
|
|
|
|
|
|
|
3
|
10
|
|
|
10
|
|
47394
|
use warnings;
|
|
10
|
|
|
|
|
21
|
|
|
10
|
|
|
|
|
318
|
|
4
|
10
|
|
|
10
|
|
54
|
use strict;
|
|
10
|
|
|
|
|
17
|
|
|
10
|
|
|
|
|
292
|
|
5
|
|
|
|
|
|
|
|
6
|
10
|
|
|
10
|
|
277
|
use 5.008;
|
|
10
|
|
|
|
|
42
|
|
|
10
|
|
|
|
|
1024
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.33';
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# Here follows the closest we come to describing an interface.
|
11
|
|
|
|
|
|
|
#
|
12
|
|
|
|
|
|
|
use classes 0.943
|
13
|
10
|
|
|
|
|
194
|
new => 'ABSTRACT',
|
14
|
|
|
|
|
|
|
clone => 'classes::clone',
|
15
|
|
|
|
|
|
|
methods => {
|
16
|
|
|
|
|
|
|
begin => 'ABSTRACT',
|
17
|
|
|
|
|
|
|
end => 'ABSTRACT',
|
18
|
|
|
|
|
|
|
isCanceled => 'ABSTRACT',
|
19
|
|
|
|
|
|
|
prepare => 'ABSTRACT',
|
20
|
|
|
|
|
|
|
setCanceled => 'ABSTRACT',
|
21
|
|
|
|
|
|
|
setMessage => 'ABSTRACT',
|
22
|
|
|
|
|
|
|
setErrorMessage => 'ABSTRACT',
|
23
|
|
|
|
|
|
|
tick => 'ABSTRACT',
|
24
|
|
|
|
|
|
|
subMonitor => 'ABSTRACT',
|
25
|
10
|
|
|
10
|
|
2974
|
};
|
|
10
|
|
|
|
|
39908
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
############################
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 NAME
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
ProgressMonitor - a flexible and configurable framework for providing feedback on how a long-running task is proceeding.
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 VERSION
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Version 0.31
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use strict;
|
40
|
|
|
|
|
|
|
use warnings;
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
use Time::HiRes qw(usleep);
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
use ProgressMonitor::Stringify::ToStream;
|
45
|
|
|
|
|
|
|
use ProgressMonitor::Stringify::Fields::Bar;
|
46
|
|
|
|
|
|
|
use ProgressMonitor::Stringify::Fields::Fixed;
|
47
|
|
|
|
|
|
|
use ProgressMonitor::Stringify::Fields::Percentage;
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub someTask
|
50
|
|
|
|
|
|
|
{
|
51
|
|
|
|
|
|
|
my $monitor = shift;
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
$monitor->prepare();
|
54
|
|
|
|
|
|
|
$monitor->begin(100);
|
55
|
|
|
|
|
|
|
for (1 .. 40)
|
56
|
|
|
|
|
|
|
{
|
57
|
|
|
|
|
|
|
usleep(100_000);
|
58
|
|
|
|
|
|
|
$monitor->tick(1);
|
59
|
|
|
|
|
|
|
}
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
anotherTask($monitor->subMonitor({parentTicks => 20}));
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
for (1 .. 40)
|
64
|
|
|
|
|
|
|
{
|
65
|
|
|
|
|
|
|
usleep(100_000);
|
66
|
|
|
|
|
|
|
$monitor->tick(1);
|
67
|
|
|
|
|
|
|
}
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
$monitor->end();
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub anotherTask
|
73
|
|
|
|
|
|
|
{
|
74
|
|
|
|
|
|
|
my $monitor = shift;
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$monitor->prepare();
|
77
|
|
|
|
|
|
|
$monitor->begin(3000);
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
for (1 .. 3000)
|
80
|
|
|
|
|
|
|
{
|
81
|
|
|
|
|
|
|
usleep(1_000);
|
82
|
|
|
|
|
|
|
$monitor->tick(1);
|
83
|
|
|
|
|
|
|
}
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
$monitor->end();
|
86
|
|
|
|
|
|
|
}
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
someTask(
|
89
|
|
|
|
|
|
|
ProgressMonitor::Stringify::ToStream->new(
|
90
|
|
|
|
|
|
|
{
|
91
|
|
|
|
|
|
|
fields =>
|
92
|
|
|
|
|
|
|
[
|
93
|
|
|
|
|
|
|
ProgressMonitor::Stringify::Fields::Bar->new,
|
94
|
|
|
|
|
|
|
ProgressMonitor::Stringify::Fields::Fixed->new,
|
95
|
|
|
|
|
|
|
ProgressMonitor::Stringify::Fields::Percentage->new,
|
96
|
|
|
|
|
|
|
]
|
97
|
|
|
|
|
|
|
}
|
98
|
|
|
|
|
|
|
)
|
99
|
|
|
|
|
|
|
);
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
The above synopsis shows it in a nutshell - cut and paste and try it. Or, peruse
|
104
|
|
|
|
|
|
|
the examples in the examples/ directory.
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 BACKGROUND
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
This is one more implementation of the idea of making code report progress in
|
109
|
|
|
|
|
|
|
what it's doing, and, typically, use this reporting to give feedback to a user
|
110
|
|
|
|
|
|
|
on how far we've come and/or how much there is left to do. There are other
|
111
|
|
|
|
|
|
|
Perl modules for this, but this is bigger and better :-).
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
The rationale for this module was twofold: first, I needed a reasonable-sized
|
114
|
|
|
|
|
|
|
excuse to try out Rob Muhlestein's (RMUHLE) 'classes' pragma as preparation for
|
115
|
|
|
|
|
|
|
a later, bigger project. Second, I like IProgressMonitor, a Java interface in
|
116
|
|
|
|
|
|
|
the Eclipse project (more information in L"SEE ALSO"> below) that I've dealt
|
117
|
|
|
|
|
|
|
with and thought the basic ideas around that could be put to good use in Perl
|
118
|
|
|
|
|
|
|
code also. There are some differences from IProgressMonitor though, if you end
|
119
|
|
|
|
|
|
|
up comparing them.
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=head2 CONCEPT
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
An overall principle of a feedback mechanism is that the code doing progress really
|
124
|
|
|
|
|
|
|
has no idea as to how (if at all) any of the progress it reports actually result in
|
125
|
|
|
|
|
|
|
any feedback, or, more importantly, what form such feedback takes. Thus, this package
|
126
|
|
|
|
|
|
|
only provides an abstract interface for progressee's to call into, and this has to be
|
127
|
|
|
|
|
|
|
done in a clearly defined manner so as to ensure that any feedback will indicate
|
128
|
|
|
|
|
|
|
the right things at the right time. The object of all this is to keep the user informed: 'cool
|
129
|
|
|
|
|
|
|
your heels - maybe it's taking a long time but I *am* working!'.
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Thus, any code that has no UI of its own should,
|
132
|
|
|
|
|
|
|
in the best of worlds, accept an instance of the ProgressMonitor interface, and
|
133
|
|
|
|
|
|
|
report its progress through that. Ideally, an entire framework should at all appropriate
|
134
|
|
|
|
|
|
|
places be able to make use of a monitor in order to allow the most granular feedback
|
135
|
|
|
|
|
|
|
possible.
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
The other side of the coin is the code that does have an UI and thus knows
|
138
|
|
|
|
|
|
|
how feedback should be shown. This code should instantiate a monitor of the correct
|
139
|
|
|
|
|
|
|
type and pass it in to the method that reports progress.
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
There is a middle ground however: a progresse may have need to use lower level functions
|
142
|
|
|
|
|
|
|
and they might also be able to use a monitor. In such a case, the higher level progressee
|
143
|
|
|
|
|
|
|
should instantiate a SubTask monitor. This special monitor type will pass on information
|
144
|
|
|
|
|
|
|
to the parent monitor and cause feedback to be correctly scaled. It is important
|
145
|
|
|
|
|
|
|
to never pass on the monitor you have been given to someone else!
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head2 The ProgressMonitor 'contract'
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
So, being a progressee, you get a monitor instance. What do you do?
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=over 2
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=item PREPARING YOURSELF
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
The first call you should do as soon as possible is to call the 'prepare' method.
|
156
|
|
|
|
|
|
|
This tells the monitor that you are in prepare mode, and this means that you now spend
|
157
|
|
|
|
|
|
|
your time figuring out how many 'things' you will need to do. While doing this you should
|
158
|
|
|
|
|
|
|
as regularly as possible call the 'tick' method (any arguments to tick will be ignored in prepare
|
159
|
|
|
|
|
|
|
mode). This will, depending on feedback mechanism, trigger some visible indication of
|
160
|
|
|
|
|
|
|
'work in progress'.
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
This step is actually
|
163
|
|
|
|
|
|
|
optional - maybe you already know how much work you need to do. Or, also common, you really don't know, and
|
164
|
|
|
|
|
|
|
it may be either impossible to figure out, or it may be prohibitive to calculate. In this case, you can go
|
165
|
|
|
|
|
|
|
straight to calling 'begin'.
|
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=item BEING ACTIVE
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
Having called the begin method, you're saying "I'm now actively working with the task".
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
The begin method takes an optional parameter, an integer. The significance is that
|
172
|
|
|
|
|
|
|
if you don't pass anything, you're saying 'the extent of this work is unknown, you'll just have to wait...I will
|
173
|
|
|
|
|
|
|
call back once in a while to ensure you see me working'. Some feedback presentations
|
174
|
|
|
|
|
|
|
are better at portraying this situation than others - for example, a character changing
|
175
|
|
|
|
|
|
|
shape for each call will give a good view of this.
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Passing a number however, constitutes
|
178
|
|
|
|
|
|
|
a promise; 'I will call back exactly this number of times' (there's no implication of
|
179
|
|
|
|
|
|
|
time between calls though). Again, some presentations look better than others in this
|
180
|
|
|
|
|
|
|
situation - specifically, presentations that can show "I'm now here, and so much remains"
|
181
|
|
|
|
|
|
|
will then give a fairly clear picture. A typical presentation is the percentage - '85 %'
|
182
|
|
|
|
|
|
|
clearly shows that it's almost finished.
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
So, in either of the above cases you should call the 'tick' method. If the total is
|
185
|
|
|
|
|
|
|
unknown, each tick simply increments the internal counter by one (i.e. any argument to
|
186
|
|
|
|
|
|
|
tick is ignored). If the total is unknown however, you should call with an integer argument.
|
187
|
|
|
|
|
|
|
Actually, the integer may be 0 in which case presentations sees it as an 'idle' tick
|
188
|
|
|
|
|
|
|
but still may do something visually interesting. Any other integer is simply added to
|
189
|
|
|
|
|
|
|
the current count - but beware of calling tick with a number that causes the total to
|
190
|
|
|
|
|
|
|
be greater than your promise; this is an error. In any event, this gives the clearest
|
191
|
|
|
|
|
|
|
signal to presentations, one which they typically use to calculate amount done vs amount
|
192
|
|
|
|
|
|
|
remaining, and then render this in the best way.
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
While 'ticking' is the primary way of informing the user, sometimes it makes sense
|
195
|
|
|
|
|
|
|
not only saying "I'm active", but also saying 'I'm currently doing this', i.e. a straightforward
|
196
|
|
|
|
|
|
|
message. Messages is a sort of out-of-band communication in regards to ticks. Depending
|
197
|
|
|
|
|
|
|
on how the monitor was set up, they may be ignored altogether, written using newlines 'beside'
|
198
|
|
|
|
|
|
|
the tick, or perhaps overlaying the tick field(s) (all or in part) - and then automatically
|
199
|
|
|
|
|
|
|
time out, restoring the tick fields. Anyway, feel free to give informational messages as
|
200
|
|
|
|
|
|
|
needed (but don't assume they'll be seen - just as with ticks, as the monitor in total
|
201
|
|
|
|
|
|
|
may be just a black hole).
|
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item FINISHING
|
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
When all your tasks are complete, you should call the 'end' method. Ideally, you should
|
206
|
|
|
|
|
|
|
by now have called tick the right number of times, and thus the final presentation should
|
207
|
|
|
|
|
|
|
show (the equivalent to) 100% complete.
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
The monitor is now unusuable for further calls and should be discarded.
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=item CANCELLATION
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
Preferably, you should intermittently also call 'isCanceled' on the monitor. A true value
|
214
|
|
|
|
|
|
|
signals that you should cancel your work at the earliest convenience - if at all possible.
|
215
|
|
|
|
|
|
|
I.e. it is legal to not care about the cancellation status. Only you can decide, but it's very
|
216
|
|
|
|
|
|
|
nice to allow users to cancel a task.
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=item SUBTASKS
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
During your prepare or active phase, you may utilize a lower level method/function to
|
221
|
|
|
|
|
|
|
do the overall task. In order to still report progress, you need to wrap your monitor inside
|
222
|
|
|
|
|
|
|
a SubTask monitor and pass that on.
|
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
It is illegal to pass on your own monitor - this will break as the lower level method should
|
225
|
|
|
|
|
|
|
follow the same pattern detailed here - thus, the first thing called will be 'prepare' and
|
226
|
|
|
|
|
|
|
since your own monitor is already in the active phase, it could get very confusing indeed!
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
The pattern here is that you allocate the subtask a certain amount of 'your' progress. Regardless
|
229
|
|
|
|
|
|
|
of how many iterations the subtask will do, the progress will be scaled to the parent so that
|
230
|
|
|
|
|
|
|
by the time the subtask is 100% complete, it has used up only the allotment it was given.
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
If you think about it, it's clear that this will work for arbitrarily deeply nested
|
233
|
|
|
|
|
|
|
subtasks - as long as all methods accept a monitor and use the pattern described here,
|
234
|
|
|
|
|
|
|
they can call each other in any order.
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
=back
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=head1 Available monitor and field types
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
This package provides 4 concrete types that can be used. Two of them are special purpose
|
241
|
|
|
|
|
|
|
monitors, and the other two are variations on how to present the feedback as strings.
|
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
The last two uses 'field' objects to display in different ways (spinner, percentage, bar etc).
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
If this is not adequate for you, it's fairly easy to derive new specializations of either
|
246
|
|
|
|
|
|
|
complete monitors or field variations.
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
For each of these, see their respective documentation for details.
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head2 MONITOR TYPES
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=over 2
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=item ProgressMonitor::Null
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
If you wish to skip feedback, you may instantiate a null monitor. It implements
|
257
|
|
|
|
|
|
|
the interface and contract but doesn't do anything with the information.
|
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
Note: this is commonly used inside monitor accepting methods; if the caller sends no
|
260
|
|
|
|
|
|
|
monitor, the code instantiates a null monitor and can then use the monitor
|
261
|
|
|
|
|
|
|
interface normally.
|
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=item ProgressMonitor::SubTask
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
This is the monitor necessary to wrap a parent monitor for a subtask. This is a
|
266
|
|
|
|
|
|
|
concrete implementation and you may use this or call on the monitor for a new
|
267
|
|
|
|
|
|
|
suitable instance using 'subMonitor'.
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::ToStream
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
This monitor type is ideal for simply displaying feedback on stdout, for example.
|
272
|
|
|
|
|
|
|
It must be given some field objects which defines the ultimate presentation.
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::ToCallback
|
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
This monitor type is useful if you have special needs for displaying, but is still
|
277
|
|
|
|
|
|
|
content with a plain string. It acts like ToStream, but instead of printing to the
|
278
|
|
|
|
|
|
|
defined stream, it will callback to a code reference you provide.
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=back
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 FIELD TYPES
|
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=over 2
|
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::Bar
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
This will display a traditional 'bar' that grows from left to right indicating
|
289
|
|
|
|
|
|
|
completion amount. If the resolution is too poor to show progress, it will still
|
290
|
|
|
|
|
|
|
do something. In cases of an unknown total it will provide a visual indication
|
291
|
|
|
|
|
|
|
of movement.
|
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::Counter
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
This will display the common counter, optionally with the total. It will try to show
|
296
|
|
|
|
|
|
|
idle progress, but for unknown totals it can only show '?'. It may also overflow if
|
297
|
|
|
|
|
|
|
the numbers get to big (settable though, and uncommon mostly).
|
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::ETA
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
This will display an estimated time to completion. When the task is finished, this
|
302
|
|
|
|
|
|
|
field will show the actual time it spent (this is very different from other fields as
|
303
|
|
|
|
|
|
|
they typically end with the final value, e.g. '100%').
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Note that since there is nothing
|
306
|
|
|
|
|
|
|
forcing progress to happen at a steady beat, this can be a very unreliable estimate.
|
307
|
|
|
|
|
|
|
For many tasks however, progress is regular enough to give a reasonable value.
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::Fixed
|
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
This will display a fixed text. Useful for combining with other fields.
|
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::Percentage
|
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
This will display a percentage showing completion.
|
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=item ProgressMonitor::Stringify::Fields::Spinner
|
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
This will display a 'moving' character/string only. Totals can't be shown with this.
|
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=back
|
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 SEE ALSO
|
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
ProgressMonitor is (loosely) based on IProgressMonitor and associated
|
326
|
|
|
|
|
|
|
mechanisms in the Eclipse/Java framework. Throw 'IProgressMonitor' into Google
|
327
|
|
|
|
|
|
|
and you'll most likely find your way to Eclipse docs around it. Also, this is
|
328
|
|
|
|
|
|
|
an article I wrote on how to deal with IProgressMonitor; it is somewhat relevant
|
329
|
|
|
|
|
|
|
in this context: L
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head1 AUTHOR
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Kenneth Olwing, C<< >>
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head1 BUGS
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
I wouldn't be surprised! If you can come up with a minimal test that shows the
|
338
|
|
|
|
|
|
|
problem I might be able to take a look. Even better, send me a patch.
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
Please report any bugs or feature requests to
|
341
|
|
|
|
|
|
|
C, or through the web interface at
|
342
|
|
|
|
|
|
|
L.
|
343
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on
|
344
|
|
|
|
|
|
|
your bug as I make changes.
|
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=head1 SUPPORT
|
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command.
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
perldoc ProgressMonitor
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
You can also look for information at:
|
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=over 4
|
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation
|
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
L
|
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=item * CPAN Ratings
|
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
L
|
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
L
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=item * Search CPAN
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
L
|
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=back
|
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
Thanks to my family. I'm deeply grateful for you!
|
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Thanks to the Eclipse project for coming up with the IProgressMonitor interface
|
379
|
|
|
|
|
|
|
and surrounding mechanisms.
|
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
Copyright 2006, 2007, 2008 Kenneth Olwing, all rights reserved.
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
386
|
|
|
|
|
|
|
under the same terms as Perl itself.
|
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=cut
|
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
1; # End of ProgressMonitor
|