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   184448 use v5.26;
  12         62  
7 12     12   5738 use Object::Pad 0.70 ':experimental(init_expr adjust_params)';
  12         94484  
  12         60  
8              
9             package Tangence::Registry 0.30;
10 10     10   6790 class Tangence::Registry :isa(Tangence::Object);
  10         30  
  10         499  
11              
12 12     12   2874 use Carp;
  12         28  
  12         882  
13              
14 12     12   80 use Tangence::Constants;
  12         25  
  12         2335  
15 12     12   83 use Tangence::Class;
  12         24  
  12         379  
16 12     12   63 use Tangence::Property;
  12         24  
  12         401  
17 12     12   4281 use Tangence::Struct;
  12         35  
  12         462  
18 12     12   93 use Tangence::Type;
  12         29  
  12         381  
19              
20 12     12   5508 use Tangence::Compiler::Parser;
  12         33  
  12         771  
21              
22 12     12   90 use Scalar::Util qw( weaken );
  12         21  
  12         14812  
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 1062 {
  11         40  
  11         21  
80             return (
81 11         98 id => 0,
82             registry => "BOOTSTRAP",
83             meta => Tangence::Class->for_perlname( $class ),
84             %args,
85             );
86             }
87              
88             field $_nextid { 1 };
89             field @_freeids;
90             field %_objects;
91              
92             ADJUST :params (
93             :$tanfile
94             ) {
95             my $id = 0;
96             weaken( $self->{registry} = $self );
97              
98             %_objects = ( $id => $self );
99             weaken( $_objects{$id} );
100             $self->add_prop_objects( $id => $self->describe );
101              
102             $self->load_tanfile( $tanfile );
103             }
104              
105             =head1 METHODS
106              
107             =cut
108              
109             =head2 get_by_id
110              
111             $obj = $registry->get_by_id( $id )
112              
113             Returns the object with the given object ID.
114              
115             This method is exposed to clients.
116              
117             =cut
118              
119 59         89 method get_by_id ( $id )
  59         108  
  59         80  
120 59     59 1 1597 {
121 59         197 return $_objects{$id};
122             }
123              
124 0         0 method method_get_by_id ( $ctx, $id )
  0         0  
  0         0  
  0         0  
125 0     0 0 0 {
126 0         0 return $self->get_by_id( $id );
127             }
128              
129             =head2 construct
130              
131             $obj = $registry->construct( $type, @args )
132              
133             Constructs a new exposed object of the given type, and returns it. Any
134             additional arguments are passed to the object's constructor.
135              
136             =cut
137              
138 14         35 method construct ( $type, @args )
  14         34  
  14         33  
  14         24  
139 14     14 1 799 {
140 14   33     100 my $id = shift @_freeids // ( $_nextid++ );
141              
142 14 50       61 Tangence::Class->for_perlname( $type ) or
143             croak "Registry cannot construct a '$type' as no class definition exists";
144              
145 14 50       40 eval { $type->can( "new" ) } or
  14         197  
146             croak "Registry cannot construct a '$type' as it has no ->new() method";
147              
148 14         88 my $obj = $type->new(
149             registry => $self,
150             id => $id,
151             @args
152             );
153              
154 14         330 $self->fire_event( "object_constructed", $id );
155              
156 14         99 weaken( $_objects{$id} = $obj );
157 14         85 $self->add_prop_objects( $id => $obj->describe );
158              
159 14         63 return $obj;
160             }
161              
162 2         3 method destroy_object ( $obj )
  2         4  
  2         4  
163 2     2 0 9 {
164 2         9 my $id = $obj->id;
165              
166 2 50       9 exists $_objects{$id} or croak "Cannot destroy ID $id - does not exist";
167              
168 2         12 $self->del_prop_objects( $id );
169              
170 2         8 $self->fire_event( "object_destroyed", $id );
171              
172 2         7 push @_freeids, $id; # Recycle the ID
173             }
174              
175             =head2 load_tanfile
176              
177             $registry->load_tanfile( $tanfile )
178              
179             Loads additional Tangence class and struct definitions from the given F<.tan>
180             file.
181              
182             =cut
183              
184 11         29 method load_tanfile ( $tanfile )
  11         24  
  11         23  
185 11     11 1 34 {
186             # Merely constructing this has the side-effect of declaring all the classes
187 11         184 Tangence::Registry::Parser->new->from_file( $tanfile );
188             }
189              
190             class Tangence::Registry::Parser :isa(Tangence::Compiler::Parser)
191             {
192             method make_class
193 12     12   45 {
194 12         115 return Tangence::Class->make( @_ );
195             }
196              
197             method make_struct
198 10     10   50 {
199 10         97 return Tangence::Struct->make( @_ );
200             }
201              
202             method make_property
203 82     82   188 {
204 82         494 return Tangence::Property->new( @_ );
205             }
206              
207             method make_type
208 195     195   544 {
209 195         639 return Tangence::Type->make( @_ );
210             }
211             }
212              
213             =head1 AUTHOR
214              
215             Paul Evans
216              
217             =cut
218              
219             0x55AA;