view lib/IMPL/Config/Bag.pm @ 413:af8d359ee4cc ref20150831

working on di container
author cin
date Thu, 24 Sep 2015 12:19:30 +0300
parents 30e8c6a74937
children ec6f2d389d1e
line wrap: on
line source

package IMPL::Config::Bag;
use strict;

use IMPL::declare {
	base => [
		'IMPL::Object' => undef
	],
	props => [
	   parent => '*r',
	   _cache => '*rw',
	   _entries => '*rw'
	]
};

sub CTOR {
	my ($this, $p) = @_;
	
	$this->{$parent} = $p;
	$this->{$_cache} = {};
	$this->{$_entries} = [];
}

sub Resolve {
	my ($this,$role) = @_;
	
	my $d = $this->GetDescriptor();
}

sub GetDescriptor {
	my ($this, $role) = @_;
	
	my $d = $this->{$_cache}{$role};
	return $d if $d and $d->{valid};
	
	my @entries = @{$this->{$_entries}};
	
	if(my $t = $this->{$parent} && $this->{$parent}->GetDescriptor($role)) {
		push @entries, $t;
	}
	
	my $level;
	foreach my $entry (@entries) {
		my $t = $entry->{isa}{$role};
		next unless defined $t;
		if (defined($level) && $level > $t) {
			$d = $entry;
			$level = $t;
		}  
	}
	
	if ($d and $d->{valid}) {
		$this->{$_cache}{$role} = $d;
		return $d;
	} else {
		return;
	} 
}

sub ResolveAll {
	my ($this, $role) = @_;
	
	my $result = $this->{$parent} ? $this->{$parent}->ResolveAll() : [];
	
	push @$result, map $_->{value}, grep $_->{isa}{$role}, @{$this->{$_entries}};
	
	return $result;
}

sub Register {
	my ($this, $role, $isa, $value) = @_;
}

sub _UpdateDescriptor {
	
}

package IMPL::Config::Bag::Entry;
use IMPL::Exception();
use IMPL::declare {
    base => [
       'IMPL::Object::Fields' => undef
    ]
};

my @fields = qw(owner type isa valid value index); 
use fields @fields;

sub CTOR {
    my SELF $this = shift;
    my $args = shift;
    
    $this->{valid} = 1;
    $this->{owner} = $args->{owner} or die IMPL::InvalidArgumentException->new("owner");
    $this->{value} = $args->{value} if exists $args->{value};
    $this->{isa} = $args->{isa} if $args->{isa};
}

sub Invalidate {
    my SELF $this = shift;
    
    $this->{owner}->_UpdateDescriptor($this);
}

1;