# HG changeset patch # User sergey # Date 1366207219 -14400 # Node ID b5d5793f348e7692d4ab11091f0431a23d91400b # Parent 2ff513227cb42e32dad820ce7b61321ee11da9d8 TTView refactoring, still experiencing memory leaks diff -r 2ff513227cb4 -r b5d5793f348e Lib/IMPL/Web/View/TTDocument.pm --- a/Lib/IMPL/Web/View/TTDocument.pm Mon Apr 15 07:44:50 2013 +0400 +++ b/Lib/IMPL/Web/View/TTDocument.pm Wed Apr 17 18:00:19 2013 +0400 @@ -9,6 +9,7 @@ use IMPL::declare { require => { + TTRegistry => 'IMPL::Web::View::TTRegistry', TTFactory => 'IMPL::Web::View::TTFactory', TTControl => 'IMPL::Web::View::TTControl', Loader => 'IMPL::Code::Loader' @@ -41,54 +42,16 @@ my ($this,$args) = @_; $args ||= {}; - - my %controls; - my $require; - my $documentContext; - my $self = $this; + $this->context->localise(); # localise stash + my $documentContext = _clone_context( $this->context ); # create a new context - $require = sub { - my $control = shift; - - unless($self) { - carp("Cant load control $control outside the document rendering process"); - return; - } - - if (my $factory = $controls{$control}) { - return $factory; - } else { - my $path = $control; - - if ( my $template = $self->loader->template($path) ) { - - $documentContext->localise(); - my $ctx = _clone_context($documentContext); - $documentContext->delocalise(); - - $factory = new IMPL::Web::View::TTFactory( - $template, - $ctx, - join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) ), - $require - ); - - $controls{$control} = $factory; - - return $factory; - - } else { - die new IMPL::KeyNotFoundException($control); - } - } - }; - - $this->context->localise(); - $documentContext = _clone_context( $this->context ); - - $this->context->stash->set(require => $require); - $this->context->stash->set(document => sub { $self }); + my $registry = TTRegistry->new($this->loader, $documentContext); + + $this->context->stash->update({ + require => sub { $registry->Require(shift) }, + document => $this + }); my $text = eval { @@ -122,10 +85,8 @@ my $e = $@; - undef $require; - undef $documentContext; - undef %controls; - undef $self; + $registry->Dispose(); + undef $registry; $this->context->delocalise(); if ($e) { diff -r 2ff513227cb4 -r b5d5793f348e Lib/IMPL/Web/View/TTFactory.pm --- a/Lib/IMPL/Web/View/TTFactory.pm Mon Apr 15 07:44:50 2013 +0400 +++ b/Lib/IMPL/Web/View/TTFactory.pm Wed Apr 17 18:00:19 2013 +0400 @@ -27,14 +27,14 @@ instances => PROP_RW, baseLocation => PROP_RW, base => PROP_RW, - require => PROP_RO, + registry => PROP_RO, blocks => PROP_RO, initialized => PROP_RO ] }; sub CTOR { - my ($this,$template,$context,$baseLocation,$require) = @_; + my ($this,$template,$context,$path,$registry) = @_; die ArgException->new("A template is required") unless $template; @@ -42,17 +42,18 @@ if $this->factory and not ref $this->factory; $context ||= new Template::Context(); + my $baseLocation = join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) ); $this->template($template); $this->context($context); $this->baseLocation($baseLocation); $this->instances(0); - $this->require($require); + $this->registry($registry); if (my $baseTplName = $template->extends) { $baseTplName =~ s{^\./}{$baseLocation/}; - my $base = &$require($baseTplName) + my $base = $registry->Require($baseTplName) or die OpException->new("The specified base template isn't found"); $this->base($base); @@ -99,7 +100,7 @@ my ($module) = @_; $module =~ s/^\.\//$baseLocation\//; - return $require->($module); + return $registry->Require($module); }}); } diff -r 2ff513227cb4 -r b5d5793f348e Lib/IMPL/Web/View/TTRegistry.pm --- a/Lib/IMPL/Web/View/TTRegistry.pm Mon Apr 15 07:44:50 2013 +0400 +++ b/Lib/IMPL/Web/View/TTRegistry.pm Wed Apr 17 18:00:19 2013 +0400 @@ -1,5 +1,6 @@ package IMPL::Web::View::TTRegistry; use strict; +use mro; use IMPL::Const qw(:prop); use IMPL::declare { @@ -7,7 +8,8 @@ TTFactory => 'IMPL::Web::View::TTFactory' }, base => [ - 'IMPL::Object' => undef + 'IMPL::Object' => undef, + 'IMPL::Object::Disposable' => undef ], props => [ loader => PROP_RW, @@ -16,6 +18,14 @@ ] }; +sub CTOR { + my ($this,$loader,$context) = @_; + + $this->loader($loader); + $this->context($context); + $this->_cache({}); +} + sub Require { my ($this,$name) = @_; @@ -37,6 +47,30 @@ } } +sub Dispose { + my ($this) = @_; + + $this->_cache(undef); + $this->context(undef); + $this->loader(undef); + + $this->next::method(); +} + 1; __END__ + +=pod + +=head1 NAME + +C - реестр шаблонов документа. + +=head1 DESCRIPTION + +Используется для реализации функции C внутри шаблонов. + + + +=cut