/***************************************************** * * Copyright 2009 Adobe Systems Incorporated. All Rights Reserved. * ***************************************************** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * * The Initial Developer of the Original Code is Adobe Systems Incorporated. * Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems * Incorporated. All Rights Reserved. * *****************************************************/ package org.osmf.media { import org.osmf.events.LoadEvent; import org.osmf.traits.LoadState; import org.osmf.traits.LoadTrait; import org.osmf.traits.LoaderBase; import org.osmf.traits.MediaTraitType; /** * LoadableElementBase is the base class for media elements that * have a LoadTrait. It manages the registration of event listeners, * and provides protected hook methods to simplify the load workflow * for subclasses. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public class LoadableElementBase extends MediaElement { /** * Constructor. * * @param resource The MediaResourceBase that represents the piece of * media to load into this media element. * @param loader Loader used to load the media. If null, then this class * is responsible for selecting/generating the appropriate loader. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ public function LoadableElementBase(resource:MediaResourceBase=null, loader:LoaderBase=null) { super(); _loader = loader; this.resource = resource; } /** * @private */ override public function set resource(value:MediaResourceBase):void { super.resource = value; updateLoadTrait(); } // Protected // /** * The LoaderBase used by this element to load resources. **/ protected final function get loader():LoaderBase { return _loader; } protected final function set loader(value:LoaderBase):void { _loader = value; } /** * Subclasses can override this method to return a custom LoadTrait * subclass. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ protected function createLoadTrait(resource:MediaResourceBase, loader:LoaderBase):LoadTrait { return new LoadTrait(_loader, resource); } /** * * Subclasses can override this method to do processing when the media * element enters the LOADING state. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ protected function processLoadingState():void { // Subclass stub } /** * Subclasses can override this method to do processing when the media * element enters the READY state. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ protected function processReadyState():void { // Subclass stub } /** * Subclasses can override this method to do processing when the media * element enters the UNLOADING state. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion OSMF 1.0 */ protected function processUnloadingState():void { // Subclass stub } /** * @private * * Given a resource, this method will locate the first LoaderBase which can handle * the resource and set it as the loader for this class. Gives precedence to the * current loader first, then the alternateLoaders, in order. **/ protected function getLoaderForResource(resource:MediaResourceBase, alternateLoaders:Vector.):LoaderBase { // Assume it's the original loader. var result:LoaderBase = loader; if (resource != null && (loader == null || loader.canHandleResource(resource) == false)) { // Don't call canHandleResource twice on the same loader. var loaderFound:Boolean = false; for each (var alternateLoader:LoaderBase in alternateLoaders) { // Skip this one if it's the same as the current loader. if (loader == null || loader != alternateLoader) { if (alternateLoader.canHandleResource(resource)) { result = alternateLoader; break; } } } // If none was found that can handle the resource, pick the // last one, if only so that errors will be dispatched // further downstream. if (result == null && alternateLoaders != null) { result = alternateLoaders[alternateLoaders.length - 1]; } } return result; } // Private // private function onLoadStateChange(event:LoadEvent):void { // The asymmetry between READY and UNLOADING (versus UNINITIALIZED) is // motivated by the fact that once a media is already unloaded, one // cannot reference it any longer. Triggering the event upfront the // actual unload being effectuated allows listeners to still act on // the media that is about to be unloaded. if (event.loadState == LoadState.LOADING) { processLoadingState(); } else if (event.loadState == LoadState.READY) { processReadyState(); } else if (event.loadState == LoadState.UNLOADING) { processUnloadingState(); } } private function updateLoadTrait():void { var loadTrait:LoadTrait = getTrait(MediaTraitType.LOAD) as LoadTrait; if (loadTrait != null) { // Remove (and unload) any existing LoadTrait. if (loadTrait.loadState == LoadState.READY) { loadTrait.unload(); } loadTrait.removeEventListener ( LoadEvent.LOAD_STATE_CHANGE , onLoadStateChange ); removeTrait(MediaTraitType.LOAD); } if (loader != null) { // Add a new LoadTrait for the current resource. loadTrait = createLoadTrait(resource, loader); loadTrait.addEventListener ( LoadEvent.LOAD_STATE_CHANGE , onLoadStateChange, false, 10 // Using a higher priority event listener in order to process load state changes before clients. ); addTrait(MediaTraitType.LOAD, loadTrait); } } private var _loader:LoaderBase; } }