1#!/usr/local/bin/perl -w -I..
2
3# This is a simple test of "package sessions".  These are similar to
4# object sessions, but they work with packages instead of objects.  It
5# is also a simpler test than sessions.perl.
6
7use strict;
8use lib '../lib';
9use POE;
10
11#==============================================================================
12# Counter is a package composed of event handler functions.  It is
13# never instantiated as an object here.
14
15package Counter;
16use strict;
17use POE::Session;
18                                        # stupid scope trick, part 1 of 3
19$Counter::name = '';
20
21#------------------------------------------------------------------------------
22# This is a normal subroutine, not an object method.  It sets up the
23# session's variables and sets the session in motion.
24
25sub _start {
26  my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
27                                        # register a signal handler
28  $kernel->sig('INT', 'sigint');
29                                        # initialize the counter
30  $heap->{'counter'} = 0;
31                                        # stupid scope trick, part 2 of 3
32  $heap->{'name'} = $Counter::name;
33                                        # hello, world!
34  print "Session $heap->{'name'} started.\n";
35                                        # start things moving
36  $kernel->post($session, 'increment');
37}
38
39#------------------------------------------------------------------------------
40# This is a normal subroutine, not an object method.  It cleans up
41# after receiving POE's standard _stop event.
42
43sub _stop {
44  my $heap = $_[HEAP];
45
46  print "Session $heap->{'name'} stopped after $heap->{'counter'} loops.\n";
47}
48
49#------------------------------------------------------------------------------
50# This is a normal subroutine, and not an object method.  It will be
51# registered as a SIGINT handler so that the session can acknowledge
52# the signal.
53
54sub sigint {
55  my ($heap, $from, $signal_name) = @_[HEAP, SENDER, ARG0];
56
57  print "$heap->{'name'} caught SIG$signal_name from $from\n";
58                                        # did not handle the signal
59  return 0;
60}
61
62#------------------------------------------------------------------------------
63# This is a normal subroutine, and not an object method.  It does most
64# of the counting work.  It loops by posting events back to itself.
65# The session exits when there is nothing left to do; this event
66# handler causes that condition when it stops posting events.
67
68sub increment {
69  my ($package, $kernel, $session, $heap) = @_[OBJECT, KERNEL, SESSION, HEAP];
70
71  $heap->{'counter'}++;
72
73  if ($heap->{counter} % 2) {
74    $kernel->state('runtime_state', $package);
75  }
76  else {
77    $kernel->state('runtime_state');
78  }
79
80  print "Session $heap->{'name'}, iteration $heap->{'counter'}.\n";
81
82  if ($heap->{'counter'} < 5) {
83    $kernel->post($session, 'increment');
84    $kernel->yield('runtime_state', $heap->{counter});
85  }
86  else {
87    # no more events.  since there is nothing left to do, the session exits.
88  }
89}
90
91#------------------------------------------------------------------------------
92# This state is added on every even count.  It's removed on every odd
93# one.  Every count posts an event here.
94
95sub runtime_state {
96  my ($session, $heap, $iteration) = @_[SESSION, HEAP, ARG0];
97  print( 'Session ', $heap->{name},
98         ' received a runtime_state event during iteration ',
99         $iteration, "\n"
100       );
101}
102
103#==============================================================================
104# Create ten Counter sessions, all sharing the subs in package
105# Counter.  In a way, POE's sessions provide a simple form of object
106# instantiation.
107
108package main;
109
110foreach my $name (qw(one two three four five six seven eight nine ten)) {
111                                        # stupid scope trick, part 3 of 3
112  $Counter::name = $name;
113                                        # create the session
114  POE::Session->create(
115    package_states => [
116      Counter => [ qw(_start _stop increment sigint) ]
117    ]
118  );
119}
120
121$poe_kernel->run();
122
123exit;
124
125