File Coverage

blib/lib/Tangence/Registry.pm
Criterion Covered Total %
statement 78 84 92.8
branch 3 6 50.0
condition 1 3 33.3
subroutine 20 21 95.2
pod 3 6 50.0
total 105 120 87.5


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