1 Reply Latest reply on May 21, 2007 2:48 PM by cluebcke

    singletons and static initializers oh my!

    snafu7x7
      I'm trying to write a Settings class that will load in configuration items from a custom xml file. In typical OO this is often handled by implementing a Singleton design pattern (to ensure only a single instance is created ever) and using static initializers to load static properties when the class is loaded. Since AS3 doesnt allow private constructors using a static initializer seemed to make even more sense. My code below illustrates what I'm trying to accomplish. Basically when the class is first loaded I want it to call my LoadConfig() to populate my settings into an XMLListCollection. I then have a GetConfigItem(key:String) method that will filter thru the XMLListCollection seeking the key and return its associated value.

      The problem is the order of events doesn't occur as expected.

      If in my application I call

      var test:Settings = Settings.instance; //try to force the class to load
      Settings.GetConfigItem("somekey");

      you would expect to not even have to use the first line because the minute you invoke the second it 'should' load the class but I put it in to try to force it to load. So one would expect it to load and initialize the properties and by the time you made the next call to LoadConfig(), the Config variable would be initialized. What happens though is that the LoadConfig isn't getting called until AFTER I make my call to GetConfigItem so the Config object is null and I get an exception. To me this seems to completely violate the way these constructs are supposed to work.

      The only thing I can think might be happening is that the HttpService call is running asynchronously and so the results are not available when expected??? Please help gang, this one's got me stumped...if I've made some boneheaded mistake forgive me, its Friday ;)



      public final class Settings{
      private static var _instance:Settings = new Settings();
      {
      LoadConfig();
      }
      public static var Config:XMLListCollection

      public function Settings()
      {
      if (_instance != null)
      {
      throw new Error("Singleton can only be accessed through Singleton.instance");
      }

      }

      public static function get instance():Settings
      {
      return _instance;
      }

      public static function LoadConfig():void{
      var url:String = "config.xml";
      var service:HTTPService = new HTTPService();
      service.resultFormat = "e4x";
      service.url = url;
      service.addEventListener(ResultEvent.RESULT, onConfigLoad);
      service.send();
      }

      private static function onConfigLoad(event:ResultEvent):void{
      Config = new XMLListCollection(event.result.*);
      }

      public static function GetConfigItem(itemKey:String):String{
      var filteredList:XMLListCollection = Config.(@key.indexOf(itemKey) > -1);
      //return the value associated with the key
      }


      }