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-2022 -- leonerd@leonerd.org.uk
5              
6 12     12   145895 use v5.26;
  12         52  
7 12     12   4563 use Object::Pad 0.57;
  12         74555  
  12         49  
8              
9             package Tangence::Registry 0.29;
10 10     10   4755 class Tangence::Registry :isa(Tangence::Object);
  10         22  
  10         381  
11              
12 12     12   2135 use Carp;
  12         23  
  12         1449  
13              
14 12     12   75 use Tangence::Constants;
  12         19  
  12         2016  
15 12     12   74 use Tangence::Class;
  12         33  
  12         244  
16 12     12   48 use Tangence::Property;
  12         19  
  12         241  
17 12     12   3523 use Tangence::Struct;
  12         33  
  12         414  
18 12     12   71 use Tangence::Type;
  12         20  
  12         370  
19              
20 12     12   4642 use Tangence::Compiler::Parser;
  12         30  
  12         615  
21              
22 12     12   79 use Scalar::Util qw( weaken );
  12         17  
  12         12183  
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         29 sub BUILDARGS ( $class, %args )
79 11     11 0 832 {
  11         34  
  11         19  
80             return (
81 11         77 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         91 method get_by_id ( $id )
  59         83  
  59         65  
122 59     59 1 1361 {
123 59         192 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         32  
  14         22  
141 14     14 1 687 {
142 14   33     160 my $id = shift @_freeids // ( $_nextid++ );
143              
144 14 50       61 Tangence::Class->for_perlname( $type ) or
145             croak "Registry cannot construct a '$type' as no class definition exists";
146              
147 14 50       36 eval { $type->can( "new" ) } or
  14         162  
148             croak "Registry cannot construct a '$type' as it has no ->new() method";
149              
150 14         66 my $obj = $type->new(
151             registry => $self,
152             id => $id,
153             @args
154             );
155              
156 14         208 $self->fire_event( "object_constructed", $id );
157              
158 14         76 weaken( $_objects{$id} = $obj );
159 14         56 $self->add_prop_objects( $id => $obj->describe );
160              
161 14         45 return $obj;
162             }
163              
164 2         21 method destroy_object ( $obj )
  2         5  
  2         3  
165 2     2 0 13 {
166 2         7 my $id = $obj->id;
167              
168 2 50       11 exists $_objects{$id} or croak "Cannot destroy ID $id - does not exist";
169              
170 2         22 $self->del_prop_objects( $id );
171              
172 2         11 $self->fire_event( "object_destroyed", $id );
173              
174 2         6 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         21 method load_tanfile ( $tanfile )
  11         21  
  11         19  
187 11     11 1 24 {
188             # Merely constructing this has the side-effect of declaring all the classes
189 11         145 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   36 {
196 12         77 return Tangence::Class->make( @_ );
197             }
198              
199             method make_struct
200 10     10   36 {
201 10         78 return Tangence::Struct->make( @_ );
202             }
203              
204             method make_property
205 82     82   169 {
206 82         398 return Tangence::Property->new( @_ );
207             }
208              
209             method make_type
210 195     195   394 {
211 195         540 return Tangence::Type->make( @_ );
212             }
213             }
214              
215             =head1 AUTHOR
216              
217             Paul Evans
218              
219             =cut
220              
221             0x55AA;