Blog

  • Generic Responder – Good for Command Pattern

    When implementing the Command pattern for this game concept I’m working on at home, I had a need for the command to also support an “executed” method. Typically, it executes, and that’s the end of it.

    However, I’m managing the commands in a Queue/Stack of sorts, and need to know when the command is done. Since the command class really has little coupling with the source that it’s actually calling the command on, I created a Responder class that they all could share. The issue is, however, there is no way to create these in such a way to merely have a method, execute it when the even happens, and then go away.

    Granted, my class could implement the event, and using GDispatcher, execute it, but these events are asyncronous, and I don’t want the command adding himself as a listener to the “receiver”, or the class he’s executing the command on. Everything now is nicely coupled only via methods or explicit setting via the Controller. It’s an abstract pain in the arse, but so far the code is beautiful and flexible. Thus, the Responder needed to have a Singleton’esque ability to create instances of himself for one time uses, but have enough knowledge of the method he’s calling since the class who is using him cares not what even happens to him. The usual way is when you create a responder, you hold onto it, or map it back to yourself; like Remoting/Central responder objects either map to functions in your class or are generic responder objects that execute in your class’ scope. If you don’t care, what do you do?

    I created a static method of my responder class to create one-time event listeners that call a method, pass what args you need, and assumably die when done. This way, my Command class could execute the command, and get the generic responder object as the return value. The receiver, or the class getting the command executed upon it, could return this responder, and when his event is done, merely have the responder inform the command class without having to worry about caring about the responder objects after that point.

    Since the Command class adds himself as a listener, he’ll be able to generate events on when commands are started and stopped (and any number of mods such as “undo” in the future), and this then supports a nice way for the Queue to know wtf is going on.

    Observe the method; the entire class is at the bottom.

    static function createGenericResponder(method:String):Object
    {
            var o:Object = {};
            grantskinner.events.GDispatcher.initialize(o);
            o.method = method;
            o[method] = function()
            {
                    dispatchEvent({type: this.method, target: this, results: arguments});
            };
            return o;
    }
    

    Here’s an example of a function called via the Command class, and the reciever returning the generic responder which he’ll call when an animation is done.

    public function attack(targets_array:Array):Object
    var o:Object = jxl.events.Responder.createGenericResponder("onDoneAttacking");
    this.gotoAndPlay(ATTACKING_START);
    doWhenFrameReached("onDoneAttacking", this, this, ATTACKING_END, o);
    return o;
    }
    

    And the Responder class it sits in:

    class jxl.events.Responder
    {
            static var inited:Boolean;
            
            public var addEventListener:Function;
            public var removeEventListener:Function;
            private var dispatchEvent:Function;
            
            function Responder()
            {
                    if(!inited){
                            inited = true;
                            grantskinner.events.GDispatcher.initialize(Responder.prototype);
                    }
            }
            
            public function onResult()
            {
                    dispatchEvent({type: "result", target: this, results: arguments});
            }
            
            public function onStatus()
            {
                    dispatchEvent({type: "status", target: this, results: arguments});
            }
            
            static function createGenericResponder(method:String):Object
            {
                    var o:Object = {};
                    grantskinner.events.GDispatcher.initialize(o);
                    o.method = method;
                    o[method] = function()
                    {
                            dispatchEvent({type: this.method, target: this, results: arguments});
                    };
                    return o;
            }
    }
    
  • Web Service Connector Factory

    Waiting on Java programmers, so trying to be effective with my time. Figured I’d show some code snippets I’ve found useful over the past couple of weeks. Hopefully someone can gleen some use from ’em.

    First on da platter is a factory function to create web service calls. I had some problems with the web service classes, so ended up using the WebServiceConnector on the majority of my work here at my job. However, as a physical component with a few parameters, I needed an easy way to create many, allow them to function indenpendently, but quickly get the code running so I could meet my Friday deadlines.

    The below creates WebServiceConnectors, initializes them, fires off the web service call, and waits for the response. When there is a response, it calls whatever function is required, and then self-destructs. Who knows if garbage collection cleans up the mess… Make sure you have a WebServiceConnector in your library. Technically the return value should be WebServiceConnector.

    
    function createWebService(WSDLURL,
                              result_str,
                              result_obj,
                              status_str,
                              status_obj,
                              operation,
                              params):Object
    {
            if(wsID == null){
                    wsID = -1;
            }
            wsID++;
            // create the web service connector
            var ws = attachMovie("WebServiceConnector", "ws" + wsID, getNextHighestDepth());
            ws.WSDLURL = WSDLURL;
            
            // create a responder object and set him up with needed supplies
            var r = {};
            // who is my parent?
            r.owner = this;
            // what web service?
            r.ws = ws;
            // what method do I call when done?
            r.result_str = result_str;
            // what scope is he in?
            r.result_obj = result_obj;
            // what method do I call when I flarge up?
            r.status_str = status_str;
            // what scope is he in?
            r.status_obj = status_obj;
            // define my result function
            r.result = function(result)
            {
                    // call my callback, and pass the result
                    this.result_obj[this.result_str](result);
                    this.ws.removeMovieClip();
            };
            r.status = function(status)
            {
                    // call my callback, and pass the status
                    this.status_obj[this.status_str](status);
            };
            // add the responder as a listener
            ws.addEventListener("result", r);
            ws.addEventListener("status", r);
            // define the web service method name
            ws.operation = operation;
            // any web service arguments?
            // Remove the first 5 to check for leftovers...
            arguments.shift();
            arguments.shift();
            arguments.shift();
            arguments.shift();
            arguments.shift();
            if(arguments.length > 0){
                    ws.params = arguments;
            }else{
                    ws.params = [];
            }
            // start this mug!
            ws.trigger();
            // you want this?
            return ws;
    }
    

    Example usage:

    var ws = createWebService("http://something.com/service?WSDL",
                              "result",
                              this,
                              "status",
                              this,
                              "doIt",
                              "JesterXL",
                              "mypassword");
    
  • Super need not apply, nor call

    Dude, is this a bug in AS2? I’m probably doing it wrong.

    In the main timeline, I can do:

    function Mammal(target)
    {
            this.target = target;
    }
    
    function Cow(t)
    {
            super.apply(this, [t]); // doesn't work
            super.apply(super, [t]); // doesn't work
            super.call(this, t); // doesn't work
            super.call(super, t); // doesn't work
    }
    Cow.prototype = new Mammal();
    

    It doesn’t even compile in AS2:

    class Mammal extends Cow
    {
            function Mammal(t)
            {
                    super.apply(this, [t]); // says there is no apply method
                    super.call(this, t); // says there is no call method
            }
    }
    

    I’m guessing this is because inside the constructor, it’s scoped to the function vs. “this”, where this is the class.

    Typically, I’ll do:

    function MyClass()
    {
            init.apply(this, arguments);
    }
    

    So if the init method has a lot of arguments, I don’t have to type them out 3 times; twice in the constructor, and then again in the init. I figured I could just bypass init, and use super… but I guess he’s weird…? I’m confused.

  • WTF is createClassObject, createObject, and destroyObject?

    Lemme get that for you. Typically the documentation explains these as “object creators” which is kind of… well, generic. They do more (or less) than that, and they are a lot more approachable than the docs lead on. They are, however, integral that you learn when you mess with the framework, for if nothing else, to kick it good form style. I don’t know everything, but here’s what I do know.

    createObject

    Replacement for attachMovie in the Flash MX 2004 component framework. A wrapper function for attachMovie, it operates the exact same. It returns whatever attachMovie returns; typically the movie clip/component object your attaching. You pass in the same parameters.

    destroyObject

    Replacement and extension for removeMovieClip in the Flash MX 2004 component framework. A wrapper function for removeMovieClip, it extends it to support authortime clips as well. Since authortime components (objects manually dropped on the stage at authortime) are automatically compiled to reside in negative depths, removeMovieClip will not work on them. This method, if it detects an authortime component trying to be removed, will find a depth that is unoccupied and empty, bring the component to that depth, and remove it. Finally, it deletes a reference to the movie clip’s name (no clue why since you just removed it).

    The difference with this method vs. removeMovieClip however is that it takes a string parameter; the movie clip/component’s name as a string. Therefore, instead of doing:

    my_lb.removeMovieClip();
    // or
    removeMovieClip(my_lb);
    

    You’d do:

    destroyObject(my_lb._name);
    

    The framework itself uses this method because there are a ton of string references to objects in the other classes because of skinning, for example. Still, that’s not enough for me to understand why they did it this way. Maybe Java’s Swing does this… :: shrugs ::

    createClassObject

    An replacement and extension of attachMovie in the Flash MX 2004 framework. Typically, you use similiar to attachMovie, except you use your class name. For example:

    var ref_lb = createClassObject(mx.controls.List, "names_lb", 0);

    The first parameter, however, determines how the function works. Most classes created to work in the Flash MX 2004 framework will have a 2 static variables defined called symbolOwner and symbolName. The symbolName one represents a string pointing to the component’s linkageID. The symbolOwner is a reference to the class’s class name, or package path. In List’s case, that is mx.controls.List; the object on global that holds his class definition.

    This function assumes if the class you pass in doesn’t have a symbolName, then it must be a sub class. Since this function calls createObject, and thus attachMovie, your creating a movie clip and getting a reference to it. The way Flash 6 & 7 associate class methods with a movie clip is via the method Object.registerClass. This takes the movie clip’s symbol linkage name (got that?), the class, and basically says, “Yo, if you ever get attached, you’ll now have all the powers of this class; properties, methods, you name it.” This can get weird if your class doesn’t inherit from MovieClip somewhere up the chain… at least in wrapping your head around the concept, anyway.

    Therefore, if your class is a sub class, it’ll register it via Object.registerClass with the class’ symbolName/linkageID. After attaching the component/movie clip via createObject, assuming you passed in a sub-class, it does the registering again with a slight difference; it uses the className’s symbolOwner/class name instead of just the className you passed in. Not sure of the significance of the difference.

    Conclusion

    These are support methods, really, for a lot of the framework. Additionally, you can now see where the symbolName and symbolOwner static variables you may have been defining in your components are used. If these methods don’t work, it’s probably because those variables are not defined or miss-spelled. I’ve copied and pasted classes before to save time in rewriting a new class. I sometimes forget to change these variables with the class name.