Mercurial > pub > Impl
comparison lib/IMPL/Config/ServicesBag.pm @ 411:ee36115f6a34 ref20150831
sync
author | cin |
---|---|
date | Mon, 21 Sep 2015 00:53:10 +0300 |
parents | c6e90e02dd17 |
children |
comparison
equal
deleted
inserted
replaced
410:9335cf010b23 | 411:ee36115f6a34 |
---|---|
4 | 4 |
5 use mro; | 5 use mro; |
6 | 6 |
7 use IMPL::Const qw(:prop); | 7 use IMPL::Const qw(:prop); |
8 use IMPL::declare { | 8 use IMPL::declare { |
9 require => { | |
10 Entry => '-IMPL::Config::ServicesBag::Entry' | |
11 }, | |
9 base => [ | 12 base => [ |
10 'IMPL::Object' => undef | 13 'IMPL::Object' => undef |
11 ], | 14 ], |
12 props => [ | 15 props => [ |
13 _prototype => PROP_RW, | 16 _prototype => PROP_RW, |
55 } | 58 } |
56 | 59 |
57 sub RegisterValue { | 60 sub RegisterValue { |
58 my ( $this, $value, $name, $type ) = @_; | 61 my ( $this, $value, $name, $type ) = @_; |
59 | 62 |
60 my $d = { owner => $this, value => $value, valid => 1 }; | 63 my $d = Entry->new( {owner => $this, value => $value} ); |
61 | 64 |
62 if ($type) { | 65 if ($type) { |
63 my $map = $this->_typeMap; | 66 my $map = $this->_typeMap; |
64 my $isa = mro::get_linear_isa($type); | 67 my $isa = mro::get_linear_isa($type); |
65 $d->{isa} = $isa; | 68 $d->{isa} = $isa; |
75 } | 78 } |
76 | 79 |
77 $map->{$t} = $d; | 80 $map->{$t} = $d; |
78 } | 81 } |
79 | 82 |
80 if ($replaces) { | |
81 | |
82 # invalidate cache | 83 # invalidate cache |
83 $replaces->{owner}->UpdateDescriptor($replaces); | 84 $replaces->Invalidate() if $replaces; |
84 } | 85 |
85 } | 86 } |
86 | 87 |
87 if ($name) { | 88 if ($name) { |
88 my $prev = $this->_nameMap->{$name}; | 89 my $prev = $this->_nameMap->{$name}; |
89 $d->{name} = $name; | 90 $d->{name} = $name; |
90 $this->_nameMap->{$name} = $d; | 91 $this->_nameMap->{$name} = $d; |
91 $prev->{owner}->UpdateDescriptor($prev) if $prev; | 92 $prev->Invalidate() if $prev; |
92 } | 93 } |
93 | 94 |
94 return $d; | 95 return $d; |
95 } | 96 } |
96 | 97 |
97 sub UpdateDescriptor { | 98 sub _UpdateDescriptor { |
98 my ( $this, $d ) = @_; | 99 my ( $this, $d ) = @_; |
99 | 100 |
100 my $d2 = {}; | 101 my $d2 = Entry->new($d); |
101 | |
102 # copy descriptor | |
103 while ( my ( $k, $v ) = each %$d ) { | |
104 $d2->{$k} = $v; | |
105 } | |
106 | 102 |
107 # update named entries | 103 # update named entries |
108 my $name = $d->{name}; | 104 my $name = $d->{name}; |
109 if ( $name and $this->_nameMap->{$name} == $d ) { | 105 if ( $name and $this->_nameMap->{$name} == $d ) { |
110 $this->_nameMap->{$name} = $d2; | 106 $this->_nameMap->{$name} = $d2; |
118 $map->{$t} = $d2; | 114 $map->{$t} = $d2; |
119 } | 115 } |
120 } | 116 } |
121 | 117 |
122 $d->{valid} = 0; | 118 $d->{valid} = 0; |
119 } | |
120 | |
121 package IMPL::Config::ServicesBag::Entry; | |
122 use IMPL::Exception(); | |
123 use IMPL::declare { | |
124 base => [ | |
125 'IMPL::Object::Fields' => undef | |
126 ] | |
127 }; | |
128 | |
129 my @fields = qw(owner type isa valid value); | |
130 use fields @fields; | |
131 | |
132 sub CTOR { | |
133 my SELF $this = shift; | |
134 my $args = shift; | |
135 | |
136 $this->{valid} = 1; | |
137 $this->{owner} = $args{owner} or die IMPL::InvalidArgumentException->new("owner"); | |
138 $this->{value} = $args{value} if exists $args->{value}; | |
139 $this->{isa} = $args{isa} if $args->{isa}; | |
140 } | |
141 | |
142 sub Invalidate { | |
143 my SELF $this = shift; | |
144 | |
145 $this->{owner}->_UpdateDescriptor($this); | |
123 } | 146 } |
124 | 147 |
125 1; | 148 1; |
126 | 149 |
127 __END__ | 150 __END__ |