File: Random.pm

package info (click to toggle)
moodss 19.7-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 6,136 kB
  • ctags: 3,149
  • sloc: tcl: 49,048; ansic: 187; perl: 178; makefile: 166; sh: 109; python: 65
file content (249 lines) | stat: -rw-r--r-- 12,082 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# $Id: Random.pm,v 1.16 2004/10/16 21:08:40 jfontain Exp $

# Perl module sample file with random data

# Corresponding pkgIndex.tcl file content:
# package ifneeded Random 1.9 "source [file join $dir Random.pm]"
# Module name must be capitalized and file extension .pm.
# The version number (1.9 here) must match the module version
# (see below).


package Random; # must be capitalized

# Note: the subroutines after(), yield(), flashMessage(), pushMessage(),
# popMessage() and traceMessage() are defined by the core in the module
# namespace and therefore should be seen as reserved subroutines, not to
# be redefined in the module (this file for the Random module).


use strict;
use warnings; # highly recommended, makes debugging much easier

BEGIN {
    # There is no need to export anything,
    # as moodss core uses fully qualified Perl names

    # The version number is mandatory. It must match with the
    # pkgIndex.tcl file content.
    # Example: our $VERSION = 1.18;
    our $VERSION = qw($Revision: 1.16 $)[1];
    # Note: see version number management requirements in moodss HTML
    # documentation (Module Development section)
}
# Module data is arranged in a hash and an array both named "data",
# It contains configuration values as well as dynamic data
# (see update subroutine).
our %data;
our @data;
our $asynchronous;

# Hash members are:

# - updates: a counter. Must be incremented as soon as the data has been
#   updated. Must be initialized in the module body in all cases as it
#   is used for automatic module detection (may not be changed in the
#   initialize subroutine).
$data{updates} = 0;

# Column numbers must be positive, starting from 0 included. Column members are:
#  - label: the title displayed on the top cell of the data column.
#  - type: valid types are: ascii, clock, dictionary, integer and real.
#    - ascii: simple strings.
#    - clock: accepts most date and time formats (you must really read the Tcl
#      clock command manual page, scan subcommand, for a precise description.
#    - dictionary: strings with eventually embedded numbers, taken into account
#      when sorting the column.
#    - real: floating point values.
#  - message: help text that appears in a widget tip when the mouse
#    cursor is left over the column title cell for a short while.
#  - anchor: optional member. Column data is either centered by default
#    (center), tucked to the left (left) or right side (right) of the
#    column.
$data{columns}[0] = {label => 'name', type => 'ascii', message => 'user name'};
$data{columns}[1] = {label => 'cpu', type => 'real', message => 'cpu usage in percent'};
$data{columns}[2] = {label => 'disk', type => 'integer', message => 'disk usage in megabytes'};
$data{columns}[3] = {label => 'memory', type => 'integer', message => 'memory usage in kilobytes'};
$data{columns}[4] = {label => 'command', type => 'dictionary', message => 'command name', anchor => 'left'};

# - pollTimes: in seconds. A list with the default poll time in first
#   position. The other times can be in any order, as the core will sort
#   them and use the lowest value as the minimum poll time value.
#   The minimum poll seconds must be a reasonable value depending on the
#   processing time of the update subroutine.
$data{pollTimes} = [10, 5, 20, 30, 60, 120, 300];

# - indices: an optional list that specifies the data columns that
#   should be displayed. If not specified, all the data columns are
#   visible.
#   Can be used when there are no views (see below).
#$data{indices} = [0, 1, 2, 3];

# - sort: an optional entry that defines the initial column to be used
#   for sorting the table data and in which direction. The specified
#   column must be visible (see indices member above).
#   Should be a hash with a single entry with the column as index and
#   either the 'increasing' or 'decreasing' keyword as value.
#   Can be used when there are no views (see below).
#$data{sort} = {1 => 'decreasing'};

# - indexColumns: a list that specifies the columns required to uniquely
#   identify a row in the table. It is optional and defaults to the
#   column 0, unless of course you do not have a 0 column index, in
#   which case it is mandatory to specify this list. When specified, all
#   the columns in the list must be visible (see indices member above or
#   in views below).
$data{indexColumns} = [0, 4];

# - views: optional. Arrays of hashes. If specified, it
#   defines one or more views to be used in place of the default
#   view. One table will be displayed per view.
#   For each view, 1 entry must be defined: 'indices' (syntax and usage
#   identical to the 'indices' list above).
#   2 members are optional:
#   'sort' (syntax and usage identical to the 'sort' entry above),
#   and
#   'swap', a boolean, specifies whether the data is displayed in a table
#   with columns and rows swapped (useful when data has only a single or
#   a couple of rows permanently).
#$data{views} = [
#    {indices => [0, 1, 3, 4], sort => {1 => 'decreasing'}, swap => 1},
#    {indices => [0, 2, 4], sort => {2 => 'decreasing'}}
#];
$data{views} = [
    {indices => [0, 1, 3, 4], sort => {1 => 'decreasing'}},
    {indices => [0, 2, 4], sort => {2 => 'decreasing'}}
];

# - persistent: optional (considered false if missing). A boolean
#   value that tells whether row numbers (used by the core, along with
#   the column numbers, to identify data cells) are identically mapped
#   from data row keys across module instances.
$data{persistent} = 1;

# - switches: optional. A hash of boolean values indexed by switches.
#   A switch is a single letter or a string prepended with the - or +
#   sign. The boolean value (0 or 1) specifies whether the switch takes
#   an argument. If the switches list is defined, an appropriate
#   initialize subroutine must be defined in the module (see initialize
#   subroutine example in this module). The core will take care of
#   parsing the command line and reject any invalid switch / value
#   combination for the module. The switches value may not be changed in
#   the initialize subroutine.
$data{switches} =
    {'-a' => 0, '--asynchronous' => 0, '-i' => 0, '--identify' => 0};

# - identifier: optional. A string that uniquely identifies this
#   module. It will be displayed by the core in the initial data tables
#   title area and data cell labels in viewers. This feature can be used
#   for example in modules that gather data from a remote host: in such
#   a case, the identifier could be set to dataType(hostName).
# $data{identifier} = 'random(test)';

# - resizableColumns: optional. A boolean value (0 or 1) which specifies
#   whether displayed data table(s) columns can be manually resized by
#   the user with the mouse. Not available on a per view basis.
# $data{resizableColumns} = 0;

# - helpText: displayed when the module help is launched from the main
#   window help menu. Can be plain text or HTML formatted (<HTML> and
#   <BODY> tags required), in which case it is properly rendered in the
#   module help window (note: tables, frames, and may other tags are not
#   supported: stick to formatted text at the moment).
# Here we load the HTML code from a file in this module directory, which
# the core changes to during the loading stage.
# The HTML code can obviously also be inlined.
$data{helpText} = `cat Random.htm`; # load HTML formatted help

# The initialize subroutine, if it exists, is invoked by the core before
# any update occurs (update subroutine invocation if the module is
# synchronous (always the case in Perl modules)). It can be used for
# module setup that cannot be accomplished during the loading phase.
# The initialize subroutine is optional when the module does not support
# command line arguments, and in such a case takes no arguments.
# The initialize subroutine is mandatory when the module supports command
# line arguments, and in such a case takes an hash as sole argument. The
# hash contains the switched options values, indexed by switch. For
# example, if the command line was:
# $ moodss random --asynchronous --other-option value -x 1234
# the hash will contain:
#   $options{--asynchronous} = 1
#   $options{--other-option} = value
#   $options{-x}             = 1234
# Note that the --asynchronous member value is filled with a boolean
# even though that switch takes no argument.
# For the above example, switches would have been defined as:
#   $data{switches} = [qw(-a 0 --asynchronous 0 --other-option 1 -x 1)];
# In all cases, data members other than updates and switches can be set
# or updated in the initialize subroutine, and still taken into account by
# the core.
sub initialize(%) {
    my %option = @_;
    $asynchronous = ($option{'-a'} || $option{'--asynchronous'});
    if ($asynchronous) {
        $data{pollTimes} = [-10];
        # use the core to call a subroutine after a number of milliseconds
        # without blocking the user interface, as sleep() would do
        after(3000, 'Random::update'); # boot simulation
    }
    if ($option{'-i'} || $option{'--identify'}) {
        # generate a unique module identifier:
        my $identifier = int(rand(100));
        $data{identifier} = "random $identifier";
    }
}

