MCVC Controller - Part 3

December 26th, 2007

The controller is the glue that holds your application together. It facilitates communication between views and Models as well as Models to other Models. This controller also over comes one of AS 2.0 fatal flaws; the event system.

I find that there are two types of Flash Developers. The first are the ones who try to use the AS 2.0 event system along with the flawed delegate class, and the other group of people just want things to work right and make their own event system. I fall into the second group. Don’t get me wrong, I like a lot of what the delegate class can do but without keeping scope and passing data along with the event what is the point? With that in mind I present my BaseController from my MCVC system.

/**
 * @author Jesse Freeman | <pre>jesse@bfreedesign.com</pre>
 * <br>
 * <b>BaseController</b> - is an easy way to link all classes together in an application and pass data (Events) between class instances
 * without using a Delegate class. This Class helps relieve scope issues common in flash applications by storing a reference
 * to a class (once registered) and linking it to an id.
 * <br><br>
 * Models & Components automatically register with the controller class. It is important to make sure that Models or
 * Components that have multiple instances are flagged in the init object to use a unique name.
 * <br><br>
 * example register class:
 *
 */

class com.jessefreeman.mcvc.v1.BaseController{
       
        private static var __aControlled_models:Array;
       
        /**
         * This method defines a model to be controlled.
         * @param id: String to be used as a reference to define model being controlled.
         * @param model: Instance of model that will be associated to the id.
         * @Example:(In Model)
         *           BaseController.model_to_control("Model_Name",this);// ‘this’ refers to a reference to the model/instance itself     
         */

        public static function model_to_control(id:String,model:Object):Boolean{
                trace(“BaseController.model_to_control(”+id+“, Model.”+model.name+“)”);
                // Look to see if Array is registered
                if(!__aControlled_models)
                        __aControlled_models = new Array();
                // Look to is ID is free       
                if (!__aControlled_models[id]){
                        __aControlled_models[id] = model;
                        return true;
                }else{
                        trace(‘BaseController Error: id "’+id+‘" already exists’);
                        return false;
                }
        }
       
        /**
         * This Pass data off directly to Model.
         * @param id: ID used to look up Model being controlled.
         * @param event: An event wrapped in an object to be passed back to the linked Model.
         * @param special_method: Default method called on Model is "receive_event", this can be any method name that is set up to receive a event as a parameter.
         * @return Boolean: True for successful look up of model, false if ID is not valid and model couldn’t be found.
         * @example 1:(Default method call)
         *           var bEvent_success:Boolean = BaseController.new_event("Model_Name",{type:’event_type’,action:’load_site’};
         *           // Extra step to verify event was sent
         *           if(bEvent_success)
         *                trace("Event was sent");
         *           else
         *                trace("Event Failed");
         *           
         * @example 2: (Use special method param to call public method of a model, in this example the model has the method Model.load_site() that will be called)
         *           BaseController.new_event("Model_Name",{type:’event_type’,action:’load’,'load_site’};
         */

        public static function new_event(id:String, event:Object, special_method:String):Boolean {
                //trace("BaseController.new_event(id, event, special_method)");
                if (__aControlled_models[id]){
                        // Look for a sepcial method to use, if not supply default method
                        if (!special_method)
                                special_method = “receive_event”;
                        // Call method on Model and pass in event
                        __aControlled_models[id][special_method](event);
                        return true;
                }else{
                        // Error happens when no model is found with supplied ID
                        trace(‘BaseController Error: id "’+id+‘" does not exist’);
                        return false;
                }
        }

}

I really spent a lot of time commenting the crap out of this because it is a simple class by nature. So with that in mind I will try to touch on the core functionality of the class and what it does instead of usage or examples.

At the heart of the class is an associate array called __aControlled_models. This array keeps track of all the models the controller can broadcast to. When a BaseModel gets created it automatically calls the model_to_control and passes its’ name and scope. The controller stores that 1 to 1 relationship and uses it later when an event is sent.

An event is simply a dynamically created object that should always have a type property. Everything else is optional. Now seeing how the AS 3.0 event system works, I would probably have created an event class to help with typing. For what its worth, this plays nicely and since the goal is to keep the system as open and customizable as possible there isn’t much more that can be done.

So when a model or view, or anything for that matter, needs to send out an event, it can call the new_event() method. This method looks for the Class’s id, the event, and a special 3rd parameter called special_method. Take a look at this code:

// Look for a special method to use, if not supply default method
        if (!special_method)
                special_method = “receive_event”;
        // Call method on Model and pass in event
        __aControlled_models[id][special_method](event);

When this method is normally called and you don’t pass in a special_method you get the default “receive_event” method on the receiving Class. Great, but the real power is that you can now call ANY method on any class through the controller. This is really crazy and probably breaks every rule of MVC and OOP but sometimes in Flash you just need to trigger something and not go through the hoops. I don’t normally ever use this extra option but you never know, it may come in handy for you.

That was painless. This controller can easily be taken out of the MCVC system and used in any project. As long as you correctly register your classes with the controller you can begin to remove yourself from Flash’s built in event system and regain control! Check out the BaseView.

One Response to “MCVC Controller - Part 3”

  1. The Flash Art of War » Blog Archive » Are Singletons Bad? Says:

    [...] needed to get the project out the door. In fact, my own MCVC framework made use of a Singleton like Controller class accessible from all Models and Views in the system. This basically was my way of not using global [...]

Leave a Reply