All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.feathers.utils.textures.TextureCache.as Maven / Gradle / Ivy

/*
Feathers
Copyright 2012-2015 Bowler Hat LLC. All Rights Reserved.

This program is free software. You can redistribute and/or modify it in
accordance with the terms of the accompanying license agreement.
*/
package feathers.utils.textures
{
	import flash.errors.IllegalOperationError;

	import starling.textures.Texture;

	/**
	 * Caches textures in memory. Each texture may be saved with its own key,
	 * such as the URL where the original image file is located.
	 * 
	 * 

Note: Most developers will only need to create a * TextureCache, pass it to multiple ImageLoader * components, and dispose the cache when finished. APIs to retain and * release textures are meant to be used by ImageLoader.

* *

A single TextureCache may be passed to multiple * ImageLoader components using the textureCache * property:

* * * var cache:TextureCache = new TextureCache(); * loader1.textureCache = cache; * loader2.textureCache = cache; * *

Don't forget to dispose the TextureCache when it is no * longer needed -- to avoid memory leaks:

* * * cache.dispose(); * *

To use a TextureCache in a List or * GroupedList with the default item renderer, pass the cache * to the ImageLoader components using the * iconLoaderFactory or * accessoryLoaderFactory:

* * * var cache:TextureCache = new TextureCache(); * list.itemRendererFactory = function():IListItemRenderer * { * var itemRenderer:DefaultListItemRenderer = new DefaultListItemRenderer(); * itemRenderer.iconLoaderFactory = function():ImageLoader * { * var loader:ImageLoader = new ImageLoader(); * loader.textureCache = cache; * return loader; * }; * return itemRenderer; * }; * * @see feathers.controls.ImageLoader#textureCache */ public class TextureCache { /** * Constructor. */ public function TextureCache(maxUnretainedTextures:int = int.MAX_VALUE) { this._maxUnretainedTextures = maxUnretainedTextures; } /** * @private */ protected var _unretainedKeys:Vector. = new []; /** * @private */ protected var _unretainedTextures:Object = {}; /** * @private */ protected var _retainedTextures:Object = {}; /** * @private */ protected var _retainCounts:Object = {}; /** * @private */ protected var _maxUnretainedTextures:int; /** * Limits the number of unretained textures that may be stored in * memory. The textures retained least recently will be disposed if * there are too many. */ public function get maxUnretainedTextures():int { return this._maxUnretainedTextures; } /** * @private */ public function set maxUnretainedTextures(value:int):void { if(this._maxUnretainedTextures === value) { return; } this._maxUnretainedTextures = value; if(this._unretainedKeys.length > value) { this.trimCache(); } } /** * Disposes the texture cache, including all textures (even if they are * retained). */ public function dispose():void { for each(var texture:Texture in this._unretainedTextures) { texture.dispose(); } for each(texture in this._retainedTextures) { texture.dispose(); } this._retainedTextures = null; this._unretainedTextures = null; this._retainCounts = null; } /** * Saves a texture, and associates it with a specific key. * * @see #removeTexture() * @see #hasTexture() */ public function addTexture(key:String, texture:Texture, retainTexture:Boolean = true):void { if(!this._retainedTextures) { throw new IllegalOperationError("Cannot add a texture after the cache has been disposed.") } if(key in this._unretainedTextures || key in this._retainedTextures) { throw new ArgumentError("Key \"" + key + "\" already exists in the cache."); } if(retainTexture) { this._retainedTextures[key] = texture; this._retainCounts[key] = 1 as int; return; } this._unretainedTextures[key] = texture; this._unretainedKeys[this._unretainedKeys.length] = key; if(this._unretainedKeys.length > this._maxUnretainedTextures) { this.trimCache(); } } /** * Removes a specific key from the cache, and optionally disposes the * texture associated with the key. * * @see #addTexture() */ public function removeTexture(key:String, dispose:Boolean = false):void { if(!this._unretainedTextures) { return; } var texture:Texture = this._unretainedTextures[key] as Texture; if(texture) { this.removeUnretainedKey(key); } else { texture = this._retainedTextures[key] as Texture; delete this._retainedTextures[key]; delete this._retainCounts[key]; } if(dispose && texture) { texture.dispose(); } } /** * Indicates if a texture is associated with the specified key. */ public function hasTexture(key:String):Boolean { if(!this._retainedTextures) { return false; } return key in this._retainedTextures || key in this._unretainedTextures; } /** * Returns how many times the texture associated with the specified key * has currently been retained. */ public function getRetainCount(key:String):int { if(this._retainCounts && (key in this._retainCounts)) { return this._retainCounts[key] as int; } return 0; } /** * Gets the texture associated with the specified key, and increments * the retain count for the texture. Always remember to call * releaseTexture() when finished with a retained texture. * * @see #releaseTexture() */ public function retainTexture(key:String):Texture { if(!this._retainedTextures) { throw new IllegalOperationError("Cannot retain a texture after the cache has been disposed.") } if(key in this._retainedTextures) { var count:int = this._retainCounts[key] as int; count++; this._retainCounts[key] = count; return Texture(this._retainedTextures[key]); } if(!(key in this._unretainedTextures)) { throw new ArgumentError("Texture with key \"" + key + "\" cannot be retained because it has not been added to the cache."); } var texture:Texture = Texture(this._unretainedTextures[key]); this.removeUnretainedKey(key); this._retainedTextures[key] = texture; this._retainCounts[key] = 1 as int; return texture; } /** * Releases a retained texture. * * @see #retainTexture() */ public function releaseTexture(key:String):void { if(!this._retainedTextures || !(key in this._retainedTextures)) { return; } var count:int = this._retainCounts[key] as int; count--; if(count === 0) { //get the existing texture var texture:Texture = Texture(this._retainedTextures[key]); //remove from retained delete this._retainCounts[key]; delete this._retainedTextures[key]; this._unretainedTextures[key] = texture; this._unretainedKeys[this._unretainedKeys.length] = key; if(this._unretainedKeys.length > this._maxUnretainedTextures) { this.trimCache(); } } else { this._retainCounts[key] = count; } } /** * @private */ protected function removeUnretainedKey(key:String):void { var index:int = this._unretainedKeys.indexOf(key); if(index < 0) { return; } this._unretainedKeys.removeAt(index); delete this._unretainedTextures[key]; } /** * @private */ protected function trimCache():void { var currentCount:int = this._unretainedKeys.length; var maxCount:int = this._maxUnretainedTextures; while(currentCount > maxCount) { var key:String = this._unretainedKeys.shift(); var texture:Texture = Texture(this._unretainedTextures[key]); texture.dispose(); delete this._unretainedTextures[key]; currentCount--; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy