-
Notifications
You must be signed in to change notification settings - Fork 8
/
objmaps.perl
143 lines (113 loc) · 4.51 KB
/
objmaps.perl
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
#!/usr/bin/perl -w
# $Id$
# This is another simple functionality test. It tests sessions that
# are composed of objects (also called "object sessions"). The
# difference between this and objsessions.perl is that the object
# method names do not match their state names.
use strict;
use lib '../lib';
use POE;
#==============================================================================
# Counter is an object that roughly approximates "child" sessions from
# the sessions.perl test. It counts for a little while, then stops.
package Counter;
use strict;
use POE::Session;
#------------------------------------------------------------------------------
# This is a normal Perl object method. It creates a new Counter
# instance and returns a reference to it. It's also possible for the
# object to wrap itself in a Session within the constructor.
# Self-wrapping objects are explored in other examples.
sub new {
my ($type, $name) = @_;
print "Session ${name}'s object created.\n";
bless { 'name' => $name }, $type;
}
#------------------------------------------------------------------------------
# This is a normal Perl object method. It destroys a Counter object,
# doing any late cleanup on the object. This is different than the
# _stop event handler, which handles late cleanup on the object's
# Session.
sub DESTROY {
my $self = shift;
print "Session $self->{name}'s object destroyed.\n";
}
#------------------------------------------------------------------------------
# This method is an event handler. It sets the session in motion
# after POE sends the standard _start event.
sub poe_start {
my ($object, $session, $heap, $kernel) = @_[OBJECT, SESSION, HEAP, KERNEL];
# register a signal handler
$kernel->sig('INT', 'sigint');
# initialize the counter
$heap->{'counter'} = 0;
# hello, world!
print "Session $object->{'name'} started.\n";
$kernel->post($session, 'increment');
}
#------------------------------------------------------------------------------
# This method is an event handler, too. It cleans up after receiving
# POE's standard _stop event.
sub poe_stop {
my ($object, $kernel, $heap) = @_[OBJECT, KERNEL, HEAP];
print "Session $object->{'name'} stopped after $heap->{'counter'} loops.\n";
}
#------------------------------------------------------------------------------
# This method is an event handler. It will be registered as a SIGINT
# handler so that the session can acknowledge the signal.
sub poe_sigint {
my ($object, $from, $signal_name) = @_[OBJECT, SENDER, ARG0];
print "$object->{'name'} caught SIG$signal_name from $from\n";
# did not handle the signal
return 0;
}
#------------------------------------------------------------------------------
# This method is an event handler. It does most of counting work. It
# loops by posting events back to itself. The session exits when
# there is nothing left to do; this event handler causes that
# condition when it stops posting events.
sub poe_increment {
my ($object, $kernel, $session, $heap) = @_[OBJECT, KERNEL, SESSION, HEAP];
$heap->{'counter'}++;
if ($heap->{counter} % 2) {
$kernel->state('runtime_state', $object, 'poe_runtime_state');
}
else {
$kernel->state('runtime_state');
}
print "Session $object->{'name'}, iteration $heap->{'counter'}.\n";
if ($heap->{'counter'} < 5) {
$kernel->post($session, 'increment');
$kernel->yield('runtime_state', $heap->{counter});
}
else {
# no more events. since there is nothing left to do, the session exits.
}
}
#------------------------------------------------------------------------------
# This state is added on every even count. It's removed on every odd
# one. Every count posts an event here.
sub poe_runtime_state {
my ($self, $iteration) = @_[OBJECT, ARG0];
print( 'Session ', $self->{name},
' received a runtime_state event during iteration ',
$iteration, "\n"
);
}
#==============================================================================
# Create ten Counter objects, and wrap them in sessions.
package main;
foreach my $name (qw(one two three four five six seven eight nine ten)) {
POE::Session->create(
object_states => [
Counter->new($name) => {
_start => 'poe_start',
_stop => 'poe_stop',
increment => 'poe_increment',
sigint => 'poe_sigint',
},
],
);
}
$poe_kernel->run();
exit;