Keith
Keith

Reputation: 4204

Should I be using direct function calls instead of event handlers here?

I'm working in Actionscript3, building a MMO-like game, I'm in charge of the UI, among other things. I use Events for a lot of my workflow, but my partner was suggesting that I use direct function calls for my UI assets instead. Here's an example:

  1. I created a ColorChooser class that we're using to re-color parts of a user's avatar.
  2. When you click on a color, the ColorChooser reads the pixel (of a color spectrum image) clicked and dispatches an event (ColorChooser.COLOR_CHOSEN).
  3. My AvatarDesigner class is listening for this event.
  4. When the event gets dispatched, the handler event in AvatarDesigner reads (e.target as ColorChooser).chosenColor and applies that color to the selected part of the avatar.

My partner was suggesting that instead I:

  1. Give ColorChooser the instance of its parent AvatarDesigner object (_avatarDesigner).
  2. When a color is clicked, read the pixel clicked (var chosenColor:uint) and call _avatarDesigner.colorAvatar(chosenColor) from within the ColorChooser object.

Now, with most of my UI I'm using events so that I can keep assets like dropdown menus, buttons, textareas separate and re-usable. I imagine that we'll re-use this ColorChooser object for other things (ObjectDesigner, WallpaperDesigner, BuildingDesigner). He said that it'd be better to add a condition within ColorChooser each time I use it for something else, so perhaps like:

private function colorClicked(e:MouseEvent):void {
    var chosenColor:uint = *the color chosen (bitmapdata.getpixel());*
    switch(parent){
        case AvatarDesigner:    (parent as AvatarDesigner).colorChosen(chosenColor); 
                                break;
        case ObjectDesigner:    (parent as ObjectDesigner).colorChosen(chosenColor); 
                                break;
        case WallpaperDesigner: (parent as WallpaperDesigner).colorChosen(chosenColor); 
                                break;
        case BuildingDesigner:  (parent as BuildingDesigner).colorChosen(chosenColor); 
                                break;
    }
}

Or something like that (maybe instead of checking parent, checking a string "type" in the constructor or something). This seems strange to me since I'd have to go back in and add a case each time it's used somewhere else. Whereas with events it can fire off it's event and have it handled or not handled regardless of what its parent is. Some of his reasoning is:

Whereas I feel that events are appropriate for reasons such as:

Can anyone shine some light on this? Could it possibly be worth hard-coding in a new logic condition in, say, "ShinyButton" every time I use this asset in a different type of parent? Even if events and listeners are using CPU, wouldn't adding conditions like this make it a bit spaghetti-ish?

Also, for the life of me I can't find an Actionscript3 best practices for when Events are good or bad, and why. Also, I'd love if any knows how Events are used on the low-level.

Thanks for reading!

Upvotes: 0

Views: 339

Answers (2)

net.uk.sweet
net.uk.sweet

Reputation: 12431

Short answer, I think you are right and your friend is wrong. Any perceived performance gains (if any) will be negligible and the tight-coupling introduced will, as you anticipate correctly, make it difficult to reuse your component in other situations and make your project more difficult to maintain as a whole.

ActionScript is an event-based asynchronous language and you'll be doing your friend a favour if you encourage him to embrace it rather than fight it!

To answer your question about best-practices for ActionScript 3.0 development, I think you could do worse than look at the structure of some of the components of the Flex framework. These were developed by Adobe engineers and, as such, can be considered a demonstration of what is considered best-practice. You'll find heavy use of events to avoid tight-coupling between different components or component actors and minimal use of the sort of smelly code your friend is suggesting.

Upvotes: 1

Pag
Pag

Reputation: 31

I think that your different opinions are based on habits more than real reasons.

I would personnaly use the personnal event model which is the most open and flexible solution I have in mind.

But if you want to use callback functions with no need to go back to your ColorChooser, you can create an Interface like IColorReceiver with a required method called something like applyColor(color:Color){}; (Speaking of programming best practices, you should be aware that method names are clearer with verbs like "applyColor" or "choseColor" instead of adjectives or names like "colorChosen" which doen't means lot)

Then in your colorPicked(e:MouseEvent){} method you make sure that parent implements IColorReceiver, and you call applyColor(chosenColor); with no other test than the one with IColorReceiver. It could also work with classic inheritance but require more code for less flexibility.

I do not provide code, but you seem to have a reasonable level so I'm confident. ;)

(hope my english is correct)

Upvotes: 3

Related Questions