/* BulkLoader: manage multiple loadings in Actioncript 3.
*
*
* @author Arthur Debert
* @version 0.9.1
*/
/*
* Licensed under the MIT License
*
* Copyright (c) 2006-2007 Arthur Debert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://code.google.com/p/bulk-loader/
* http://www.opensource.org/licenses/mit-license.php
*
*/
package br.com.stimuli.loading.loadingtypes {
import br.com.stimuli.loading.BulkLoader;
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.utils.*;
/**
* Dispatched on download progress.
*
* @eventType flash.events.ProgressEvent.PROGRESS
*/
[Event(name="progress", type="flash.events.ProgressEvent")]
/**
* Dispatched when all the item has been fully downloaded and is ready for use..
*
* @eventType flash.events.ProgressEvent.COMPLETE
*/
[Event(name="complete", type="flash.events.Event")]
/**
* Dispatched when the connection has been stablished and the download has begun. For types that can be streamed such as videos (NetStream) and sound(Sound), it's content is will be available after this event has fired.
*
* @eventType flash.events.Event.OPEN
*/
[Event(name="open", type="flash.events.Event")]
/**
* Dispatched when the the netStream can be played until the end with no interuption expected. Only fires for TYPE_VIDEO items and will only fire once.
*
* @eventType br.com.stimuli.loading.BulkLoader.CAN_BEGIN_PLAYING
*/
[Event(name="canBeginPlaying", type="br.com.stimuli.loading.BulkLoader")]
/**
* An class used in BulkLoader instances.
LoadingItem object can be used to attach events for an individual item, read it's id, type, content and urls from inside event handlers.
* When implementing custom loading types, the new type should be a subclass of LoadingItem.
* This class is just the base for specific loading types, but should provide the external interface for end users.
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
*
* @author Arthur Debert
* @since 15.09.2007
*/
public class LoadingItem extends EventDispatcher {
/** @private */
public static const STATUS_STOPPED : String = "stopped";
/** @private */
public static const STATUS_STARTED : String = "started";
/** @private */
public static const STATUS_FINISHED : String = "finished";
/** @private */
public static const STATUS_ERROR : String = "error";
/** The type of loading to perform (see BulkLoader.TYPES).
* @private */
public var _type : String;
// The url to load the asset from.
/** @private */
public var url : URLRequest;
/** @private */
public var _id : String;
/** @private */
public var _uid : String;
/** @private */
public var _additionIndex : int ;
/** @private */
public var _priority : int = 0;
/** @private */
///**Indicated if item is loaded and ready to use..*/
/** @private */
public var _isLoaded : Boolean;
/**Indicated if loading has stated.
* @private
*/
public var _isLoading : Boolean;
/** @private
* At what stage this item is at ( canceled, started, finished or error).
*/
public var status : String;
//
/** @private
* Maximun number of tries in case it fails.
* */
public var maxTries : int = 3;
/**Current try number.
* @private
*/
public var numTries : int = 0;
/**A relative unit of size, so that preloaders can show relative progress before all connections have started.
* @private
*/
public var weight : int = 1;
/**If a random string should be appended to the end of the url to prevent caching.
* @private
*/
public var preventCache : Boolean;
/**the number of bytes to load. Starts at -1.
* @private
*/
public var _bytesTotal : int = -1;
/**the number of bytes loaded so far. Starts at -1.
* @private
*/
public var _bytesLoaded : int = 0;
/** @private */
public var _bytesRemaining : int = 10000000;
/**The percentage of loading done (from 0 to 1).
* @private
*/
public var _percentLoaded : Number;
/**The percentage of loading done relative to the weight of this item(from 0 to 1).
* @private
*/
public var _weightPercentLoaded : Number;
/**
* @private
*/
public var _addedTime : int ;
/** @private */
public var _startTime : int ;
/** @private */
public var _responseTime : Number;
/** The time (in seconds) that the server took and send begin streaming content.
@private
*/
public var _latency : Number;
/** @private */
public var _totalTime : int;
/** The total time (in seconds) this item took to load.*/
public var _timeToDownload : int;
/** The speed (in kbs) for this download.
* @private
* */
public var _speed : Number;
/** @private */
public var _content : *;
/** @private */
public var _httpStatus : int = -1;
/**
* @private
*/
public var _context : * = null;
/** @private */
public var specificAvailableProps : Array ;
/** @private */
public var propertyParsingErrors : Array;
/** Stores any erros (if any), such as IOError and SecurityError for this item */
public var errorEvent : ErrorEvent;
public function LoadingItem(url : URLRequest, type : String, _uid : String){
this._type = type;
this.url = url;
if(!specificAvailableProps){
specificAvailableProps = [];
}
this._uid = _uid;
}
/**
* @private
*/
public function _parseOptions(props : Object) : Array{
preventCache = props[BulkLoader.PREVENT_CACHING];
_id = props[BulkLoader.ID];
_priority = int(props[BulkLoader.PRIORITY]) || 0;
maxTries = props[BulkLoader.MAX_TRIES] || 3;
weight = int(props[BulkLoader.WEIGHT]) || 1;
// checks that we are not adding any inexistent props, aka, typos on props :
var allowedProps : Array = BulkLoader.GENERAL_AVAILABLE_PROPS.concat(specificAvailableProps);
propertyParsingErrors = [];
for (var propName :String in props){
if (allowedProps.indexOf(propName) == -1){
propertyParsingErrors.push(this + ": got a wrong property name: " + propName + ", with value:" + props[propName]);
}
}
return propertyParsingErrors;
}
/** The content resulting from this download. The data type for the content depends on the myme-type of the downloaded asset. For types that can be streamed such as videos (NetStream) and sound(Sound), it's content is available as soon as the connection is open. Otherwiser the content will be available after the download is done and the Event.COMPLETE is fired.
* @return An object whose type depends on what the asset is.
*/
public function get content() : * {
return _content;
}
/**
* @private
*/
public function load() : void{
if (preventCache){
var cacheString : String = "BulkLoaderNoCache=" + _uid + "_" + int(Math.random() * 100 * getTimer());
if(url.url.indexOf("?") == -1){
url.url += "?" + cacheString;
}else{
url.url += "&" + cacheString;
}
}
_isLoading = true;
_startTime = getTimer();
}
/**
* @private
*/
public function onHttpStatusHandler(evt : HTTPStatusEvent) : void{
_httpStatus = evt.status;
dispatchEvent(evt);
}
/**
* @private
*/
public function onProgressHandler(evt : *) : void {
_bytesLoaded = evt.bytesLoaded;
_bytesTotal = evt.bytesTotal;
_bytesRemaining = _bytesTotal - bytesLoaded;
_percentLoaded = _bytesLoaded / _bytesTotal;
_weightPercentLoaded = _percentLoaded * weight;
dispatchEvent(evt);
}
/**
* @private
*/
public function onCompleteHandler(evt : Event) : void {
_totalTime = getTimer();
_timeToDownload = ((_totalTime - _responseTime) /1000);
if(_timeToDownload == 0){
_timeToDownload = 0.2;
}
_speed = BulkLoader.truncateNumber((bytesTotal / 1024) / (_timeToDownload));
if (_timeToDownload == 0){
_speed = 3000;
}
status = STATUS_FINISHED;
_isLoaded = true;
dispatchEvent(evt);
evt.stopPropagation();
}
/**
* @private
*/
public function onErrorHandler(evt : ErrorEvent) : void{
numTries ++;
evt.stopPropagation();
if(numTries < maxTries){
status = null
load();
}else{
status = STATUS_ERROR;
errorEvent = evt;
_dispatchErrorEvent(errorEvent);
}
}
/** @private
*/
public function _dispatchErrorEvent (evt : ErrorEvent) : void{
// we are dispatching here so we can have all error events catched by addEventListener("error"), regardless of event type.
status = STATUS_ERROR;
dispatchEvent(new ErrorEvent(BulkLoader.ERROR, true, false, evt.text));
}
/** private
*/
public function _createErrorEvent(e : Error) : ErrorEvent{
return new ErrorEvent(BulkLoader.ERROR, false, false, e.message);
}
/**
* @private
* @param A SecurityErrorEvent.
*/
public function onSecurityErrorHandler(e : ErrorEvent) : void{
status = STATUS_ERROR;
errorEvent = e as ErrorEvent;
e.stopPropagation();
_dispatchErrorEvent(errorEvent);
}
/**
* @private
*/
public function onStartedHandler(evt : Event) : void{
_responseTime = getTimer();
_latency = BulkLoader.truncateNumber((_responseTime - _startTime)/1000);
status = STATUS_STARTED;
dispatchEvent(evt);
}
public override function toString() : String{
return "LoadingItem url: " + url.url + ", type:" + _type + ", status: " + status;
}
/**
* @private
*/
public function stop() : void{
if(_isLoaded){
return;
}
status = STATUS_STOPPED;
_isLoading = false;
}
/**
* @private
*/
public function cleanListeners() : void {
}
/** Returns true if content is of type video.
*/
public function isVideo(): Boolean{
return false;
}
/** Returns true if content is of type sound.
*/
public function isSound(): Boolean{
return false;
}
/** Returns true if content is of type text.
*/
public function isText(): Boolean{
return false;
}
/** Returns true if content is of type xml.
*/
public function isXML(): Boolean{
return false;
}
/** Returns true if content is of type image.
*/
public function isImage() : Boolean{
return false;
}
/** Returns true if content is of type movieclip.
*/
public function isSWF() : Boolean{
return false;
}
/** Returns true if uses a Loader instance internally. (such as swfs and images).
*/
public function isLoader(): Boolean{
return false;
}
/** Returns true if this loading type should allow it's content to be accessed as soon as the server response starts. Should be true for sound and video types.
*/
public function isStreamable() : Boolean{
return false;
}
/**
* @private
*/
public function destroy() : void{
_content = null;
//loader = null;
}
/** Public accessors
* @private
*/
public function get bytesTotal() : int {
return _bytesTotal;
}
/**
* @private
*/
public function get bytesLoaded() : int {
return _bytesLoaded;
}
/**
* @private
*/
public function get bytesRemaining() : int {
return _bytesRemaining;
}
/**
* @private
*/
public function get percentLoaded() : Number {
return _percentLoaded;
}
/**
* @private
*/
public function get weightPercentLoaded() : Number {
return _weightPercentLoaded;
}
/** The priority at which this item will be downloaded. Items with a higher priority will be downloaded first.
* @private
*/
public function get priority() : int {
return _priority;
}
/** The type of this item.
* @see BulkLoader.AVAILABLE_EXTENSIONS
*/
public function get type() : String{
return _type;
}
/** A Boolean that indicates if the item is fully loaded and ready for consumption.
*/
public function get isLoaded() : Boolean {
return _isLoaded;
}
/**
* @private
*/
public function get addedTime() : int {
return _addedTime;
}
/**
* @private
*/
public function get startTime() : int {
return _startTime;
}
/**
* @private
*/
public function get responseTime() : Number {
return _responseTime;
}
/** The time (in seconds) that the server took and send begin streaming content.
* @private
*/
public function get latency() : Number {
return _latency;
}
/**
* @private
*/
public function get totalTime() : int {
return _totalTime;
}
/** The total time (in seconds) this item took to load.
* @private
*/
public function get timeToDownload() : int {
return _timeToDownload;
}
/** The speed (in kbs) for this download.
* @private
*/
public function get speed() : Number {
return _speed;
}
/** The httpStatus of the LoadingItem, as in int (0 if no status has been received).
* @private
*/
public function get httpStatus() : int {
return _httpStatus;
}
/** The id this item was assigned. This is use in all of BulkLoader.getXXX(key) functions
*/
public function get id() : String {
return _id;
}
/** Returns a string with time stats for this loading item.
*/
public function getStats() : String{
return "Item url:" + url.url +
", total time: " + _timeToDownload +
"(s), latency:" + _latency +
"(s), speed: " + _speed +
" kb/s, size: " + BulkLoader.truncateNumber(_bytesTotal/1024) + " kb";
}
}}