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__ |
