File Coverage

blib/lib/POEx/Tickit.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2013 -- leonerd@leonerd.org.uk
5              
6             package POEx::Tickit;
7              
8 4     4   270699 use strict;
  4         5  
  4         95  
9 4     4   14 use warnings;
  4         3  
  4         109  
10 4     4   18 use base qw( Tickit );
  4         4  
  4         3886  
11              
12             our $VERSION = '0.03';
13              
14             use Carp;
15              
16             use POE;
17             use POEx::Tickit::Driver;
18             use Tickit;
19              
20             =head1 NAME
21              
22             C - use C with C
23              
24             =head1 SYNOPSIS
25              
26             use POE;
27             use POEx::Tickit;
28              
29             my $tickit = POEx::Tickit->new;
30              
31             # Create some widgets
32             # ...
33            
34             $tickit->set_root_widget( $rootwidget );
35              
36             $tickit->run;
37              
38             =head1 DESCRIPTION
39              
40             This class allows a L user interface to run alongside other
41             L-driven code, using C as a source of IO events.
42              
43             =cut
44              
45             my $next_alias_id = 0;
46              
47             sub new
48             {
49             my $class = shift;
50             my %args = @_;
51              
52             my $self = $class->SUPER::new( %args );
53             $self->{session_alias} = __PACKAGE__ . "-" . $next_alias_id++;
54              
55             POE::Session->create(
56             object_states => [
57             $self => {
58             _start => "_poe_start",
59             sigwinch => "_poe_sigwinch",
60             input => "_poe_input",
61             output => "_poe_output",
62             timer => "_poe_timer",
63             timeout => "_poe_timeout",
64             _stop => "_poe_stop",
65             },
66             ],
67             inline_states => {
68             invoke => sub { $_[-1]->() },
69             },
70             );
71              
72             return $self;
73             }
74              
75             sub _make_writer
76             {
77             my $self = shift;
78             my ( $out ) = @_;
79              
80             $self->{writer} = POEx::Tickit::Driver->new(Handle => $out);
81              
82             return $self->{writer};
83             }
84              
85             sub _poe_start
86             {
87             my $self = $_[OBJECT];
88              
89             $_[KERNEL]->alias_set( $self->{session_alias} );
90              
91             $_[KERNEL]->sig( WINCH => sigwinch => );
92              
93             $_[KERNEL]->select_read( $self->term->get_input_handle, input => );
94             $_[KERNEL]->select_write( $self->term->get_output_handle, output => );
95             }
96              
97             sub _poe_stop
98             {
99             my $self = $_[OBJECT];
100              
101             $_[KERNEL]->sig( WINCH => () );
102              
103             $_[KERNEL]->select_read( $self->term->get_input_handle, () );
104             $_[KERNEL]->select_write( $self->term->get_output_handle, () );
105             }
106              
107             sub _poe_sigwinch
108             {
109             $_[OBJECT]->_SIGWINCH;
110             }
111              
112             sub _poe_input
113             {
114             my $self = $_[OBJECT];
115              
116             my $term = $self->term;
117              
118             $_[KERNEL]->alarm_remove( delete $_[HEAP]{timeout_id} ) if $_[HEAP]{timeout_id};
119              
120             $term->input_readable;
121              
122             _poe_timeout( @_ );
123             }
124              
125             sub _poe_output
126             {
127             my $self = $_[OBJECT];
128              
129             my $term = $self->term;
130              
131             $self->{writer}->flush( $self->term->get_output_handle );
132             }
133              
134             sub _poe_timeout
135             {
136             my $self = $_[OBJECT];
137             my $term = $self->term;
138              
139             if( defined( my $timeout = $term->check_timeout ) ) {
140             $_[HEAP]{timeout_id} = $_[KERNEL]->delay_set( timeout => $timeout / 1000 ); # msec
141             }
142             }
143              
144             sub _poe_timer
145             {
146             my $self = $_[OBJECT];
147             my ( $mode, $amount, $code ) = @_[ARG0..$#_];
148             if( $mode eq "after" ) {
149             $_[KERNEL]->delay_set( invoke => $amount, $code );
150             }
151             elsif( $mode eq "at" ) {
152             $_[KERNEL]->alarm_set( invoke => $amount, $code );
153             }
154             }
155              
156             sub later
157             {
158             my $self = shift;
159             POE::Kernel->post( $self->{session_alias}, invoke => $_[0] );
160             }
161              
162             sub timer
163             {
164             my $self = shift;
165             my ( $mode, $amount, $code ) = @_;
166             POE::Kernel->post( $self->{session_alias}, timer => $mode, $amount, $code );
167             }
168              
169             sub stop
170             {
171             my $self = shift;
172             POE::Kernel->call( $self->{session_alias}, _stop => );
173             }
174              
175             sub run
176             {
177             my $self = shift;
178              
179             POE::Session->create(
180             inline_states => {
181             _start => sub {
182             $_[KERNEL]->alias_set( "$self->{session_alias}-SIGINT" );
183             $_[KERNEL]->sig( INT => stop => );
184             },
185             stop => sub {
186             $self->stop;
187             },
188             },
189             );
190              
191             $self->setup_term;
192              
193             my $ret = eval { POE::Kernel->run };
194             my $e = $@;
195              
196             {
197             local $@;
198              
199             $self->teardown_term;
200             }
201              
202             die $@ if $@;
203             return $ret;
204             }
205              
206             =head1 AUTHOR
207              
208             Paul Evans
209              
210             =cut
211              
212             0x55AA;