SectionsTransition.as

Go to the documentation of this file.
00001 import gugga.events.EventDispatcher;
00002 import mx.utils.Delegate;
00003 
00004 import gugga.application.ISectionsController;
00005 import gugga.application.Section;
00006 import gugga.application.TransitionInfo;
00007 import gugga.common.EventDescriptor;
00008 import gugga.common.IProgressiveTask;
00009 import gugga.common.ITask;
00010 import gugga.components.ISectionLoader;
00011 import gugga.components.SectionAttacher;
00012 import gugga.components.SectionLoader;
00013 import gugga.sequence.FictiveTask;
00014 import gugga.sequence.PreconditionsTask;
00015 import gugga.sequence.ProgressMonitor;
00016 import gugga.utils.DoLaterUtil;
00017 import gugga.utils.Listener;
00018 
00019 [Event("lazyTargetSectionAvailable")]
00020 [Event("lazyTargetSectionUIInitialized")]
00021 [Event("lazyTargetSectionInitialized")]
00022 
00023 [Event("targetSectionActivate")]
00024 [Event("targetSectionOpen")]
00025 
00026 [Event("currentSectionDestroyed")]
00027 [Event("currentSectionClose")]
00028 [Event("currentSectionDestroy")]
00029 
00030 [Event("setNavigationLock")]
00031 [Event("clearNavigationLock")]
00032 
00033 [Event("sectionsSwapped")]
00034 
00035 [Event("disposed")]
00036 
00040 class gugga.application.SectionsTransition 
00041         extends EventDispatcher 
00042         implements ITask 
00043 {
00044         private var mOpenTargetSectionPreconditions : PreconditionsTask;
00045         private var mDisposePreconditions : PreconditionsTask;
00046         
00047         private var mDoLoadTargetSection : Boolean;
00048         private var mDetachCurrentSectionAfterClose : Boolean;
00049         private var mSectionPathRest : String;
00050         
00051         private var mChildSectionsTransition : SectionsTransition;
00052         
00053         private var mIsRunning : Boolean = false;
00054         private var mIsInterrupting : Boolean = false;
00055         
00056         private var mTargetSectionInitializedTask : FictiveTask;
00057                 
00058         private var mPreOpenProgressMonitor : ProgressMonitor;
00059         public function get PreOpenProgressMonitor() : ProgressMonitor { return mPreOpenProgressMonitor; }
00060         
00061         private var mSectionsController : ISectionsController;
00062         public function get SectionsController() : ISectionsController { return mSectionsController; }
00063         
00064         private var mCurrentSection : Section;
00065         public function get CurrentSection() : Section { return mCurrentSection; }
00066         
00067         private var mTargetSection : Section;
00068         public function get TargetSection() : Section { return mTargetSection; }
00069         
00070         private var mTargetSectionLoader : ISectionLoader;
00071         public function get TargetSectionLoader() : ISectionLoader { return mTargetSectionLoader; }
00072         
00073         public function SectionsTransition(aTransitionInfo:TransitionInfo) 
00074         {
00075                 mSectionsController = aTransitionInfo.SectionsController;
00076                 mCurrentSection = aTransitionInfo.CurrentSection;
00077                 mDetachCurrentSectionAfterClose = aTransitionInfo.DetachCurrentSectionAfterClose;
00078                 mTargetSection = aTransitionInfo.TargetSection;
00079                 mTargetSectionLoader = aTransitionInfo.TargetSectionLoader;
00080                 mDoLoadTargetSection = aTransitionInfo.DoLoadTargetSection;
00081                 mSectionPathRest = aTransitionInfo.SectionPathRest;
00082                 
00083                 mTargetSectionInitializedTask = new FictiveTask();
00084                 
00085                 mPreOpenProgressMonitor = new ProgressMonitor();
00086                 mOpenTargetSectionPreconditions = new PreconditionsTask();
00087                 
00088                 mDisposePreconditions = new PreconditionsTask();
00089                 mDisposePreconditions.add(new EventDescriptor(this, "readyToDispose"));
00090                 
00091                 Listener.createSingleTimeListener(
00092                         new EventDescriptor(mDisposePreconditions, "completed"),
00093                         Delegate.create(this, onDisposePreconditionsMet)
00094                 );
00095                 
00096                 mOpenTargetSectionPreconditions.add(new EventDescriptor(mPreOpenProgressMonitor, "completed"));
00097                 
00098                 Listener.createSingleTimeListener(
00099                         new EventDescriptor(mOpenTargetSectionPreconditions, "completed"),
00100                         Delegate.create(this, onOpenTargetSectionPreconditionsMet)
00101                 );
00102         }
00103          
00104         public function start() : Void 
00105         {
00106                 mIsRunning = true;
00107                 mIsInterrupting = false;
00108                 
00109                 closeCurrentSectionIfNeeded();
00110         
00111                 if(mDoLoadTargetSection)
00112                 {
00113                         openLazySection();
00114                 }
00115                 else
00116                 {
00117                         openInitializedSection();
00118                 }
00119         }
00120         
00121         private function closeCurrentSectionIfNeeded() : Void
00122         {
00123                 if(mCurrentSection && !mCurrentSection.IsClosed)
00124                 {
00125                         closeCurrentSection();
00126                 }
00127         }       
00128         
00129         private function closeCurrentSection() : Void
00130         {
00131                 mOpenTargetSectionPreconditions.add(new EventDescriptor(mCurrentSection, "closed"));
00132                         
00133                 Listener.createSingleTimeListener(
00134                         new EventDescriptor(mCurrentSection, "closed"), 
00135                         Delegate.create(this, onCurrentSectionClosed)
00136                 );
00137                 
00138                 if(!mCurrentSection.IsClosing)
00139                 {
00140                         triggerCurrentSectionClose();
00141                 }
00142         }
00143         
00144         public function isRunning() : Boolean 
00145         {
00146                 return mIsRunning || mChildSectionsTransition.isRunning();
00147         }
00148         
00149         public function isInterrupting() : Boolean 
00150         {
00151                 return mIsInterrupting || mChildSectionsTransition.isInterrupting();
00152         }
00153 
00154         public function canInterrupt() : Boolean
00155         {
00156                 return true && (!mChildSectionsTransition || mChildSectionsTransition.canInterrupt());
00157         }
00158 
00159         public function isImmediatelyInterruptable() : Boolean 
00160         {
00161                 var result =  
00162                 (!mChildSectionsTransition || (mChildSectionsTransition && mChildSectionsTransition.isImmediatelyInterruptable())) &&
00163                 //(!mCurrentSection.IsClosing || (mCurrentSection.IsClosing && mCurrentSection.isClosingImmediatelyInterruptable())) &&
00164                 (!mTargetSection.IsInitializing || (mTargetSection.IsInitializing && mTargetSection.isInitializationImmediatelyInterruptable())) &&
00165                 (!mTargetSection.IsActivating || (mTargetSection.IsActivating && mTargetSection.isActivationImmediatelyInterruptable())) &&
00166                 (!mTargetSection.IsOpening || (mTargetSection.IsOpening && mTargetSection.isOpeningImmediatelyInterruptable()));
00167                 
00168                 return result;
00169         }
00170 
00171         public function interrupt() : Void 
00172         {
00173                 mIsInterrupting = true;
00174                 
00175                 //just in case. can be removed. defence is put in trigger...() methods
00176                 mOpenTargetSectionPreconditions.interrupt();
00177                 
00178                 var interuptedPreconditions : PreconditionsTask = new PreconditionsTask();
00179                 var newCurrentSection : Section = getNewCurrentSectionAfterInterruption();
00180                 
00181                 /*
00182                 if(mCurrentSection.IsClosing)
00183                 {
00184                         DebugUtils.traceContext("--------- interruptClose", this, arguments);
00185                         
00186                         interuptedPreconditions.add(new EventDescriptor(mCurrentSection, "closeInterrupted"));
00187                         mCurrentSection.interruptClose();
00188                 }
00189                  * 
00190                  */
00191                                 
00192                 if(mTargetSection && mTargetSection.IsInitializing)
00193                 {
00194                         interuptedPreconditions.add(new EventDescriptor(mCurrentSection, "initializationInterrupted"));
00195                         mTargetSection.interruptInitialization();
00196                 }
00197                 
00198                 if(mTargetSection && mTargetSection.IsActivating)
00199                 {
00200                         interuptedPreconditions.add(new EventDescriptor(mTargetSection, "activationInterrupted"));
00201                         mTargetSection.interruptActivation();
00202                 }
00203                 
00204                 if(mTargetSection && mTargetSection.IsOpening)
00205                 {
00206                         interuptedPreconditions.add(new EventDescriptor(mTargetSection, "openInterrupted"));
00207                         mTargetSection.interruptOpen();
00208                 }
00209                 
00210                 if(mChildSectionsTransition && mChildSectionsTransition.isRunning())
00211                 {
00212                         interuptedPreconditions.add(new EventDescriptor(mChildSectionsTransition, "interrupted"));
00213                         mChildSectionsTransition.interrupt(); 
00214                 }
00215                 
00216                 Listener.createSingleTimeMergingListener(
00217                         new EventDescriptor(interuptedPreconditions, "completed"), 
00218                         Delegate.create(this, onInterrupted),
00219                         {newCurrentSection: newCurrentSection}
00220                 );
00221                 
00222                 interuptedPreconditions.start();
00223                 
00224                 if(!mDisposePreconditions.isRunning())
00225                 {
00226                         mDisposePreconditions.start();
00227                 }
00228         }
00229         
00230         private function getNewCurrentSectionAfterInterruption() : Section
00231         {
00232                 var result : Section = mCurrentSection;
00233                 
00234                 if(mTargetSection.IsOpening)
00235                 {
00236                         result = mTargetSection;
00237                 }
00238                 
00239                 return result;
00240         }
00241         
00242         private function onInterrupted(ev) : Void 
00243         {
00244                 mIsInterrupting = false;
00245                 mIsRunning = false;
00246                 
00247                 dispatchEvent({type: "interrupted", target: this, newCurrentSection: ev.newCurrentSection});
00248                 dispatchEvent({type: "readyToDispose", target: this});
00249         }
00250         
00251         private function triggerTargetSectionActivate() : Void
00252         {
00253                 if(mIsRunning && !mIsInterrupting)
00254                 {
00255                         dispatchEvent({type: "targetSectionActivate", target: this}); 
00256                         mTargetSection.activate();
00257                 }
00258         }
00259 
00260         private function triggerTargetSectionOpen() : Void
00261         {
00262                 dispatchEvent({type: "sectionsSwapped", target: this});
00263                 
00264                 if(mIsRunning && !mIsInterrupting)
00265                 {
00266                         dispatchEvent({type: "targetSectionOpen", target: this});
00267                         mTargetSection.open();
00268                 }
00269         }
00270 
00271         private function triggerCurrentSectionClose() : Void
00272         {
00273                 //TODO: this check should be revised, maybe removed
00274                 if(mIsRunning && !mIsInterrupting)
00275                 {
00276                         dispatchEvent({type: "currentSectionClose", target: this});
00277                         mCurrentSection.close();
00278                 }
00279         }
00280 
00281         private function triggerCurrentSectionDestroy() : Void
00282         {
00283                 //just trigger without check, because if the section is closed 
00284                 //and we should deatach it, it must be done regardless of the 
00285                 //transition's state
00286                 dispatchEvent({type: "currentSectionDestroy", target: this});
00287                 mCurrentSection.destroy();
00288         }
00289         
00290         private function triggerSectionsControllerOpenSection(aSectionsController : ISectionsController, 
00291                 aSectionPath : String) : SectionsTransition
00292         {
00293                 //TODO: aSectionsController should be informed that it should prepare to open a new section
00294                 //before it is initialized
00295                 mChildSectionsTransition = aSectionsController.openSection(aSectionPath);
00296                 return mChildSectionsTransition;
00297         }       
00298         
00299         private function openLazySection() : Void
00300         {
00301                 Listener.createSingleTimeListener(
00302                         new EventDescriptor(mTargetSectionLoader, "sectionAvailable"), 
00303                         Delegate.create(this, onLazyTargetSectionAvailable)
00304                 );
00305 
00306                 Listener.createSingleTimeListener(
00307                         new EventDescriptor(mTargetSectionLoader, "sectionUIInitialized"), 
00308                         Delegate.create(this, onLazyTargetSectionUIInitialized)
00309                 );
00310 
00311                 Listener.createSingleTimeListener(
00312                         new EventDescriptor(mTargetSectionLoader, "sectionInitialized"), 
00313                         Delegate.create(this, onLazyTargetSectionInitialized)
00314                 );
00315                 
00316                 if(mTargetSectionLoader instanceof SectionLoader)
00317                 {
00318                         openLazyLoadSection();
00319                 }
00320                 else if(mTargetSectionLoader instanceof SectionAttacher)
00321                 {
00322                         openLazyAttachSection();
00323                 }
00324         }
00325         
00326         private function openLazyLoadSection() : Void
00327         {
00328                 mPreOpenProgressMonitor.addFixedPartItem(mTargetSectionInitializedTask, 0);
00329                 
00330                 var targetSectionLoader : SectionLoader = SectionLoader(mTargetSectionLoader);
00331                 mPreOpenProgressMonitor.addItem(targetSectionLoader);
00332                 
00333                 mTargetSectionLoader.start();
00334         }
00335 
00336         private function openLazyAttachSection() : Void
00337         {
00338                 mPreOpenProgressMonitor.addFixedPartItem(mTargetSectionInitializedTask, 0);
00339                 
00340                 mTargetSectionLoader.start();
00341         }
00342         
00343         private function openInitializedSection() : Void
00344         {
00345                 getAndMonitorTargetSectionPreOpenProgress();
00346                 triggerTargetSectionActivate();
00347                 
00348                 openAndMonitorTargetSubSection();
00349                 
00350                 startMonitoringPreOpenProgress();
00351                 startMonitoringOpenTargetSectionPreconditions();
00352         }
00353         
00354         private function onLazyTargetSectionAvailable(ev) : Void 
00355         {
00356                 mTargetSection = ev.section;
00357                 dispatchEvent({type: "lazyTargetSectionAvailable", target: this, section: ev.section});
00358         }
00359 
00360         private function onLazyTargetSectionUIInitialized(ev) : Void 
00361         {
00362                 dispatchEvent({type: "lazyTargetSectionUIInitialized", target: this, section: ev.section});
00363                 
00364                 getAndMonitorTargetSectionPreOpenProgress();
00365                 startMonitoringPreOpenProgress();
00366         }
00367 
00368         private function onLazyTargetSectionInitialized(ev) : Void 
00369         {
00370                 dispatchEvent({type: "lazyTargetSectionInitialized", target: this, section: ev.section});
00371                 triggerTargetSectionActivate();
00372 
00373                 openAndMonitorTargetSubSection();
00374                 startMonitoringOpenTargetSectionPreconditions();
00375                 
00376                 mTargetSectionInitializedTask.start();
00377         }
00378         
00379         private function startMonitoringOpenTargetSectionPreconditions() : Void
00380         {
00381                 mOpenTargetSectionPreconditions.start();
00382         }
00383 
00384         private function startMonitoringPreOpenProgress() : Void
00385         {
00386                 mPreOpenProgressMonitor.start();
00387         }
00388 
00389         private function getAndMonitorTargetSectionPreOpenProgress() : Void
00390         {
00391                 var sectionPreOpenProgressMonitoringTask : IProgressiveTask = mTargetSection.getPreOpenProgressMonitoringTask();
00392                 
00393                 if(sectionPreOpenProgressMonitoringTask)
00394                 {       
00395                         monitorTargetSectionPreOpenProgress(sectionPreOpenProgressMonitoringTask);
00396                 }
00397         }
00398         
00399         private function monitorTargetSectionPreOpenProgress(aSectionPreOpenProgressMonitoringTask : IProgressiveTask) : Void
00400         {
00401                 mPreOpenProgressMonitor.addItem(aSectionPreOpenProgressMonitoringTask);
00402         }
00403         
00404         private function openAndMonitorTargetSubSection() : Void
00405         {               
00406                 if((mTargetSection instanceof ISectionsController) && (mSectionPathRest != "" && mSectionPathRest != null && mSectionPathRest != undefined))
00407                 {
00408                         var childSectionsTransition : SectionsTransition = 
00409                                 triggerSectionsControllerOpenSection(ISectionsController(mTargetSection), mSectionPathRest);
00410                         
00411                         if(childSectionsTransition)
00412                         {
00413                                 monitorSubTransition(childSectionsTransition);
00414                                 mDisposePreconditions.add(new EventDescriptor(childSectionsTransition, "disposed"));
00415                         }
00416                 }       
00417                 
00418                 mDisposePreconditions.start();
00419         }
00420 
00421         private function monitorSubTransition(aSubTransition:SectionsTransition) : Void
00422         {       
00423                 monitorSubTransitionPreOpenProgress(aSubTransition.PreOpenProgressMonitor);
00424         }
00425         
00426         private function monitorSubTransitionPreOpenProgress(aChildSectionsPreOpenMonitor:IProgressiveTask) : Void
00427         {               
00428                 mPreOpenProgressMonitor.addItem(aChildSectionsPreOpenMonitor);
00429         }
00430         
00431         public function addOpenTargetSectionPrecondition(aEventDescriptor:EventDescriptor) : Void
00432         {
00433                 mOpenTargetSectionPreconditions.add(aEventDescriptor);
00434         }
00435         
00436         private function onOpenTargetSectionPreconditionsMet(ev) : Void
00437         {
00438                 Listener.createSingleTimeListener(
00439                         new EventDescriptor(mTargetSection, "opened"), 
00440                         Delegate.create(this, onTargetSectionOpened)
00441                 );
00442                 
00443                 triggerTargetSectionOpen();
00444         }
00445         
00446         private function onCurrentSectionClosed(ev) : Void
00447         {
00448                 if(mDetachCurrentSectionAfterClose)
00449                 {
00450                         Listener.createSingleTimeListener(
00451                                 new EventDescriptor(mCurrentSection, "destroyed"),
00452                                 Delegate.create(this, onCurrentSectionDestroyed)
00453                         );
00454                         
00455                         mDisposePreconditions.add(
00456                                 new EventDescriptor(this, "currentSectionDestroyed"));
00457                 
00458                         //TODO: revise. Why should we do it later
00459                         DoLaterUtil.doLater(this, triggerCurrentSectionDestroy, null, 1);
00460                 }
00461         }
00462         
00463         private function onCurrentSectionDestroyed(ev) : Void
00464         {
00465                 dispatchEvent({type: "currentSectionDestroyed", target: this, section : mCurrentSection});
00466         }
00467         
00468         private function onTargetSectionOpened(ev) : Void
00469         {
00470                 completed();
00471         }
00472                 
00473         private function completed() : Void
00474         {
00475                 mIsRunning = false;
00476                 mIsInterrupting = false;
00477                 
00478                 dispatchEvent({type: "completed", target: this});
00479         
00480                 //dispose
00481                 dispatchEvent({type: "readyToDispose", target: this});
00482         }
00483 
00484         private function onDisposePreconditionsMet() : Void 
00485         {
00486                 //finish current frame's code and dispose
00487                 DoLaterUtil.doLater(this, dispose, null, 1);
00488         }
00489         
00490         private function dispose() : Void
00491         {
00492                 dispatchEvent({type: "disposed", target: this});
00493                 removeAllEventListeners();
00494         }
00495 }

Generated on Fri May 11 17:12:44 2007 for GuggaFramework by  doxygen 1.5.2