#!/usr/bin/perl -w # This is another simple functionality test. It tests sessions that # are composed of objects (also called "object sessions"). It is # simpler than sessions.perl in many ways. 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 _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 _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 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 increment { my ($object, $kernel, $session, $heap) = @_[OBJECT, KERNEL, SESSION, HEAP]; $heap->{'counter'}++; if ($heap->{counter} % 2) { $kernel->state('runtime_state', $object); } 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 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) => [ qw(_start _stop increment sigint) ] ], ); } $poe_kernel->run(); exit;