Getters and setters work differently when targeting Flash than when targeting anything else. Normally, you’d use (get, set)
, and then you’d define the corresponding getters and setters.
public var width(get, set):Float;
//...
private function get_width():Float {
return _width;
}
private function set_width(value:Float):Float {
return _width = value;
}
When the compiler sees (get, set)
after “width,” it looks for corresponding get_width
and set_width
methods. Then if you say “width = width + 1
,” the compiler replaces that with “set_width(get_width() + 1)
.”
Haxe-style getters and setters work on any target, even Flash. So what’s the problem? Shouldn’t your solution work?
Well, in this case, the compiler doesn’t see “(get, set)
” anywhere. The variable definition is just “var width:Float
,” with no access modifiers. It’s declared this way in Flash’s Sprite
class, which you can’t edit.
You can’t use Haxe-style getters or setters here, but fortunately, Flash provides an alternate version. Flash-style getters and setters happen at runtime, not compile time. Whenever you access a variable in Flash, it checks if there’s a relevant getter or setter. If there is, Flash uses that. So you can’t modify the Sprite
class itself, but you can add a getter for the width
variable, and then Flash will call your getter.
class MySprite extends Sprite {
@:getter(width)
private function get_width():Float {
return _width;
}
@:setter(width)
private function set_width(value:Float):Void {
_width = value;
}
}
The names of the functions are totally arbitrary. All you need is the right annotation, and the right function signature.
Speaking of function signatures, you’ll notice that get_width()
returned Float
in the Haxe example, but now it returns Void
. Haxe-style setters must return a value, and Flash-style setters aren’t allowed to return anything, and there’s no way around either of those.
That said, you can still make this work using #if flash
tags. This way, you can include a return
statement when compiling for most targets, but skip it in Flash. You can also remove “(get, set)
” in the Flash target.
#if flash
var width:Float;
#else
var width(get, set):Float;
#end
//...
@:getter(width)
private function get_width():Float {
return _width;
}
@:setter(width)
private function set_width(value:Float) {
_width = value;
#if !flash
return _width;
#end
}
I left the return value off of set_width()
so that Haxe would infer it. Usually, I recommend typing all of your variables and functions, but in this case it would require too much extra code.
This implementation is almost done. The one remaining thing you need to take into account is that you’re extending the Sprite
class, and the compiler will give you an error if you try to redefine the width
variable. Also, the non-Flash version of Sprite
already has get_width()
and get_height()
functions, so you need to add the override
keyword.
//#if flash
//var width:Float;
//#else
//var width(get, set):Float;
//#end
//...
#if flash @:getter(width) #else override #end
private function get_width():Float {
return _width;
}
#if flash @:setter(width) #else override #end
private function set_width(value:Float) {
_width = value;
#if !flash
return _width;
#end
}