changeset 305:b5d5793f348e

TTView refactoring, still experiencing memory leaks
author sergey
date Wed, 17 Apr 2013 18:00:19 +0400
parents 2ff513227cb4
children d4caf951260d
files Lib/IMPL/Web/View/TTDocument.pm Lib/IMPL/Web/View/TTFactory.pm Lib/IMPL/Web/View/TTRegistry.pm
diffstat 3 files changed, 52 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- 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) {
--- 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);
     }});
 }
 
--- 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<IMPL::Web::View::Registry> - реестр шаблонов документа.
+
+=head1 DESCRIPTION
+
+Используется для реализации функции C<require> внутри шаблонов.
+
+
+
+=cut