title: Run-time loading of external assets and re-using preloaded assets in actionscript 3?
body: <p>I'm creating a 2d flash game (coded in flex/actionscript 3) where assets are downloaded when they are needed. Currently I have it setup like this:</p>
  
  <p>AssetLoader.as</p>
  
  <pre><code>package
  {
      import flash.display.Loader;
      import flash.net.URLRequest;
  
      public class AssetLoader extends Loader
      {
          //set vars
          private var url:String = "http://test.com/client/assets/";
  
          public function AssetLoader(url:String)
          {
              Logger.log("AssetLoader request: " + this.url + url);
              var request:URLRequest = new URLRequest(this.url + url);
              this.load(request);
          }
      }
  }
  </code></pre>
  
  <p>Then, where I want to load the asset I do the following:</p>
  
  <pre><code>var asset:AssetLoader = new AssetLoader("ships/" + graphicId + ".gif");
  asset.contentLoaderInfo.addEventListener(Event.COMPLETE, onShipAssetComplete, false, 0, true);
  
  private function onShipAssetComplete(event:Event):void
  {
      var loader:Loader = Loader(event.target.loader);
          shipImage = Bitmap(loader.content);
          shipImage.smoothing = true;
          addChild(shipImage);
  }
  </code></pre>
  
  <p>The thing is, that this method doesn't check for already downloaded assets, so it will redownload them the second time the same asset is being requested (I think).</p>
  
  <p>So, what I need is an array where all downloaded assets are stored, and on request the name of this asset is checked for existance in the array. So if it has already been downloaded, that asset from memory must be returned rather than redownloaded.</p>
  
  <p>I could make the assetloader a static class, but I have to wait for the event to fire when it's done downloading the image - so I can't simply let a static function return the corresponding image. Any idea how I should do this?</p>
  
  <p><strong>EDIT for an attempt after comments:</strong></p>
  
  <pre><code>package
  {
      import flash.display.Loader;
      import flash.events.Event;
      import flash.net.URLRequest;
  
      public final class AssetManager
      {
          private static var assets:Object = {};
          private static var preUrl:String = Settings.ASSETS_PRE_URL;
  
          public static function load(postUrl:String):*
          {
              if (assets[postUrl])
              { //when the asset already exists
                  //continue
              }
              else
              { //the asset still has to be downloaded
                  var request:URLRequest = new URLRequest(preUrl + postUrl);
                  var loader:Loader = new Loader();
                  loader.load(request);
                  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, 
                  function(event:Event):void
                  {
                      var loader:Loader = Loader(event.target.loader);
                      assets[postUrl] = loader.content;
                  }, false, 0, true); 
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>EDIT2: another attempt</strong></p>
  
  <pre><code>package
  {
      import flash.display.Loader;
      import flash.events.Event;
      import flash.events.EventDispatcher;
      import flash.net.URLRequest;
  
      public final class AssetManager
      {
          private static var assets:Object = {};
          private static var preUrl:String = Settings.ASSETS_PRE_URL;
  
          public static function load(postUrl:String):*
          {
              if (assets[postUrl])
              { //the asset already exists
                  var dispatcher:EventDispatcher = new EventDispatcher();
                  dispatcher.dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, assets[postUrl]));
              }
              else
              { //the asset still has to be downloaded
                  var request:URLRequest = new URLRequest(preUrl + postUrl);
                  var loader:Loader = new Loader();
                  loader.load(request);
                  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, 
                  function(event:Event):void
                  {
                      var loader:Loader = Loader(event.target.loader);
                      assets[postUrl] = loader.content;
                      var dispatcher:EventDispatcher = new EventDispatcher();
                      dispatcher.dispatchEvent(new CustomEvent(CustomEvent.LOAD_COMPLETE, assets[postUrl]));
                  }, false, 0, true); 
              }
          }
      }
  }
  </code></pre>
  
  <p>Then, I try the following:</p>
  
  <pre><code>var asset:AssetManager = AssetManager.load("ships/" + graphicId + ".gif");
              asset.addEventListener(CustomEvent.LOAD_COMPLETE, onShipAssetComplete, false, 0, true);
  </code></pre>
  
  <p>But get an error, "undefined method addEventListener by a reference of the type static AssetManager" (roughly translated).</p>