# The terminate subroutine if it exists is invoked by the core when
# the module is unloaded dynamically.
sub terminate() {
    # We could do some cleanup chores right here.
}

# The dynamic data array is 2 dimensional, indexed by row and column.
# The column number must start from 0 up to the total number of
# columns minus 1 (no holes are allowed in the column sequence).
# The row number can take any positive integer value (between 0 and
# 2147483647) and be defined in any order, as long as it is unique
# during the lifetime of the module data. If a new row is created, it
# must take a value that was never used: thus, the number of a row
# that has disappeared is not allowed. Row numbers need not be
# consecutive.
# Voidness for numeric data cells (integer or real type) takes the
# form of the ? character. Reminder: as long as a data row exists, all
# its data cells must exist. Thus voidness cannot be expressed by
# non-existence.
# The update subroutine function is to update module data.
sub update() {
    $data[0][0] = "John\nWo"; $data[0][4] = 'cc';
    $data[0][1] = sprintf('%.1f', rand(30)); $data[0][2] = 100 + int(rand(50)); $data[0][3] = 10 + int(rand(50));
    $data[1][0] = 'Bill'; $data[1][4] = 'xedit';
    $data[1][1] = sprintf('%.1f', rand(3)); $data[1][2] = 300 + int(rand(100)); $data[1][3] = 30 + int(rand(100));
    $data[2][0] = "Anny\nDoe"; $data[2][4] = 'ps';
    $data[2][1] = sprintf('%.1f', rand(5)); $data[2][2] = 200 + int(rand(30)); $data[2][3] = 20 + int(rand(30));
    $data[3][0] = 'Robert'; $data[3][4] = 'top';
    $data[3][1] = sprintf('%.1f', rand(10)); $data[3][2] = 500 + int(rand(150)); $data[3][3] = 50 + int(rand(150));
    $data[4][0] = "Peter\nWard"; $data[4][4] = 'ls';
    $data[4][1] = sprintf('%.1f', rand(8)); $data[4][2] = 50 + int(rand(10)); $data[4][3] = 5 + int(rand(10));
    $data[6][0] = 'Laura'; $data[6][4] = 'emacs';
    $data[6][1] = sprintf('%.1f', rand(20)); $data[6][2] = 90 + int(rand(20)); $data[6][3] = 9 + int(rand(20));
    $data[9][0] = 'Laura'; $data[9][4] = 'cc';
    $data[9][1] = sprintf('%.1f', rand(30)); $data[9][2] = 100 + int(rand(50)); $data[9][3] = 10 + int(rand(50));
    if (int(rand(4)) == 0) {
        # it is possible to post messages to the user:
        flashMessage('the Random module is still at work', 2);
        # also available: pushMessage(), popMessage() and traceMessage()
    }
    $data{updates}++;
    if ($asynchronous) { # simulate asynchronous operation if requested
        # use the core to call a subroutine after a number of milliseconds
        # without blocking the user interface, as sleep() would do
        after(2000 + int(rand(9000)), 'Random::update');
    }
}

END {
    # does not seem to be executed when interpreter is destroyed
    # as module is unloaded: you may use terminate() instead.
}

1; # traditional