SectionsController.as

Go to the documentation of this file.
00001 import mx.utils.Delegate;
00002 
00003 import gugga.application.ISectionsController;
00004 import gugga.application.Section;
00005 import gugga.application.SectionsTransition;
00006 import gugga.application.TransitionInfo;
00007 import gugga.collections.HashTable;
00008 import gugga.common.EventDescriptor;
00009 import gugga.components.ISectionLoader;
00010 import gugga.components.SectionAttacher;
00011 import gugga.components.SectionLoader;
00012 import gugga.debug.Assertion;
00013 import gugga.sequence.ExecuteAsyncMethodTask;
00014 import gugga.sequence.FictiveTask;
00015 import gugga.sequence.TaskManager;
00016 import gugga.utils.Listener;
00017 import gugga.utils.Locker;
00018 
00019 [Event("currentSectionPathChanged")]
00020 
00024 class gugga.application.SectionsController extends Section implements ISectionsController
00025 {
00026         private var mSectionsInitializationStartTask : FictiveTask;
00027         private var mSectionsInitializationEndTask : FictiveTask;
00028         private var mSectionsControllerInitializingSequence : TaskManager;
00029         //private var mSubSectionsInitializationSequence : TaskSequence;
00030 
00031         private var mSections : HashTable;
00032 
00033         private var mMouseEventsLocker : Locker;
00034 
00035         private var mLazySectionLoaders : HashTable;
00036         private var mDetachAfterCloseSections : HashTable;
00037 
00038         private var mTransition : SectionsTransition;
00039 
00040         private var mTargetSectionID : String;
00041         
00042         private var mCurrentSection : Section;
00043         public function get CurrentSection() : Section { return mCurrentSection; }
00044         
00045         private var mCurrentSectionID : String;
00046         public function get CurrentSectionID() : String { return mCurrentSectionID; }
00047 
00048         private var mCurrentSectionPath : String;
00049         public function get CurrentSectionPath() : String { return mCurrentSectionPath; }
00050 
00051         private var mIsTransitingSections : Boolean = false;
00052         public function get IsTransitingSections() : Boolean { return mIsTransitingSections; }
00053         public /*protected*/ function set IsTransitingSections(aValue:Boolean) : Void { mIsTransitingSections = aValue; }
00054 
00059         private var mDisableNavigationWhenTransiting : Boolean = false;
00060         public function get DisableNavigationWhenTransiting() : Boolean { return mDisableNavigationWhenTransiting; }
00061         public function set DisableNavigationWhenTransiting(aValue:Boolean) : Void { mDisableNavigationWhenTransiting = aValue; }
00062 
00063         private var mSectionSwfsLoadingPart : Number = 70;
00064         public function get SectionSwfsLoadingPart() : Number { return mSectionSwfsLoadingPart; }
00065         public function set SectionSwfsLoadingPart(aValue:Number) : Void { mSectionSwfsLoadingPart = aValue; }
00066 
00067         function SectionsController()
00068         {
00069                 mSections = new HashTable();
00070                 mMouseEventsLocker = new Locker();
00071                 
00072                 mLazySectionLoaders = new HashTable();
00073                 mDetachAfterCloseSections = new HashTable();
00074         }
00075         
00076         private function initUI() : Void
00077         {
00078                 super.initUI();
00079                 
00080                 createSectionInitializationSequence();
00081         }
00082 
00083         private function getSectionID(aSection:Section) : String
00084         {
00085                 for(var key:String in mSections)
00086                 {
00087                         if(mSections[key] == aSection)
00088                         {
00089                                 return key;
00090                         }
00091                 }
00092                 
00093                 return null;
00094                 //Assertion.warning(aSection + " not found", this, arguments);
00095         }
00096 
00097         public function getCurrentSectionPath() : String
00098         {
00099                 return CurrentSectionPath;
00100         }       
00101         
00102         private function harvestCurrentSectionPath() : Void
00103         {
00104                 var sectionPath : String = CurrentSectionID;
00105 
00106                 if(mCurrentSection instanceof ISectionsController)
00107                 {
00108                         sectionPath += "." + ISectionsController(mCurrentSection).getCurrentSectionPath();
00109                 }
00110                 
00111                 mCurrentSectionPath = sectionPath;
00112                 dispatchEvent({type: "currentSectionPathChanged", target: this});
00113         }
00114         
00115         private function createSectionInitializationSequence() : Void
00116         {
00117                 var initializingSequence : TaskManager = new TaskManager();
00118                 mSectionsInitializationStartTask = new FictiveTask();
00119                 mSectionsInitializationEndTask = new FictiveTask();
00120                 
00121                 initializingSequence.addStartingTasks([mSectionsInitializationStartTask]);
00122                                 
00123                 initializingSequence.addTaskWithPredecessor(mSectionsInitializationEndTask, mSectionsInitializationStartTask);
00124                 initializingSequence.setFinalTask(mSectionsInitializationEndTask);
00125                 
00126                 //sub sections initialization
00127                 //mSubSectionsInitializationSequence = new TaskSequence();
00128                 
00129                 //initializingSequence.addTaskWithPredecessor(mSubSectionsInitializationSequence, mSectionsInitializationStartTask);
00130                 //initializingSequence.addTaskPredecessor(mSectionsInitializationEndTask, mSubSectionsInitializationSequence);
00131                 
00132                 //register
00133                 mSectionsControllerInitializingSequence = initializingSequence;
00134                 registerInitializingTask(initializingSequence);
00135         }
00136                 
00137         public function registerSection(aSectionInstance:Section, aID:String)
00138         {
00139                 Assertion.failIfEmpty(aID, "aID is empty", this, arguments);                    
00140                 Assertion.failIfNotNull(mSections[aID], "mSections[" + aID + "] already exists", this, arguments);      
00141                 Assertion.failIfNull(aSectionInstance, "aSectionInstance is null", this, arguments);                            
00142                                 
00143                 mSections[aID] = aSectionInstance;
00144                 
00145                 if(aSectionInstance instanceof ISectionsController)
00146                 {
00147                         ISectionsController(aSectionInstance).addEventListener(
00148                                 "currentSectionPathChanged", Delegate.create(this, onSubControllerSectionPathChanged));
00149                 }
00150                 
00151                 var initializeSectionTask : ExecuteAsyncMethodTask = ExecuteAsyncMethodTask.createBasic(
00152                         "initialized", aSectionInstance, aSectionInstance.initialize);
00153                         
00154                 mSectionsControllerInitializingSequence.addTaskWithPredecessor(initializeSectionTask, mSectionsInitializationStartTask);
00155                 mSectionsControllerInitializingSequence.addTaskPredecessor(mSectionsInitializationEndTask, initializeSectionTask);
00156         }
00157         
00158         public function registerChildSection(aSectionInstanceName:String, aID:String)
00159         {
00160                 registerSection(this[aSectionInstanceName], aID);
00161                 return this[aSectionInstanceName];
00162         }
00163         
00164         public function registerLazyLoadSection(aSectionLoader:SectionLoader, aSectionSwfPath:String, aID:String, aDetachAfterClose:Boolean)
00165         {
00166                 Assertion.failIfEmpty(aSectionSwfPath, "aSectionSwfPath is empty", this, arguments);                            
00167                 
00168                 aSectionLoader.ContentPath = aSectionSwfPath;
00169                 registerLazySection(aSectionLoader, aID, aDetachAfterClose);
00170         }
00171         
00172         public function registerLazyAttachSection(aSectionAttacher:SectionAttacher, aSectionLinkage:String, aID:String, aDetachAfterClose:Boolean)
00173         {
00174                 Assertion.failIfEmpty(aSectionLinkage, "aSectionLinkage is empty", this, arguments);
00175                 
00176                 aSectionAttacher.SectionLinkage = aSectionLinkage;
00177                 registerLazySection(aSectionAttacher, aID, aDetachAfterClose);
00178         }
00179         
00180         public function registerLazySection(aSectionLoader:ISectionLoader, aID:String, aDetachAfterClose:Boolean)
00181         {
00182                 Assertion.failIfEmpty(aID, "aID is empty", this, arguments);                    
00183                 Assertion.failIfNotNull(mSections[aID], "mSections[" + aID + "] is already exists", this, arguments);   
00184                 
00185                 aSectionLoader.addEventListener("sectionAvailable", Delegate.create(this, onLazySubSectionAvailable));
00186                 
00187                 mLazySectionLoaders[aID] = aSectionLoader;
00188                 mDetachAfterCloseSections[aID] = aDetachAfterClose;
00189         }
00190         
00191         //TODO: can be done in onLazyTargetSectionInitialized()
00192         private function onLazySubSectionAvailable(ev) : Void
00193         {
00194                 var section : Section = ev["section"];
00195                 
00196                 if(section instanceof ISectionsController)
00197                 {
00198                         ISectionsController(section).addEventListener(
00199                                 "currentSectionPathChanged", Delegate.create(this, onSubControllerSectionPathChanged));
00200                 }
00201         }
00202                 
00203         private function isSectionIDRegistered(aSectionID:String) : Boolean
00204         {
00205                 if(mSections.containsKey(aSectionID))
00206                 {
00207                         return true;
00208                 }
00209                 else if(mLazySectionLoaders.containsKey(aSectionID))
00210                 {
00211                         return true;
00212                 }
00213                 else
00214                 {
00215                         return false;
00216                 }
00217         }               
00218                 
00219         private function isLazySection(aSectionID:String) : Boolean
00220         {
00221                 return mLazySectionLoaders.containsKey(aSectionID);
00222         }
00223         
00224         private function isDetachAfterCloseSection(aSectionID:String) : Boolean
00225         {
00226                 if(mDetachAfterCloseSections.containsKey(aSectionID))
00227                 {
00228                         return mDetachAfterCloseSections[aSectionID];
00229                 }
00230                 else
00231                 {
00232                         return false;
00233                 }
00234         }
00235         
00236         private function needLazyLoad(aSectionID:String) : Boolean
00237         {
00238                 if(mSections.containsKey(aSectionID))
00239                 {
00240                         return false;
00241                 }
00242                 else if(mLazySectionLoaders.containsKey(aSectionID))
00243                 {
00244                         return true;
00245                 }
00246                 else
00247                 {
00248                         Assertion.fail("Invalid section ID", this, arguments);
00249                 }
00250         }
00251         
00252         //TODO: Can be ranamed to generateTransitionInfo()
00253         private function getTransitionInfo(aSectionID:String, aSectionPathRest:String) : TransitionInfo
00254         {
00255                 var transitionInfo : TransitionInfo = new TransitionInfo();
00256                 
00257                 transitionInfo.SectionsController = this;
00258                 
00259                 transitionInfo.CurrentSection = mCurrentSection;
00260                 transitionInfo.TargetSection = mSections[aSectionID];
00261                 
00262                 if(isLazySection(aSectionID))
00263                 {
00264                         transitionInfo.TargetSectionLoader = mLazySectionLoaders[aSectionID];
00265                         transitionInfo.DoLoadTargetSection = needLazyLoad(aSectionID);
00266                 }
00267                 
00268                 transitionInfo.DetachCurrentSectionAfterClose = isDetachAfterCloseSection(aSectionID);
00269                 transitionInfo.SectionPathRest = aSectionPathRest;
00270                 
00271                 return transitionInfo; 
00272         }       
00273         
00274         //TODO: Can be ranamed to generateTransition()
00275         private function getTransition(aSectionID:String, aSectionPathRest:String) : SectionsTransition
00276         {
00277                 var transitionInfo : TransitionInfo = getTransitionInfo(aSectionID, aSectionPathRest);
00278         
00279                 var transition : SectionsTransition = new SectionsTransition(transitionInfo);   
00280                 return transition;
00281         }
00282         
00283         private function startTransition(aTransition:SectionsTransition) : Void
00284         {
00285                 //TODO: Listener should be destroyed after transition is destroyed
00286                 Listener.createSingleTimeListener(
00287                         new EventDescriptor(aTransition, "lazyTargetSectionInitialized"), 
00288                         Delegate.create(this, onLazyTargetSectionInitialized)
00289                 );
00290                 
00291                 Listener.createSingleTimeListener(
00292                         new EventDescriptor(aTransition, "sectionsSwapped"), 
00293                         Delegate.create(this, onSectionsSwapped)
00294                 );
00295                 
00296                 Listener.createSingleTimeListener(
00297                         new EventDescriptor(aTransition, "currentSectionDestroyed"), 
00298                         Delegate.create(this, onCurrentSectionDestroyed)
00299                 );
00300                 
00301                 Listener.createSingleTimeListener(
00302                         new EventDescriptor(aTransition, "completed"), 
00303                         Delegate.create(this, onTransitionCompleted)
00304                 );
00305                 
00306                 //TODO: Listener should be destroyed after transition is destroyed
00307                 Listener.createSingleTimeListener(
00308                         new EventDescriptor(aTransition, "interrupted"), 
00309                         Delegate.create(this, onTransitionInterrupted)
00310                 );
00311                 
00312                 Listener.createSingleTimeListener(
00313                         new EventDescriptor(aTransition, "disposed"), 
00314                         Delegate.create(this, onTransitionDisposed)
00315                 );
00316                 
00317                 aTransition.start();
00318         }
00319         
00320         public function openSection(aSectionPath:String) : SectionsTransition
00321         {
00322                 Assertion.failIfEmpty(aSectionPath, "Argument aPath is empty", this, arguments);
00323                 Assertion.failIfNotNull(mTransition, "Old transition is still alive", this, arguments);
00324                 Assertion.failIfTrue(mTransition.isRunning(), "Old transition is still running", this, arguments);
00325         
00326                 var pathArray:Array = aSectionPath.split(".");
00327                 var sectionID:String = pathArray[0];
00328                 var sectionPathRest:String; 
00329                 
00330                 mTargetSectionID = sectionID;
00331                 
00332                 Assertion.failIfReturnsFalse(
00333                         this, isSectionIDRegistered, [sectionID], 
00334                         "Section ID '" + sectionID + "' is not registered", this, arguments);
00335                 
00336                 if(pathArray.length > 1)
00337                 {
00338                         var sectionPathRestArray:Array = pathArray.slice(1);
00339                         sectionPathRest = sectionPathRestArray.join(".");
00340                 }
00341         
00342                 if(mCurrentSectionID == sectionID)
00343                 {
00344                         var currentSection : Section = Section(mSections[mCurrentSectionID]);
00345                         
00346                         if(currentSection)
00347                         {
00348                                 if((currentSection instanceof ISectionsController) && sectionPathRest)
00349                                 {
00350                                         var openChildSectionsTransition : SectionsTransition = 
00351                                                 ISectionsController(currentSection).openSection(sectionPathRest);
00352                                         
00353                                         return openChildSectionsTransition;
00354                                 }                       
00355                                 else
00356                                 {
00357                                         return null;
00358                                 }
00359                         }
00360                 }
00361         
00362                 //-------------- actual section opening
00363                 
00364                 mIsTransitingSections = true;
00365                 
00366                 /*
00367                 if(mDisableNavigationWhenTransiting)
00368                 {
00369                         setNavigationLock("DisableNavigationWhenTransitingLock_" + this);
00370                 }
00371                  */
00372                 
00373                 mTransition = getTransition(sectionID, sectionPathRest);
00374                 
00375                 if(mTransition)
00376                 {
00377                         startTransition(mTransition);
00378                 }
00379                 
00380                 return mTransition;
00381         }
00382         
00383         private function isSectionClosing(aSectionPath:String) : Boolean
00384         {
00385                 var pathArray:Array = aSectionPath.split(".");
00386                 var sectionID:String = pathArray[0];
00387                 var section:Section = mSections[sectionID];
00388                 
00389                 if(section instanceof SectionsController)
00390                 {
00391                         var sectionPathRest:String = ""; 
00392                         
00393                         if(pathArray.length > 1)
00394                         {
00395                                 var sectionPathRestArray:Array = pathArray.slice(1);
00396                                 sectionPathRest = sectionPathRestArray.join(".");
00397                         }
00398                         
00399                         return SectionsController(section).isSectionClosing(sectionPathRest);
00400                 }
00401                 else
00402                 {
00403                         return section.IsClosing;
00404                 }
00405         }
00406         
00407         private function onLazyTargetSectionInitialized(ev) : Void 
00408         {
00409                 var section : Section = ev.section;
00410                 mSections[mTargetSectionID] = section;
00411         }
00412         
00413         private function onCurrentSectionDestroyed(ev) : Void
00414         {
00415                 var sectionID : String = getSectionID(ev.section);
00416                 if(mLazySectionLoaders.containsKey(sectionID))
00417                 {
00418                         var sectionLoader : ISectionLoader = mLazySectionLoaders[sectionID];
00419                         sectionLoader.unloadData();
00420                 }
00421                 
00422                 mSections[sectionID] = null;
00423         }
00424         
00425         private function onSectionsSwapped(ev) : Void 
00426         {
00427                 mCurrentSectionID = mTargetSectionID;
00428                 mCurrentSection = mSections[mCurrentSectionID];
00429                 
00430                 harvestCurrentSectionPath();
00431         }
00432         
00433         private function onSubControllerSectionPathChanged(ev) : Void 
00434         {
00435                 harvestCurrentSectionPath();
00436         }
00437         
00438         private function onTransitionCompleted(ev) : Void 
00439         {
00440                 mTargetSectionID = null;
00441                 mIsTransitingSections = false;
00442 
00443                 //clearNavigationLock("DisableNavigationWhenTransitingLock_" + this);
00444         }
00445         
00446         private function onTransitionInterrupted(ev) : Void 
00447         {
00448                 mTargetSectionID = null;
00449                 mIsTransitingSections = false;
00450                 
00451                 mCurrentSection = ev.newCurrentSection;
00452                 mCurrentSectionID = getSectionID(mCurrentSection);
00453 
00454                 //clearNavigationLock("DisableNavigationWhenTransitingLock_" + this);
00455         }
00456         
00457         private function onTransitionDisposed(ev) : Void 
00458         {
00459                 delete mTransition;
00460         }
00461         
00462         public function enableBoundingBoxMouseEvents() : Void
00463         {
00464                 mMouseEventsLocker.clearAllLocks();
00465                 super.enableBoundingBoxMouseEvents();
00466         }
00467         
00468         public function setMouseEventsLock(aLockID:String) : String
00469         {
00470                 disableBoundingBoxMouseEvents();
00471                 return mMouseEventsLocker.setLock(aLockID);
00472         }
00473         
00474         public function clearMouseEventsLock(aLockID:String) : Void
00475         {
00476                 mMouseEventsLocker.clearLock(aLockID);
00477                 
00478                 if(!mMouseEventsLocker.isLocked())
00479                 {
00480                         super.enableBoundingBoxMouseEvents();
00481                 }
00482         }       
00483 }

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