Topic: Using HaXe... can I get the chumby AppParams class to play nicely?

Hi Folks,

I've got quite a nice little app written using Haxe and Geany as my dev tools. I'd like to add the option to store a few parameters on the Chumby server so I took a look at the documentation.

I don't know how to include the .as files so that I can import the class. Can anyone give me a push in the right direction?  Thanks!

2 (edited by gmcbay 2011-09-30 11:02:38)

Re: Using HaXe... can I get the chumby AppParams class to play nicely?

I don't have a nice simple wholly formed example of this, but you can do the parameter saving and loading directly in haxe code.

If you've got some parameters in a Hash<String> with their variable names as the keys and their values as the values, you can create a haxe xml document to persist them thusly:

           var uploadXml:Xml = Xml.createDocument();
        
            var widgetInstance:Xml = Xml.createElement('widget_instance');
            
            uploadXml.addChild(widgetInstance);
            
            var widgetParameters:Xml = Xml.createElement('widget_parameters');
            
            widgetInstance.addChild(widgetParameters);
            
            for(saveKey in saveObject.keys())
            {
                var paramNode:Xml = Xml.createElement('widget_parameter');
                
                var nameNode:Xml = Xml.createElement('name');
                nameNode.addChild(Xml.createPCData(saveKey));
                
                var valueNode:Xml = Xml.createElement('value');
                valueNode.addChild(Xml.createPCData(saveObject.get(saveKey)));
                
                paramNode.addChild(nameNode);
                paramNode.addChild(valueNode);
                
                widgetParameters.addChild(paramNode);
            }

To save them, get the proper chumby widget instance url.  Here's a helper function:


    // -----------------------------------------------------------------------------
    private inline function getConfigUrl():String 
    {
#if flash9
        var configUrl:String = Lib.current.loaderInfo.parameters._chumby_instance_url;
        
        if (configUrl == null)
        {
            configUrl = Lib.current.loaderInfo.parameters._chumby_widget_instance_href;
        }
#else
        var configUrl:String = Lib.current._chumby_instance_url;
        
        if (configUrl == null)
        {
            configUrl = Lib.current._chumby_widget_instance_href;
        }
#end
        return configUrl;
    }

To do the actual saving (assuming you are in a function that has been passed successCallback and failureCallback functions -- this code includes versions for both flash9 and flash8, you may not need both):

      url = getConfigUrl();

      if (url != null)
      {
#if flash9
                var urlRequest:URLRequest = new URLRequest(url);
                urlRequest.data = uploadXml.toString();
                urlRequest.contentType = "text/xml";
                urlRequest.method = "POST";
                
                var urlLoader:URLLoader = new URLLoader();                
                
                urlLoader.addEventListener(Event.COMPLETE, function(data:Dynamic) 
                { 
                    if (successCallback != null) 
                    {
                        successCallback();
                    }
                });
                
                urlLoader.addEventListener(IOErrorEvent.IO_ERROR, function(data:Dynamic) 
                { 
                    if (failureCallback != null) 
                    {
                        failureCallback("Network error when saving app settings.");
                    }
                });
                
                urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(data:Dynamic) 
                { 
                    if (failureCallback != null) 
                    {
                        failureCallback("Security error when saving app settings.");
                    }
                });
                
                urlLoader.load(urlRequest);
#else
                var recv:Dynamic = untyped __new__(_global["XML"], uploadXml.toString());                
                
                recv.onData = function(data:Dynamic) 
                { 
                    if (successCallback != null) 
                    {
                        successCallback();
                    }
                }
                
                recv.onHTTPStatus = function(code:Int) 
                { 
                    if (code != 200 && failureCallback != null) 
                    {
                        failureCallback("HTTP error " + code + " when saving app settings.");
                    }
                };
                
                recv.sendAndLoad(url, recv);
#end
            }
            else 
            {
                if (failureCallback != null) 
                {
                    failureCallback("No valid url to save app settings to.");
                }
            }
        

To get the parameter values back you should generally just read them from flash _root as the control panel should place the values there for you.   You can do this in haxe like so:

    // -----------------------------------------------------------------------------
    function getParamVar(name:String):String 
    {
#if flash9
        if (Lib.current != null && Lib.current.loaderInfo != null && 
            Lib.current.loaderInfo.parameters != null)
        {
            return Reflect.field(Lib.current.loaderInfo.parameters, name);
        }
#else
        if (Lib.current != null)
        {
            return Reflect.field(Lib.current, name);
        }
#end

        return null;
    }


    ...

    var whatever:String = getParamVar("whatever");

    ....

(You can do it even faster by just using untyped on the Lib.current objects and referencing the variable names using flash array-syntax, but for a handful of variables you won't save much doing that).

If you need to manually load the variables for any reason:

            var configUrl:String = getConfigUrl();
            
            loadHttp = new Http(configUrl);
            loadHttp.onData = onGotServerParameters;
            loadHttp.request(false);        
     // -----------------------------------------------------------------------------
    function onGotServerParameters(data:String):Void 
    {
        var paramHash:Hash<String> = new Hash<String>();
        
        var xml:Xml = Xml.parse(data);
        var fast:Fast = new Fast(xml.firstElement());
        
        for (parameter in fast.node.widget_parameters.nodes.widget_parameter)
        {
            paramHash.set(parameter.node.name.innerData,  parameter.node.value.innerData);
        }
    }

Sorry this isn't a more complete example, I'll put one together when I have some more free time, but the code should be fairly easy to smash into your own code to get something working.

Alternately, you can use the 'as' class from haxe since haxe can inteop with actionscript code, though how you include it depends on whether you are targeting avm1/ActionScript2 or avm2/ActionScript3.   I'd assume as3 since the link you posted is as3 specific?