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