/[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.7 - (show annotations)
Sat Jun 15 07:56:40 2002 UTC (22 years, 3 months ago) by cvsjoko
Branch: MAIN
Changes since 1.6: +16 -8 lines
+ bugfixes for win32 (additional keys)

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

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