/[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.8 - (show annotations)
Sat Jun 15 08:08:51 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
Changes since 1.7: +10 -3 lines
+ modifications in Term::ReadKey behaviour

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

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