File Coverage

blib/lib/Tangence/Registry.pm
Criterion Covered Total %
statement 73 79 92.4
branch 3 6 50.0
condition 1 3 33.3
subroutine 17 18 94.4
pod 3 6 50.0
total 97 112 86.6


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2010-2024 -- leonerd@leonerd.org.uk
5              
6 12     12   834039 use v5.26;
  12         47  
7 12     12   74 use warnings;
  12         31  
  12         862  
8 12     12   7162 use Object::Pad 0.800 ':experimental(adjust_params)';
  12         120577  
  12         932  
9              
10             package Tangence::Registry 0.33;
11 10     10   8271 class Tangence::Registry :isa(Tangence::Object);
  10         41  
  10         1849  
12              
13 12     12   2831 use Carp;
  12         27  
  12         1019  
14              
15 12     12   79 use Tangence::Constants;
  12         22  
  12         2947  
16 12     12   91 use Tangence::Class;
  12         23  
  12         428  
17 12     12   67 use Tangence::Property;
  12         22  
  12         373  
18 12     12   6455 use Tangence::Struct;
  12         48  
  12         580  
19 12     12   132 use Tangence::Type;
  12         36  
  12         424  
20              
21 12     12   7898 use Tangence::Compiler::Parser;
  12         51  
  12         1371  
22              
23 12     12   112 use Scalar::Util qw( weaken );
  12         24  
  12         26265  
24              
25             Tangence::Class->declare(
26             __PACKAGE__,
27              
28             methods => {
29             get_by_id => {
30             args => [ [ id => 'int' ] ],
31             ret => 'obj',
32             },
33             },
34              
35             events => {
36             object_constructed => {
37             args => [ [ id => 'int' ] ],
38             },
39             object_destroyed => {
40             args => [ [ id => 'int' ] ],
41             },
42             },
43              
44             props => {
45             objects => {
46             dim => DIM_HASH,
47             type => 'str',
48             }
49             },
50             );
51              
52             =head1 NAME
53              
54             C - object manager for a C server
55              
56             =head1 DESCRIPTION
57              
58             This subclass of L acts as a container for all the exposed
59             objects in a L server. The registry is used to create exposed
60             objects, and manages their lifetime. It maintains a reference to all the
61             objects it creates, so it can dispatch incoming messages from clients to them.
62              
63             =cut
64              
65             =head1 CONSTRUCTOR
66              
67             =cut
68              
69             =head2 new
70              
71             $registry = Tangence::Registry->new;
72              
73             Returns a new instance of a C object. An entire server
74             requires one registry object; it will be shared among all the client
75             connections to that server.
76              
77             =cut
78              
79 11         40 sub BUILDARGS ( $class, %args )
80 11     11 0 3359570 {
  11         56  
  11         24  
81             return (
82 11         171 id => 0,
83             registry => "BOOTSTRAP",
84             meta => Tangence::Class->for_perlname( $class ),
85             %args,
86             );
87             }
88              
89             field $_nextid = 1;
90             field @_freeids;
91             field %_objects;
92              
93             ADJUST :params (
94             :$tanfile
95             ) {
96             my $id = 0;
97             weaken( $self->{registry} = $self );
98              
99             %_objects = ( $id => $self );
100             weaken( $_objects{$id} );
101             $self->add_prop_objects( $id => $self->describe );
102              
103             $self->load_tanfile( $tanfile );
104             }
105              
106             =head1 METHODS
107              
108             =cut
109              
110             =head2 get_by_id
111              
112             $obj = $registry->get_by_id( $id );
113              
114             Returns the object with the given object ID.
115              
116             This method is exposed to clients.
117              
118             =cut
119              
120 59     59 1 1949 method get_by_id ( $id )
  59         310  
  59         116  
  59         94  
121             {
122 59         346 return $_objects{$id};
123             }
124              
125 0     0 0 0 method method_get_by_id ( $ctx, $id )
  0         0  
  0         0  
  0         0  
  0         0  
126             {
127 0         0 return $self->get_by_id( $id );
128             }
129              
130             =head2 construct
131              
132             $obj = $registry->construct( $type, @args );
133              
134             Constructs a new exposed object of the given type, and returns it. Any
135             additional arguments are passed to the object's constructor.
136              
137             =cut
138              
139 14     14 1 1151 method construct ( $type, @args )
  14         109  
  14         44  
  14         43  
  14         32  
140             {
141 14   33     316 my $id = shift @_freeids // ( $_nextid++ );
142              
143 14 50       103 Tangence::Class->for_perlname( $type ) or
144             croak "Registry cannot construct a '$type' as no class definition exists";
145              
146 14 50       45 eval { $type->can( "new" ) } or
  14         255  
147             croak "Registry cannot construct a '$type' as it has no ->new() method";
148              
149 14         100 my $obj = $type->new(
150             registry => $self,
151             id => $id,
152             @args
153             );
154              
155 14         436 $self->fire_event( "object_constructed", $id );
156              
157 14         72 weaken( $_objects{$id} = $obj );
158 14         85 $self->add_prop_objects( $id => $obj->describe );
159              
160 14         75 return $obj;
161             }
162              
163 2     2 0 5 method destroy_object ( $obj )
  2         16  
  2         4  
  2         4  
164             {
165 2         10 my $id = $obj->id;
166              
167 2 50       13 exists $_objects{$id} or croak "Cannot destroy ID $id - does not exist";
168              
169 2         15 $self->del_prop_objects( $id );
170              
171 2         14 $self->fire_event( "object_destroyed", $id );
172              
173 2         11 push @_freeids, $id; # Recycle the ID
174             }
175              
176             =head2 load_tanfile
177              
178             $registry->load_tanfile( $tanfile );
179              
180             Loads additional Tangence class and struct definitions from the given F<.tan>
181             file.
182              
183             =cut
184              
185 11     11 1 30 method load_tanfile ( $tanfile )
  11         52  
  11         32  
  11         23  
186             {
187             # Merely constructing this has the side-effect of declaring all the classes
188 11         188 Tangence::Registry::Parser->new->from_file( $tanfile );
189             }
190              
191             class Tangence::Registry::Parser :isa(Tangence::Compiler::Parser)
192             {
193             method make_class
194             {
195             return Tangence::Class->make( @_ );
196             }
197              
198             method make_struct
199             {
200             return Tangence::Struct->make( @_ );
201             }
202              
203             method make_property
204             {
205             return Tangence::Property->new( @_ );
206             }
207              
208             method make_type
209             {
210             return Tangence::Type->make( @_ );
211             }
212             }
213              
214             =head1 AUTHOR
215              
216             Paul Evans
217              
218             =cut
219              
220             0x55AA;