Fake enums

26 10 2010

The more I write ActionScript code the more I want to write C++ code. Partially because I like C++ and partially because I dislike ActionScript I guess. In many ways, and probably a whole topic in and of itself, the enjoyment and usage of a programming language is highly subjective. But it isn’t the topic of this post.

ActionScript 3.0 doesn’t support the notion of built-in enumerated values. Otherwise known as enums by those with a panache for shortening words. The thing about enums is that, well, they are really really useful to have around when we want to limit the input range of a given function or container. Enums give us an even further advantage though in the sense that they not only provide a controlling mechanism but also an associative relationship between a symbol and its representation in the system. A simple example in C++.

enum StateType
{
  IN_GAME = 0,
  IN_MENU = 1,
  IN_TRANSITION_OUT = 2,
  IN_TRANSITION_IN = 3,
};

In this case we can define another variable in the main game class which holds a current state [not the best solution but a simple and viable one nonetheless].

StateType mCurrentState = StateType::IN_MENU;

mCurrentState can now only hold those values specified by the StateType enum. And not only that but each particular value has a meaningful name. Very useful and, unfortunetly, non-existant in ActionScript 3.0. So I finally gave up and decided to hack something together. It’s a bit ungainly as a solution but it’s a neccessary evil for now.

The other tactic one can employ in this situation, by the way, is to simply create a few static constants and pass them around as unsigned/signed integers. Good but not quite what I want although it is a part of my solution. This Type class is designed to define a few buttons on the main menu and make sure we can’t accidently choose a funny button.

public class ButtonType
{
  public static const BUTTON_01:uint = 0;
  public static const BUTTON_02:uint = 1;
  public static const BUTTON_03:uint = 2;
  public static const BUTTON_04:uint = 3;

  public static function CheckValid(_value:uint):void
  {
    switch (_value)
    {
      case SHARK_ISLAND:
      case SEVEN_CITIES:
      case UNKNOWN_BOOK:
      case INSTRUCTIONS: break;
      default: { throw Error("Unrecognized button type"); }
    }
  }  
  public function get value():uint { return mValue; }
  public function set value(_value:uint):void
  {
    CheckValid(_value);
    mValue = _value;
  }
	
  public function ButtonType(_type:uint)
  { 
    this.value = _type;
  }

  /*PRIVATE DATA*/
  private var mValue:uint = 0;
}

Why go through all the trouble of writing a different class instead of just encoding the static constants into the main menu class? My reasons are as follow:

  1. Because it means the MainMenu will have one less responsiblity to take care of [validity check].
  2. Code is now localized. So all code changes to button types [adding/removing types] and their validity checking would only occur in one place.
  3. Other classes which only use the button types don’t need to have knowledge of the entire MainMenu class [ie. import it]

Any better ideas out there?

“And every time she sneezes I believe it’s love and, oh lord, I’m not ready for this sort of thing…”

Advertisements

Actions

Information

2 responses

26 10 2010
Tatham

This method works, but it’s not type-checked at compile time. Which can lead to some annoying exceptions because, later down the line, you forget to initialise an enum properly.
A good solution is to actually use instances of your class as the static constant variables instead of uints, use a copy constructor as the only way to initialise, and then the compiler will handle the CheckValid functionality for you.
Here’s a good example: http://www.liranuna.com/typesafe-assignable-enumerations-in-as3/
I also recommend making your constructor private so that you can’t accidentally construct an Enum that’s not initialised. AS3 doesn’t do private constructors, so you’ll have to hack it using this trick: http://www.berniecode.com/blog/2007/11/28/proper-private-constructors-for-actionscript-30/
Then to finish it off you can write your own toString() and toUint() methods, which in AS3 are probably a better idea than implicit conversions for enums

27 10 2010
shattenyagger

Thanks, it’s an interesting read and a cool idea. I don’t really like to hack too much unless I have to [which is why I chose the easy way out :P].

The enum method in your first link is good but I wanted to also associate my enums with integers since it gives me the ability to use them for boolean bit logic. I suspect a better solution for me would probably be to combine the two methods and have the constructor

public function Direction(_d:Direction, _value:int)

If only ActionScript allowed operator overloading and some better control for implicit conversions.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: