20.10.12

Jeash StageQuality; Enum or String?

The last day's I've been playing with Haxe and NME without any specific goals. Now I'm starting to code myself a very basic library, similar to my AS3 one. But already after a few lines I encountered some problems regarding the stage setup for HTML.

In this post I'm going to write about a minor jeash specific type error "String should be StageQuality" I got while implementing the basic stage setup and its solution. Although its really simple I felt like sharing.

Setting up the stage to useful default values, like disabling scaling, setting alignment to top left and maybe even specifying the stage quality, are usually one of the first steps that are happening in my applications
Lib.current.stage.quality   = StageQuality.HIGH;
Lib.current.stage.align   = StageAlign.TOP_LEFT;
Lib.current.stage.scaleMode   = StageScaleMode.NO_SCALE;  
The example above works for all platforms, but in my case I do not assign the values directly but have them stored in a typed field and use them later to setup the stage.
package ;

import nme.display.Sprite;
import nme.display.StageQuality;
import nme.Lib;

class Main extends Sprite 
{
 private var quality:StageQuality;
 
 static public function main() { Lib.current.addChild( new Main() ); }
 public function new() 
 {
  super();
  
  this.quality = StageQuality.HIGH;  
  Lib.current.stage.quality = this.quality;
 }
}
This code compiles for flash, but failes for HTML with the following message:
src/Main.hx:16: characters 2-34 : String should be nme.display.StageQuality
src/Main.hx:16: characters 2-34 : String should be jeash.display.StageQuality
src/Main.hx:17: characters 2-42 : nme.display.StageQuality should be String
src/Main.hx:17: characters 2-42 : jeash.display.StageQuality should be String
So what is going wrong here? My field quality expects StageQuality as a type but gets a String and the stage property quality expects a String. Interessting enough, it same scenario works with StageAlign and StageScaleMode. It is also interessting to get the same type error twice but with different packages, but figured it must be because of the way NME uses typedef as aliases and the compiler works and choose to ignore it.

Solution:
I took a look into the source of those 3 classes and saw that jeash.display.StageQuality was different compared to StageAlign or StageScaleMode as it was not an enum like the others, but an ordinary class with static fields as its done in AS3. So in order to fix it I made jeash's StageQuality class an enum aswell and changed the type of jeash.display.Stage.quality from String to StageQuality.
package jeash.display;

/*class StageQuality
{
  public static var BEST = "best";
  public static var HIGH = "high";
  public static var MEDIUM = "medium";
  public static var LOW = "low";
}*/

enum StageQuality {
   BEST;
   HIGH;
   MEDIUM;
   LOW;
}
I previously tried to solve it by using @:fakeEnum(Type), because I didn't want to change the interface of StageQuality or Stage and thought for some reason that this could work. But it doesn't for at least two reasons:
  • As far as I understand you cannot specify a specific value for each enum entry and the @fakeEnum(Type) compiler instruction uses the fieldname when type is String and the index when type is Int. So it would replace it with "BEST", "HIGH"; and that might cause some problems.
  • Even more important: the instruction does not alter the type in any way so it is still an enum and not a String. So you would not get rid of the type error anyway. fakeEnum just alters the way the comparision works.
So my take away from this simple type error is that I shouldn't slam haxe features on issues just because I'd like to code some witty haxe magic. But I learned a bit about how enums work and got a glimpse into NME and that's cool.

I just hope my change in the jeash source does not cause any unwanted side effects. x)

No comments:

Post a Comment