rendered paste bodyIndex: ReadWrite.pm
===================================================================
--- ReadWrite.pm (revision 2190)
+++ ReadWrite.pm (working copy)
@@ -28,6 +28,8 @@
sub STATE_WRITE () { 14 }
sub STATE_READ () { 15 }
sub UNIQUE_ID () { 16 }
+sub PAUSE_INPUT () { 17 }
+sub PAUSE_INPUT_QUEUE () { 18 }
sub CRIMSON_SCOPE_HACK ($) { 0 }
@@ -238,7 +240,7 @@
}
#------------------------------------------------------------------------------
-# Redefine the select-read handler. This uses stupid closure tricks
+# Redefine the select-read handler. This uses clever closure tricks
# to prevent keeping extra references to $self around.
sub _define_read_state {
@@ -275,13 +277,13 @@
my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
if (defined(my $raw_input = $driver->get($handle))) {
$$input_filter->get_one_start($raw_input);
+ my @recs;
while (1) {
my $next_rec = $$input_filter->get_one();
last unless @$next_rec;
- foreach my $cooked_input (@$next_rec) {
- $k->call($me, $$event_input, $cooked_input, $unique_id);
- }
+ push @recs, @$next_rec;
}
+ $self->_cook_input($me, $$input_filter, $$event_input, $unique_id, \@recs);
}
else {
$$event_error and $k->call(
@@ -307,9 +309,7 @@
# The actual code starts here.
my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
if (defined(my $raw_input = $driver->get($handle))) {
- foreach my $cooked_input (@{$$input_filter->get($raw_input)}) {
- $k->call($me, $$event_input, $cooked_input, $unique_id);
- }
+ $self->_cook_input($me, $$input_filter, $$event_input, $unique_id, $$input_filter->get($raw_input));
}
else {
$$event_error and $k->call(
@@ -320,16 +320,32 @@
}
);
}
- # register the state's select
+ # register the state's select
$poe_kernel->select_read($self->[HANDLE_INPUT], $self->[STATE_READ]);
}
- # undefine the select, just in case
+ # undefine the select, just in case
else {
$poe_kernel->select_read($self->[HANDLE_INPUT])
}
}
#------------------------------------------------------------------------------
+#
+sub _cook_input {
+ my ($self, $filter, $me, $event, $uid, $records) = @_;
+ while ( my $record = shift @$records) {
+ if ( $self->[PAUSE_INPUT] ) {
+ unshift @$records, $record;
+ $self->[PAUSE_INPUT_QUEUE] = $records;
+ return;
+ } else {
+ $k->call($me, $event, $record, $uid);
+ }
+ }
+}
+
+
+#------------------------------------------------------------------------------
# Redefine events.
sub event {
@@ -595,12 +611,21 @@
sub pause_input {
my $self = shift;
return unless defined $self->[HANDLE_INPUT];
+ $self->[PAUSE_INPUT] = 1;
$poe_kernel->select_pause_read( $self->[HANDLE_INPUT] );
}
# Resume the wheel's input watcher.
sub resume_input {
my $self = shift;
+ $self->[PAUSE_INPUT] = 0;
+ $self->_cook_input( # lets clear out the stack of crap we held up before
+ $self->[FILTER_INPUT],
+ $me, # ToDo: somehow we need to get the parent session here!
+ $self->[EVENT_INPUT],
+ $self->[UNIQUE_ID],
+ $self->[PAUSE_INPUT_QUEUE]
+ );
return unless defined $self->[HANDLE_INPUT];
$poe_kernel->select_resume_read( $self->[HANDLE_INPUT] );
}