/[cvs]/joko/Scripts/psh/lib/POE/Component/Terminal.pm
ViewVC logotype

Contents of /joko/Scripts/psh/lib/POE/Component/Terminal.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations)
Sat Jun 15 08:15:50 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +8 -5 lines
+ bugfixes in ReadKey-behavious for Linux

1 #!/usr/bin/perl
2 ##
3 ## POE::Component::Terminal -- Terminal Component
4 ##
5 ## $Id: Terminal.pm,v 1.8 2002/06/15 08:08:51 cvsjoko Exp $
6 ##
7 ## $Log: Terminal.pm,v $
8 ## Revision 1.8 2002/06/15 08:08:51 cvsjoko
9 ## + modifications in Term::ReadKey behaviour
10 ##
11 ## Revision 1.7 2002/06/15 07:56:40 cvsjoko
12 ## + bugfixes for win32 (additional keys)
13 ##
14 ## Revision 1.6 2002/06/15 07:46:11 cvsjoko
15 ## + bugfixes for linux
16 ##
17 ## Revision 1.5 2002/06/15 05:19:36 cvsjoko
18 ## + modified order/way of key-handling-logic
19 ##
20 ## Revision 1.4 2002/06/15 04:28:10 cvsjoko
21 ## immediate polling, no delay
22 ##
23 ## Revision 1.3 2002/06/15 04:24:15 cvsjoko
24 ## + added modifier for running in linux or win32
25 ## + modified order of some commands in core key-polling
26 ##
27 ## Revision 1.2 2002/06/15 03:45:21 cvsjoko
28 ## + cvs id & log
29 ## + clearing inputbuffer just after getting the "enter"-key
30 ##
31 ##
32 package POE::Component::Terminal;
33
34 use strict;
35 #use strict qw ( vars refs );
36 use warnings;
37
38
39 use Carp qw( croak carp );
40
41 use POE;
42
43 use Term::ReadKey;
44 use Data::Dumper;
45
46 $POE::Component::Terminal::VERSION = 0.01;
47
48 my @args_needed = qw (
49 Alias
50 Caption
51 PromptPrefix
52 PromptPostfix
53 RequestSession
54 RequestState
55 ResponseSession
56 ResponseState
57 PromptChangeState
58 );
59
60 my $states = {
61 _start => 'start',
62 _stop => 'stop',
63 _signal => 'signal',
64 _default => 'default',
65 pollForKey => 'pollForKey',
66 recievePrompt => 'recievePrompt',
67 recieveResponse => 'recieveResponse',
68 };
69
70 sub RUNNING_IN_HELL () { $^O eq 'MSWin32' }
71
72 sub new {
73 my $class = shift;
74 $class = ref( $class ) || $class;
75 #my( %args ) = ( %default_args, @_ );
76 my $args = shift;
77
78 # bless class into object ($self)
79 my $self = bless {}, $class;
80
81 ## Check args
82 foreach my $arg_needed (@args_needed) {
83 croak "Need $arg_needed argument."
84 unless exists $args->{ $arg_needed };
85 }
86
87 # store entries from args to object ($self)
88 map { $self->{$_} = $args->{$_}; } keys %{$args};
89
90 if ( RUNNING_IN_HELL () ) {
91 $self->{conf}{KeyEnter} = 13;
92 $self->{conf}{KeyBackspace} = 8;
93 $self->{conf}{KeyCTRLC} = 3;
94 } else {
95 $self->{conf}{KeyEnter} = 10;
96 $self->{conf}{KeyBackspace} = 127;
97 $self->{conf}{KeyCTRLC} = 3;
98 }
99
100 ## Make our session. See $states defined up above . . .
101 POE::Session->create( object_states => [ $self => $states, ], );
102
103 return $self;
104 }
105
106 ##
107 ## start -- Startup state
108 ##
109 sub start {
110 my( $self, $kernel, $heap, $session, $sender ) =
111 @_[ OBJECT, KERNEL, HEAP, SESSION, SENDER ];
112
113 ## Pipe up if we're debugging
114 print STDERR "## ", __PACKAGE__, "::start\r\n" if $self->{Debug};
115
116 ## Set the alias requested so we can be post'd to
117 $kernel->alias_set( $self->{Alias} );
118
119 ## Remember session that created us for posting DispatchEvent
120 $self->{ _target } = $sender;
121
122 $heap->{state}{InputBuffer} = '';
123 $heap->{state}{Startup} = 1;
124 $heap->{state}{Caption} = $self->{Caption};
125 $heap->{state}{KeyPressed} = 0;
126 $heap->{state}{RequestPending} = 0;
127
128 # initially call worker-state
129 ReadMode 4;
130 $kernel->post($session, "pollForKey");
131
132 return;
133 }
134
135 ##
136 ## stop -- Shutdown state
137 ##
138 sub stop {
139 my( $self, $kernel, $heap ) = @_[ OBJECT, KERNEL, HEAP ];
140
141 ## Just pipe up if we're debugging
142 print STDERR "## ", __PACKAGE__, "::stop\r\n" if $self->{_debug};
143
144 return
145 }
146
147 ##
148 ## signal -- Handle any signals received
149 ##
150 sub signal {
151 my( $self, $heap, $signal ) = @_[ OBJECT, HEAP, ARG0 ];
152
153 ## Just pipe up if we're debugging
154 print STDERR "## ", __PACKAGE__, "::signal $signal\n" if $self->{_debug};
155
156 ## shut things down on TERM, QUIT, or INT
157 if( $signal =~ /^TERM|QUIT|INT/ ) {
158 delete $heap->{wheel}; # toss our listening wheel reference
159
160 ## Check for child wheels
161 my $live_wheels = scalar keys %{$heap->{wheels}};
162 if( $live_wheels ) {
163 print STDERR "Exiting with $live_wheels clients still active\n"
164 if $self->{_debug};
165 delete $heap->{wheels};
166 }
167 }
168
169 return
170 }
171
172 ##
173 ## default -- Catch any unhandled events for debugging
174 ##
175 sub default {
176 my( $self, $heap, $event ) = @_[ OBJECT, HEAP, ARG0 ];
177
178 ## Just pipe up if we're debugging
179 print STDERR "## ", __PACKAGE__, "::default got $event\n"
180 if $self->{_debug};
181
182 return
183 }
184
185
186
187
188
189
190
191 # ================ POE stuff
192
193 sub pollForKey {
194
195 my ($self, $kernel, $heap, $session) = @_[OBJECT, KERNEL, HEAP, SESSION ];
196
197 my $prompt_inlay = $heap->{state}{PromptInlay};
198 if ($prompt_inlay) { $prompt_inlay .= ' '; } else { $prompt_inlay = ''; }
199
200 my $prompt = "#> ";
201 $prompt = $self->{PromptPrefix} . ' ' . $prompt_inlay . $self->{PromptPostfix};
202
203 if ( (
204 ( $heap->{state}{KeyPressed} == 1 ) &&
205 ( $heap->{state}{RequestPending} == 0 )
206 ) ||
207 ( $heap->{state}{Startup} )
208 ) {
209 $heap->{state}{Startup} = 0;
210 $heap->{state}{KeyPressed} = 0;
211 my $outputline = $prompt . $heap->{state}{InputBuffer};
212 my $s = ' ' x (length($outputline) + 1);
213 print "\r", $s;
214 print "\r", $outputline;
215 #print $outputline;
216 }
217
218 my $key = ReadKey(-1);
219 if ( defined $key ) {
220
221 #print "key: ", ord($key), "\n";
222
223 # CTRL+C pressed?
224 if (ord($key) == $self->{conf}{KeyCTRLC}) {
225 ReadMode 1;
226 print "\n";
227 exit;
228 }
229
230 # enter pressed?
231 if (ord($key) == $self->{conf}{KeyEnter}) {
232
233 # if enter was pressed while request was pending,
234 # we should stop waiting for output and come back to prompt again,
235 if ($heap->{state}{RequestPending}) {
236 $kernel->post( $self->{ResponseSession} => $self->{ResponseState} => ' < stopped waiting for response');
237 }
238
239 # send command, if buffer is filled
240 my $buf = $heap->{state}{InputBuffer};
241 if ($buf) {
242 $heap->{state}{InputBuffer} = '';
243 $heap->{state}{RequestPending} = 1;
244 my $response_target = {
245 ResponseSession => $self->{ResponseSession},
246 ResponseState => $self->{ResponseState},
247 };
248 $kernel->post( $self->{RequestSession} => $self->{RequestState} => $buf, $response_target);
249 }
250
251 # prepare new loop for fresh prompt
252 print "\n";
253
254 }
255
256 # backspace pressed?
257 elsif (ord($key) == $self->{conf}{KeyBackspace}) {
258 $heap->{state}{InputBuffer} = substr($heap->{state}{InputBuffer}, 0, -1);
259 }
260
261 # unknown key?
262 elsif (ord($key) == 0) {
263 }
264
265 # normal key?
266 #elsif ($key =~ m/[a-zA-Z? ]/) {
267 else {
268 $heap->{state}{InputBuffer} .= $key;
269 #print $key;
270 }
271
272 # mark "KeyPressed" for next poll
273 $heap->{state}{KeyPressed} = 1;
274
275 }
276
277 $kernel->post($session, "pollForKey");
278 #$kernel->run_one_timeslice();
279 #$kernel->post($session, "pollForKey");
280 #$kernel->yield($session, "pollForKey");
281 #$kernel->delay("pollForKey", 0.1);
282 #$kernel->delay("pollForKey", 0.001);
283
284 }
285
286
287
288
289 sub recieveResponse {
290 my ($kernel, $heap, $session, $response) = @_[KERNEL, HEAP, SESSION, ARG0];
291 if ($response) {
292 print $response, "\n";
293 $heap->{state}{RequestPending} = 0;
294 }
295 }
296 sub recievePrompt {
297 my ($kernel, $heap, $session, $prompt_inlay) = @_[KERNEL, HEAP, SESSION, ARG0];
298 $heap->{state}{PromptInlay} = $prompt_inlay;
299 }
300
301
302 1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed