Cache some contents

Thanks for all your comments it’s been a while I haven’t post new article. I’ve been very busy but I will try to be more steady.

Today I come with a problem I often met : How to optimize my loadings ?

In various situation you need to load data and keep it available, for that I create an helpfull class, I call it ContentCache.

How does it work ?

I use the Dictionnary class to stock data, Dictionnaries are a very powerfull HashTable because you can use any object as key to get your value.
Thanks to that I can use the URL of the loaded object as key and be sure that I won’t load 2 times the same item !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package  multiFreid.net
{
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.net.URLRequest;
    import flash.utils.Dictionary;
    /**
     * ...
     * @author multifred
     */

    public final class ContentCache extends EventDispatcher
    {
        private var _cache:Dictionary;
        protected static var _totalLoaded:Number;
        public static function get totalLoaded():Number { return _totalLoaded; }
        protected static var _instance:ContentCache;
       
        public function ContentCache()
        {
            _totalLoaded = 0;
            _cache = new Dictionary();
        }
       
        public static function getInstance():ContentCache
        {
            if (!_instance)
                _instance = new ContentCache();
            return _instance;
        }
        /**
         * Load content if it is not in the cache
         * @param   path    Path of the content to load
         * @return  The loader
         */

        public function getContent(path:String):Loader
        {
            var urlRequest:URLRequest  = new URLRequest(path);
            if (_cache[urlRequest.url])
            {
                return _cache[urlRequest.url] as Loader;
            }
           
            var loader:Loader = new Loader();
           
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            _cache[urlRequest.url] = loader;
            loader.load(urlRequest);
           
            return _cache[urlRequest.url] as Loader;
        }
        /**
         * COMPLETE event Handler, track the loaded Data
         * @param   evt
         */

        private function completeHandler(evt:Event):void
        {
            var li:LoaderInfo = (evt.currentTarget as LoaderInfo)
            li.removeEventListener(Event.COMPLETE, completeHandler);
            li.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
           
            _totalLoaded += li.bytesTotal;
            trace(li.bytesTotal);
            dispatchEvent(new Event(Event.COMPLETE));
        }
       
        /**
         * IOError Handler : It will remove the loader from the cache
         * @param   evt
         */

        private function errorHandler(evt:IOErrorEvent):void
        {
            var li:LoaderInfo = (evt.currentTarget as LoaderInfo)
            li.removeEventListener(Event.COMPLETE, completeHandler);
            li.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
           
            dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR));
            _cache[(evt.currentTarget as Loader).loaderInfo.url] = null;
        }
       
    }

}

I keep using the Loader object to still have access to the ‘contentLoadeInfo’ property.
Actually, I wish to create a Class I could call CachedData were I’ll load as well URLLoader and Loader and then the getContent function shall return an Object.

If you have any suggesion I will be glad to think on it. You can contact me or follow me on twitter @multifreid