File Coverage

blib/lib/Games/3D/Sensor.pm
Criterion Covered Total %
statement 37 60 61.6
branch 3 18 16.6
condition 11 16 68.7
subroutine 7 12 58.3
pod 5 5 100.0
total 63 111 56.7


line stmt bran cond sub pod time code
1              
2             # Sensor - monitor conditions and trigger when they are met
3              
4             package Games::3D::Sensor;
5              
6             # (C) by Tels
7              
8 1     1   24251 use strict;
  1         3  
  1         29  
9              
10 1     1   6 use Exporter;
  1         1  
  1         59  
11 1         151 use Games::3D::Signal qw/
12             SIG_FLIP SIG_OFF SIG_DIE
13             SIG_ACTIVATE SIG_DEACTIVATE
14 1     1   448 /;
  1         15  
15 1     1   589 use Games::3D::Link;
  1         4  
  1         59  
16 1     1   8 use vars qw/@ISA @EXPORT_OK $VERSION/;
  1         1  
  1         777  
17             @ISA = qw/Exporter Games::3D::Link/;
18              
19             $VERSION = '0.01';
20              
21             sub COND_MET() { 1; }
22             sub COND_NOT_MET() { 2; }
23             sub COND_UNCOND() { 3; }
24              
25             sub SENSOR_BELOW() { 0; }
26             sub SENSOR_OVER() { 1; }
27             sub SENSOR_BETWEEN() { 2; }
28             sub SENSOR_DIED() { 3; }
29             sub SENSOR_ACTIVE() { 4; }
30             sub SENSOR_INACTIVE() { 5; }
31              
32             # periodic re-check required
33             sub SENSOR_PERIODIC() { 1000; } # dont use this type, only for comp.
34              
35             sub SENSOR_VISIBLE() { 1001; }
36             sub SENSOR_DISTANCE() { 1002; }
37              
38             @EXPORT_OK = qw/
39             COND_MET COND_NOT_MET COND_UNCOND
40             SENSOR_BELOW
41             SENSOR_BETWEEN
42             SENSOR_OVER
43             SENSOR_DIED
44             SENSOR_ACTIVE
45             SENSOR_INACTIVE
46             SENSOR_VISIBLE
47             SENSOR_DISTANCE
48             /;
49              
50             ##############################################################################
51             # methods
52              
53             sub _init
54             {
55 3     3   6 my $self = shift;
56 3         4 my $args = $_[0];
57              
58 3 50       18 $args = { @_ } if ref($_[0]) ne 'HASH';
59              
60 3         5 my $obj = $args->{obj};
61 3         4 my $id = $obj->{id};
62 3         17 $self->{watch} = {
63             $id => [ $obj, $args->{what} ], # object(s) to watch for
64             };
65              
66 3   50     11 $self->{A} = $args->{A} || 0; # range A..B
67 3   50     24 $self->{B} = $args->{B} || $args->{A} || 0; # range A..B
68 3 50       9 warn ("A=$self->{A} > B=$self->{B}\n") if
69             $self->{A} > $self->{B};
70 3   100     11 $self->{type} = $args->{type} || SENSOR_BELOW;# signal must be below A
71              
72 3         4 $self->{periodic} = 0; # check only on change
73 3 50       7 $self->{periodic} = 1
74             if $self->{type} > SENSOR_PERIODIC; # check periodically
75            
76 3   50     11 $self->{delay} = $args->{delay} || 0; # immidiately
77 3   100     12 $self->{repeat} = $args->{repeat} || 2000; # 2 seconds if count != 1
78 3   50     13 $self->{rand} = $args->{rand} || 0; # exactly
79 3   50     12 $self->{count} = $args->{count} || 1; # one signal
80 3   100     17 $self->{when} = $args->{when} || COND_UNCOND; # in and outside of range
81 3         5 $self->{fixed_output} = $args->{fixed_output};# ON and OFF are default
82              
83 3         12 $self;
84             }
85              
86             sub signal
87             {
88 0     0 1   my ($self,$input,$sig) = @_;
89              
90             # my $id = $input; $id = $input->{id} if ref($id);
91             # print "# ",$self->name()," received signal $sig from $id\n";
92              
93 0 0         die ("Unregistered input $input tried to send signal to link $self->{id}")
94             if !exists $self->{inputs}->{$input};
95              
96             # if the signal is DIE, DESTROY yourself
97 0 0         if ($sig == SIG_DIE)
98             {
99 0           $self->kill();
100 0           return;
101             }
102             # if the signal is ACTIVATE or DEACTIVATE, (in)activate yourself
103 0 0         if ($sig == SIG_ACTIVATE)
    0          
104             {
105 0           $self->activate();
106 0           return; # don't relay this signal
107             }
108             elsif ($sig == SIG_DEACTIVATE)
109             {
110 0           $self->deactivate();
111 0           return; # don't relay this signal
112             }
113              
114             # ignore all other signals
115 0           return; # don't relay this signal
116             }
117              
118             BEGIN
119             {
120             # inherit these from Thingy instead from Link:
121 1     1   6 *link = \&Games::3D::Thingy::link;
122 1         2 *unlink = \&Games::3D::Thingy::unlink;
123 1         214 *add_input = \&Games::3D::Thingy::add_input;
124             }
125              
126             sub and_gate
127             {
128 0     0 1   my $self = shift;
129              
130 0           warn ("Sensors cannot act as AND gates.\n");
131             }
132              
133             sub watch
134             {
135             # bind an additional target to the sensor
136 0     0 1   my ($self,$dst,$what) = @_;
137              
138 0           my $id = $dst->{id};
139 0           $self->{watch} = {
140             $id => [ $dst, $what ], # object(s) to watch for
141             };
142 0           $self;
143             }
144              
145             sub when
146             {
147 0     0 1   my ($self) = shift;
148              
149 0 0         $self->{when} = shift if @_ > 0;
150 0           $self->{when};
151             }
152              
153             sub type
154             {
155 0     0 1   my ($self) = shift;
156              
157 0 0         $self->{type} = shift if @_ > 0;
158 0           $self->{type};
159             }
160              
161             1;
162              
163             __END__