Hello community,
I am trying to abstract the rendering part in my application and seem not to find a good pattern. So I thought maybe someone could help me with some tipps. So here is how I tried to tackle that so far:
For example I wanted to write a Picutre Gallery where you can Swipe through some picures. So I have a Gallery class which takes items of type "Picture". So lets try to abstract "Picture". Lets say I target flash and js. I could define typedefs with conditional compiler arguments:
package gallery;
class Gallery {
function addPic(picture: gallery.typedefs.DisplayObject){...}
}
package gallery.typedefs;
#if flash
typedef DisplayObject = flash.display.DisplayObject;
#else
typedef DisplayObject = {x: Float, y: Float};
Thats not so great already.. because I have to put the typedef definition somewhere with my "Gallery" library. So that means if somebody wants to use my Gallery Library and wants to add another target it is required to add that to the "gallery.typedefs" package. As far as I can see there is no way to have it outside.
But ok.. so be it. To the next problem.
So, we still need a renderer for js. Let's implement pixijs. Guess if I want to get that in my typedefs I have to add a compiler condition (like "-D pixi"). That could look like that then:
package gallery.typedefs;
#if flash
typedef DisplayObject = flash.display.DisplayObject;
#elseif pixi
typedef DisplayObject = pixi.core.display.DisplayObject;
#else
typedef DisplayObject = {x: Float, y: Float};
but actually that does not work. Pixis DisplayObject does not have object.x. Instead it has object.position.x.
Alright.. but there is this great haxe feature called "Abstracts". Let's try and use that:
...
#elseif pixi
abstract DisplayObject(pixi.core.display.DisplayObject) {
public var x(get, set): Float;
public function get_x(): Float { return this.position.x}
public function set_x(value: Float) {
return this.position.x = value;
}
...
}
...
Looks good.. but actually isn't.. because it does not work either. Because if I do:
gallery.addPic(new pixi.core.sprites.Sprite(texture));
I get a compiler error that addPic() expects and instance of gallery.typedefs.DisplayObject.
That is to bad.. because I would have expected that the abstract becomes pixi.core.display.DisplayObject, and since pixi.core.sprite.Sprite is inheriting from that class it should work. So it seems abstracts are not aware of inheritance?
So in the end all this means the only way I can find to abstract this stuff is to do it like in the old days: use an Interface and write wrapper classes which acts as a mediator or extend the plattform specific classes and implement that interface. Also not so nice, because that adds a bit of runtime overhead. But I can not come up with something better.
I thought maybe there is something I am missing.. maybe somebody have some hints or suggestions? Maybe there is a macro for that?
Cheers