All pastes #525896 Raw Edit

imMUte

public text v1 · immutable
#525896 ·published 2007-05-31 16:01 UTC
rendered paste body
Index: 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] );
 }