File Coverage

blib/lib/Games/3D/World.pm
Criterion Covered Total %
statement 58 98 59.1
branch 6 20 30.0
condition 1 3 33.3
subroutine 14 22 63.6
pod 17 18 94.4
total 96 161 59.6


line stmt bran cond sub pod time code
1              
2             # World - contains everything in the game world
3              
4             package Games::3D::World;
5              
6             # (C) by Tels
7              
8 1     1   24626 use strict;
  1         3  
  1         35  
9 1     1   6 use vars qw/$VERSION/;
  1         2  
  1         66  
10 1     1   445 use Games::3D::Template;
  1         4  
  1         1175  
11              
12             $VERSION = '0.07';
13              
14             ##############################################################################
15             # protected vars
16              
17             {
18             my $id = 1;
19 0     0 0 0 sub ID { return $id++;}
20 1     1   4 sub _reset_ID { $id = 1; }
21             }
22              
23             ##############################################################################
24             # methods
25              
26             sub new
27             {
28             # create a new world
29 1     1 1 1637 my $class = shift;
30            
31 1         4 my $self = bless {}, $class;
32              
33 1         7 $self->{things} = { };
34 1         5 $self->{render} = { };
35 1         3 $self->{thinks} = { };
36 1         5 $self->{templates} = {};
37 1         4 _reset_ID();
38              
39 1 50       6 if (@_ == 2)
40             {
41 0         0 $self->load_templates($_[0]);
42 0         0 $self->load_from_file($_[1]);
43             }
44              
45 1         3 $self->{time} = 0;
46              
47 1         4 $self;
48             }
49              
50             sub load_from_file
51             {
52 0     0 1 0 my ($self,$file) = @_;
53              
54 0         0 $self->{file} = $file;
55 0         0 $self->{things} = { };
56 0         0 _reset_ID();
57              
58 0         0 $self;
59             }
60              
61             sub load_templates
62             {
63 1     1 1 4 my ($self,$file) = @_;
64              
65 1 50       5 if (!ref($file))
66             {
67             # got filename, so read in data
68 1 50       64 open FILE, "$file" or die ("Cant read $file: $!");
69 1         5 local $/ = undef; # slurp mode
70 1         26 my $doc = ;
71 1         3 $file = \$doc;
72 1         15 close FILE;
73             }
74              
75 1         4 $self->{templates} = {};
76 1         10 my @objects = Games::3D::Template::from_string($$file);
77              
78 1 50 33     6 if (@objects == 1 && !ref($objects[0]))
79             {
80 0         0 die($objects[0]);
81             }
82 1         3 foreach my $o (@objects)
83             {
84 9 50       25 if (exists $self->{templates}->{$o->{class}})
85             {
86 0         0 warn ("Template for class $o->{class} already seen");
87             }
88 9         25 $self->{templates}->{$o->{class}} = $o;
89 9         19 $o->{_world} = $self;
90             }
91              
92 1         5 $self;
93             }
94              
95             sub templates
96             {
97 1     1 1 2 my $self = shift;
98 1         2 scalar keys %{$self->{templates}};
  1         7  
99             }
100              
101             sub save_templates
102             {
103 0     0 1 0 my ($self,$file) = @_;
104            
105 0         0 $self;
106             }
107              
108             sub save_to_file
109             {
110 0     0 1 0 my ($self,$file) = @_;
111            
112 0         0 $self->{file} = $file;
113 0         0 $self;
114             }
115              
116             sub reload
117             {
118 0     0 1 0 my $self = shift;
119              
120 0         0 $self->load_from_file($self->{file});
121             }
122              
123             sub register
124             {
125             # register an object with yourself
126 0     0 1 0 my ($self,$obj) = @_;
127              
128 0         0 $obj->{id} = ID(); # get it a new ID
129 0         0 $self->{things}->{$obj->{id}} = $obj; # store it
130 0         0 $self->{things}->{_world} = $self; # give thing access to us
131 0 0       0 if ($obj->{visible})
132             {
133 0         0 $self->{render}->{$obj->{id}} = $obj; # store it
134             }
135 0 0       0 if ($obj->{think_time} != 0)
136             {
137 0         0 $self->{think}->{$obj->{id}} = $obj; # store it
138             }
139              
140 0         0 $self;
141             }
142              
143             sub unregister
144             {
145             # should ONLY be called via $thing->{_world}->unregister($thing) !
146 0     0 1 0 my ($self,$thing) = @_;
147              
148 0         0 my $id = $thing->{id};
149 0         0 delete $self->{render}->{$id};
150 0         0 delete $self->{things}->{$id};
151             # tricky, what happens if called inside update()?
152 0         0 delete $self->{think}->{$id};
153            
154 0         0 $self;
155             }
156              
157             sub things
158             {
159             # get count of things
160 1     1 1 6 my ($self) = @_;
161              
162 1         3 scalar keys %{$self->{things}};
  1         8  
163             }
164              
165             sub thinkers
166             {
167             # get count of thinking things
168 0     0 1 0 my ($self) = @_;
169              
170 0         0 scalar keys %{$self->{think}};
  0         0  
171             }
172              
173             sub update
174             {
175 1     1 1 3 my ($self,$now) = @_;
176              
177 1         3 $self->{time} = $now; # cache time
178 1         2 foreach my $id (keys %{$self->{think}})
  1         5  
179             {
180 0         0 my $thing = $self->{think}->{$id};
181 0 0       0 if ($thing->{next_think} >= $now)
182             {
183 0         0 $thing->think($now);
184             }
185             # if the thing is in transition between states, let it update itself
186 0 0       0 $thing->update($now) if $thing->{state_endtime} != 0;
187              
188             # XXX TODO: does not handle things that no longer want to think()
189             }
190 1         6 $self;
191             }
192              
193             sub time
194             {
195 1     1 1 2 my $self = shift;
196              
197 1         6 $self->{time};
198             }
199              
200             sub render
201             {
202 1     1 1 3 my ($self,$now,$callback) = @_;
203              
204 1         3 foreach my $id (keys %{$self->{render}})
  1         6  
205             {
206 0         0 &$callback ( $now, $self->{render}->{$id} );
207             }
208 1         6 $self;
209             }
210              
211             sub create
212             {
213             # create an object based on a template (class name)
214 3     3 1 536 my ($self,$class) = @_;
215              
216 3 50       15 return undef if !exists $self->{templates}->{$class};
217 3         22 $self->{templates}->{$class}->create_thing();
218             }
219              
220             sub find_template
221             {
222             # given a class name, return the template object for it
223 6     6 1 11 my ($self,$class) = @_;
224              
225 6         24 $self->{templates}->{$class};
226             }
227              
228 1     1 1 5 sub id { 0; }
229              
230             1;
231              
232             __END__