me8100_test_perl/ME8100.pm
changeset 32 e0b741bb5ce0
parent 31 33280ad0f4b2
--- a/me8100_test_perl/ME8100.pm	Mon Jan 28 22:23:55 2002 +0100
+++ b/me8100_test_perl/ME8100.pm	Wed Jan 30 12:46:42 2002 +0100
@@ -12,12 +12,12 @@
 my $gotSignal = 0;
 my $opt_async = 0;
 
-sub iohandler($);
+sub _iohandler($);
 sub import { $opt_async = grep { /^:async/ } @_; }
 
 # Install the signal handler only if we have passed the ':async' tag
 # to the module...
-INIT { $SIG{IO} = \&iohandler if $opt_async; }
+INIT { $SIG{IO} = \&_iohandler if $opt_async; }
 
 # Create a new object. Open all the named devices (read only)
 # and read the current values (as the driver guarantees the
@@ -59,7 +59,7 @@
 
     $self->{bits} = $idx * 16;
     $self->{inputBits} = $inputBits;
-    $self->{oldBits} = "";		
+    $self->{oldBits} = undef;		
     $self->{changedBits} = "";
 
     $self->{changed} = [split //, "0" x $self->{bits} ];
@@ -73,11 +73,11 @@
     # the suddenly succeeding select() indicate a possible successful
     # read... But only one of them will be successful!
 
-    my ($self, $timeout) = @_;
+    my ($self, %args) = @_;
 
     {
 	local $SIG{IO} = sub { $gotSignal = $_[0] } if $opt_async;
-	my @ready = $self->{select}->can_read($timeout);
+	my @ready = $self->{select}->can_read($args{timeout});
 
 	if (!@ready) {
 	    warn "select() returned nothing: $!\n";
@@ -87,9 +87,7 @@
 	$self->_read(@ready);
     }
 
-    $gotSignal and iohandler($gotSignal);
-    $self->{changedBits} = "";
-    $self->{changed} = [ split //, "0" x $self->{bits} ];
+    $gotSignal and _iohandler($gotSignal);
     return split //, unpack("b*", $self->{inputBits});
 }
 
@@ -100,7 +98,7 @@
 
 # Read *really* from the board and store the result at the proper
 # element of our @inputs array.
-sub _read {
+sub _read($@) {
     my ($self, @fds) = @_;
     my $val;	# bit0-7 bit8-15
 
@@ -113,6 +111,7 @@
     # Now get the difference between the old bits and the current values...
     # and then add these values to the array containing the change counters
     
+    $self->{oldBits} = $self->{inputBits} if not defined $self->{oldBits};
     my $changedBits = $self->{inputBits} ^ $self->{oldBits};
 
     my @changed = split //, unpack("b*", $changedBits);
@@ -128,7 +127,7 @@
     $self->{oldBits} = $self->{inputBits};
 }
 
-sub iohandler($) { 
+sub _iohandler($) { 
     # If an interrupt occurs, we've to search for the file descriptor(s)
     # that caused the interrupt.  This is done by a lookup in the module global
     # %Objects hash.  ("fd" -> { fd => XXX, object => XXXX })
@@ -139,9 +138,6 @@
     # anymore, we stored the reference itself behind the key, as well
     # as the object reference...
     
-
-    # Now a race condition might occur.  It's possible that an other
-    # select() runs too (called in the read() method).
     my $select = new IO::Select(map { $Objects{$_}->{fd} } keys %Objects);
     my @ready = $select->can_read(0);
 
@@ -156,20 +152,25 @@
 
 sub changed {
     my $self = shift;
+    my @changed = @{$self->{changed}};
     my $r = 0;
 
-    wantarray and return @{$self->{changed}};
-    foreach (@{$self->{changed}}) {
+    $self->{changedBits} = "";
+    $self->{changed} = [ split //, "0" x $self->{bits} ];
+
+    wantarray and return @changed;
+
+    foreach (@changed) {
 	$r += $_;
     }
     return $r;
 }
 
-sub DESTROY
-{
-    my $self = shift;
-    delete @Objects{ @{$self->{fds}} };
-}
+#sub DESTROY
+#{
+#    my $self = shift;
+#    delete @Objects{ @{$self->{fds} }};
+#}
 
 
 #-- Documenation follows 
@@ -199,7 +200,7 @@
 
 Creates a new ME8100 object connected to all the listed devices.
 
-=item read([I<timeout>])
+=item read(I<[timeout =E<gt> timeout]>)
 
 Read the input from the devices.  This call is guaranteed to succeede
 on the first run, but every following call will block until the status
@@ -207,21 +208,22 @@
 
 A timeout may be passed.
 
-Every read() resets the register for obtaining the changed bits.
-
 On success an array of the input bits is returned, otherwise undef.
 
 =item status()
 
 Returns an array with the current status of all input bits.
-Never blocks.
+Never blocks.  No side effects.
 
 =item changed()
 
-Returns an array containing the number of detected changes per input
-bit.
+In array context returns an array containing the counts of changes
+for every single bit.  In scalar context returns the total number of
+changes.
 
-=item iohandler(I<signal>)
+Every call resets the counter.
+
+=item _iohandler(I<signal>)
 
 For internal use only.