1#!/usr/local/bin/perl -w 2 3# This is another simple functionality test. It tests sessions that 4# are composed of objects (also called "object sessions"). It is 5# simpler than sessions.perl in many ways. 6 7use strict; 8use lib '../lib'; 9use POE; 10 11#============================================================================== 12# Counter is an object that roughly approximates "child" sessions from 13# the sessions.perl test. It counts for a little while, then stops. 14 15package Counter; 16use strict; 17use POE::Session; 18 19#------------------------------------------------------------------------------ 20# This is a normal Perl object method. It creates a new Counter 21# instance and returns a reference to it. It's also possible for the 22# object to wrap itself in a Session within the constructor. 23# Self-wrapping objects are explored in other examples. 24 25sub new { 26 my ($type, $name) = @_; 27 print "Session ${name}'s object created.\n"; 28 bless { 'name' => $name }, $type; 29} 30 31#------------------------------------------------------------------------------ 32# This is a normal Perl object method. It destroys a Counter object, 33# doing any late cleanup on the object. This is different than the 34# _stop event handler, which handles late cleanup on the object's 35# Session. 36 37sub DESTROY { 38 my $self = shift; 39 print "Session $self->{name}'s object destroyed.\n"; 40} 41 42#------------------------------------------------------------------------------ 43# This method is an event handler. It sets the session in motion 44# after POE sends the standard _start event. 45 46sub _start { 47 my ($object, $session, $heap, $kernel) = @_[OBJECT, SESSION, HEAP, KERNEL]; 48 # register a signal handler 49 $kernel->sig('INT', 'sigint'); 50 # initialize the counter 51 $heap->{'counter'} = 0; 52 # hello, world! 53 print "Session $object->{'name'} started.\n"; 54 55 $kernel->post($session, 'increment'); 56} 57 58#------------------------------------------------------------------------------ 59# This method is an event handler, too. It cleans up after receiving 60# POE's standard _stop event. 61 62sub _stop { 63 my ($object, $kernel, $heap) = @_[OBJECT, KERNEL, HEAP]; 64 65 print "Session $object->{'name'} stopped after $heap->{'counter'} loops.\n"; 66} 67 68#------------------------------------------------------------------------------ 69# This method is an event handler. It will be registered as a SIGINT 70# handler so that the session can acknowledge the signal. 71 72sub sigint { 73 my ($object, $from, $signal_name) = @_[OBJECT, SENDER, ARG0]; 74 75 print "$object->{'name'} caught SIG$signal_name from $from\n"; 76 # did not handle the signal 77 return 0; 78} 79 80#------------------------------------------------------------------------------ 81# This method is an event handler. It does most of counting work. It 82# loops by posting events back to itself. The session exits when 83# there is nothing left to do; this event handler causes that 84# condition when it stops posting events. 85 86sub increment { 87 my ($object, $kernel, $session, $heap) = @_[OBJECT, KERNEL, SESSION, HEAP]; 88 89 $heap->{'counter'}++; 90 91 if ($heap->{counter} % 2) { 92 $kernel->state('runtime_state', $object); 93 } 94 else { 95 $kernel->state('runtime_state'); 96 } 97 98 print "Session $object->{'name'}, iteration $heap->{'counter'}.\n"; 99 100 if ($heap->{'counter'} < 5) { 101 $kernel->post($session, 'increment'); 102 $kernel->yield('runtime_state', $heap->{counter}); 103 } 104 else { 105 # no more events. since there is nothing left to do, the session exits. 106 } 107} 108 109#------------------------------------------------------------------------------ 110# This state is added on every even count. It's removed on every odd 111# one. Every count posts an event here. 112 113sub runtime_state { 114 my ($self, $iteration) = @_[OBJECT, ARG0]; 115 print( 'Session ', $self->{name}, 116 ' received a runtime_state event during iteration ', 117 $iteration, "\n" 118 ); 119} 120 121#============================================================================== 122# Create ten Counter objects, and wrap them in sessions. 123 124package main; 125 126foreach my $name (qw(one two three four five six seven eight nine ten)) { 127 POE::Session->create( 128 object_states => [ 129 Counter->new($name) => [ qw(_start _stop increment sigint) ] 130 ], 131 ); 132} 133 134$poe_kernel->run(); 135 136exit; 137