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
|
#!/usr/bin/perl -w
# 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;
|