Quellcode durchsuchen

proper cleanup (not yet for textures) + interactive events management

git-svn-id: https://svn.shirogames.com/evoland1/lib@13 9d342a87-36e0-4458-8f1b-22e0acdbfa51
ncannasse vor 13 Jahren
Ursprung
Commit
b87a96535f
10 geänderte Dateien mit 236 neuen und 21 gelöschten Zeilen
  1. 8 0
      h2d/CachedBitmap.hx
  2. 21 0
      h2d/Event.hx
  3. 12 4
      h2d/Graphics.hx
  4. 0 4
      h2d/HtmlText.hx
  5. 55 0
      h2d/Interactive.hx
  6. 109 0
      h2d/Scene.hx
  7. 27 7
      h2d/Sprite.hx
  8. 0 4
      h2d/SpriteBatch.hx
  9. 2 1
      h2d/TileColorGroup.hx
  10. 2 1
      h2d/TileGroup.hx

+ 8 - 0
h2d/CachedBitmap.hx

@@ -42,6 +42,14 @@ class CachedBitmap extends Sprite {
 		this.height = height;
 	}
 	
+	override function onDelete() {
+		if( tex != null ) {
+			tex.dispose();
+			tex = null;
+		}
+		super.onDelete();
+	}
+	
 	function set_width(w) {
 		if( tex != null ) {
 			tex.dispose();

+ 21 - 0
h2d/Event.hx

@@ -0,0 +1,21 @@
+package h2d;
+
+enum EventKind {
+	EPush;
+	ERelease;
+	EMove;
+}
+
+class Event {
+
+	public var kind : EventKind;
+	public var relX : Float;
+	public var relY : Float;
+	
+	public function new(k,x=0.,y=0.) {
+		kind = k;
+		this.relX = x;
+		this.relY = y;
+	}
+	
+}

+ 12 - 4
h2d/Graphics.hx

@@ -34,15 +34,23 @@ class Graphics extends Sprite {
 		return (ctx = new GraphicsContext(this));
 	}
 	
+	override function onDelete() {
+		if( tile != null ) {
+			tile.tiles.dispose();
+			tile = null;
+		}
+		super.onDelete();
+	}
+	
 	public function endDraw() {
-		if( ctx == null )
-			return;
+		if( ctx == null ) return;
+		if( tile != null ) tile.tiles.dispose();
 		tile = Tiles.fromSprites([ctx.mc]).get(0);
-		ctx = null;
 	}
 	
 	override function draw(engine) {
-		if( ctx != null ) endDraw();
+		if( tile == null ) endDraw();
+		if( tile == null ) return;
 		Bitmap.drawTile(engine, this, tile, null);
 	}
 

+ 0 - 4
h2d/HtmlText.hx

@@ -16,10 +16,6 @@ class HtmlText extends Sprite {
 		textColor = 0xFFFFFF;
 	}
 	
-	override function onRemove() {
-		glyphs.onRemove();
-	}
-	
 	function set_htmlText(t) {
 		this.htmlText = t;
 		glyphs.reset();

+ 55 - 0
h2d/Interactive.hx

@@ -0,0 +1,55 @@
+package h2d;
+
+class Interactive extends Sprite {
+
+	public var width : Float;
+	public var height : Float;
+	public var useMouseHand : Bool;
+	var scene : Scene;
+	
+	public function new(width, height, ?parent) {
+		super(parent);
+		this.width = width;
+		this.height = height;
+		useMouseHand = true;
+	}
+
+	override function onAlloc() {
+		var p : Sprite = this;
+		while( p.parent != null )
+			p = p.parent;
+		if( Std.is(p, Scene) ) {
+			scene = cast p;
+			scene.addEventTarget(this);
+		}
+		super.onAlloc();
+	}
+	
+	override function onDelete() {
+		if( scene != null )
+			scene.removeEventTarget(this);
+		super.onDelete();
+	}
+	
+	@:allow(h2d.Scene)
+	function handleEvent( e : Event ) {
+		switch( e.kind ) {
+		case EMove:
+			onMove(e);
+		case EPush:
+			onPush(e);
+		case ERelease:
+			onRelease(e);
+		}
+	}
+	
+	public dynamic function onPush( e : Event ) {
+	}
+
+	public dynamic function onRelease( e : Event ) {
+	}
+	
+	public dynamic function onMove( e : Event ) {
+	}
+	
+}

+ 109 - 0
h2d/Scene.hx

@@ -5,9 +5,12 @@ class Scene extends Sprite {
 	public var width(default,null) : Int;
 	public var height(default,null) : Int;
 	var fixedSize : Bool;
+	var interactive : flash.Vector<Interactive>;
+	var pendingEvents : flash.Vector<Event>;
 	
 	public function new() {
 		super(null);
+		interactive = new flash.Vector();
 	}
 	
 	public function setFixedSize( w, h ) {
@@ -17,6 +20,105 @@ class Scene extends Sprite {
 		posChanged = true;
 	}
 
+	override function onDelete() {
+		var stage = flash.Lib.current.stage;
+		stage.removeEventListener(flash.events.MouseEvent.MOUSE_DOWN, onMouseDown);
+		stage.removeEventListener(flash.events.MouseEvent.MOUSE_MOVE, onMouseMove);
+		stage.removeEventListener(flash.events.MouseEvent.MOUSE_UP, onMouseUp);
+		super.onDelete();
+	}
+	
+	override function onAlloc() {
+		var stage = flash.Lib.current.stage;
+		stage.addEventListener(flash.events.MouseEvent.MOUSE_DOWN, onMouseDown);
+		stage.addEventListener(flash.events.MouseEvent.MOUSE_MOVE, onMouseMove);
+		stage.addEventListener(flash.events.MouseEvent.MOUSE_UP, onMouseUp);
+		super.onAlloc();
+	}
+	
+	function onMouseDown(e:flash.events.MouseEvent) {
+		if( pendingEvents != null )
+			pendingEvents.push(new Event(EPush, e.localX, e.localY));
+	}
+
+	function onMouseUp(e:flash.events.MouseEvent) {
+		if( pendingEvents != null )
+			pendingEvents.push(new Event(ERelease, e.localX, e.localY));
+	}
+	
+	function onMouseMove(e:flash.events.MouseEvent) {
+		if( pendingEvents != null )
+			pendingEvents.push(new Event(EMove, e.localX, e.localY));
+	}
+	
+	function emitEvent( event : Event ) {
+		var x = event.relX, y = event.relY;
+		var rx = x * matA + y * matB + absX;
+		var ry = x * matC + y * matD + absY;
+		var r = height / width;
+		
+		for( i in interactive ) {
+			// this is a bit tricky since we are not in the not-euclide viewport space
+			// (r = ratio correction)
+			var dx = rx - i.absX;
+			var dy = ry - i.absY;
+			
+			var w1 = i.width * i.matA * r;
+			var h1 = i.width * i.matC;
+			var ky = h1 * dx - w1 * dy;
+			// up line
+			if( ky < 0 )
+				continue;
+				
+			var w2 = i.height * i.matB * r;
+			var h2 = i.height * i.matD;
+			var kx = w2 * dy - h2 * dx;
+				
+			// left line
+			if( kx < 0 )
+				continue;
+			
+			var max = h1 * w2 - w1 * h2;
+			// bottom/right
+			if( ky > max || kx * r > max )
+				continue;
+						
+			event.relX = (kx * r / max) * i.width;
+			event.relY = (ky / max) * i.height;
+			i.handleEvent(event);
+		}
+	}
+	
+	public function checkEvents() {
+		if( pendingEvents == null ) {
+			if( interactive.length == 0 )
+				return;
+			pendingEvents = new flash.Vector();
+		}
+		var old = pendingEvents;
+		if( old.length == 0 )
+			return;
+		pendingEvents = null;
+		for( e in old )
+			emitEvent(e);
+		if( interactive.length > 0 )
+			pendingEvents = new flash.Vector();
+	}
+	
+	@:allow(h2d)
+	function addEventTarget(i) {
+		interactive.push(i);
+	}
+	
+	@:allow(h2d)
+	function removeEventTarget(i) {
+		for( k in 0...interactive.length )
+			if( interactive[k] == i ) {
+				interactive.splice(k, 1);
+				break;
+			}
+	}
+
 	override function updatePos() {
 		// don't take the parent into account
 		if( !posChanged )
@@ -59,7 +161,14 @@ class Scene extends Sprite {
 		}
 	}
 	
+	public function dispose() {
+		if( allocated )
+			onDelete();
+	}
+	
 	override public function render( engine : h3d.Engine ) {
+		if( !allocated )
+			onAlloc();
 		if( !fixedSize && (width != engine.width || height != engine.height) ) {
 			width = engine.width;
 			height = engine.height;

+ 27 - 7
h2d/Sprite.hx

@@ -21,6 +21,7 @@ class Sprite {
 	var absY : Float;
 	
 	var posChanged : Bool;
+	var allocated : Bool;
 	
 	public function new( ?parent : Sprite ) {
 		matA = 1; matB = 0; matC = 0; matD = 1; absX = 0; absY = 0;
@@ -37,29 +38,48 @@ class Sprite {
 	}
 	
 	public function addChild( s : Sprite ) {
+		var p = this;
+		while( p != null ) {
+			if( p == s ) throw "Recursive addChild";
+			p = p.parent;
+		}
 		if( s.parent != null )
-			s.remove();
+			s.parent.childs.remove(s);
 		childs.push(s);
 		s.parent = this;
 		s.posChanged = true;
+		// ensure that proper alloc/delete is done if we change parent
+		if( allocated ) {
+			if( !s.allocated )
+				s.onAlloc();
+		} else if( s.allocated )
+			s.onDelete();
 	}
 	
+	// kept for internal init
+	function onAlloc() {
+		allocated = true;
+		for( c in childs )
+			c.onAlloc();
+	}
+		
 	// kept for internal cleanup
-	function onRemove() {
+	function onDelete() {
+		allocated = false;
+		for( c in childs )
+			c.onDelete();
 	}
 	
 	public function removeChild( s : Sprite ) {
 		if( childs.remove(s) ) {
 			s.parent = null;
-			s.onRemove();
+			if( s.allocated ) s.onDelete();
 		}
 	}
 	
+	// shortcut for parent.removeChild
 	public inline function remove() {
-		if( this != null && parent != null ) {
-			parent.removeChild(this);
-			onRemove();
-		}
+		if( this != null && parent != null ) parent.removeChild(this);
 	}
 	
 	function draw( engine : h3d.Engine ) {

+ 0 - 4
h2d/SpriteBatch.hx

@@ -67,10 +67,6 @@ class SpriteBatch extends Sprite {
 		material.blend(SrcAlpha, OneMinusSrcAlpha);
 	}
 	
-	override function onRemove() {
-		tmpBuf = null;
-	}
-	
 	public function alloc(t) {
 		var e = new BatchElement(this, t);
 		if( first == null )

+ 2 - 1
h2d/TileColorGroup.hx

@@ -117,8 +117,9 @@ class TileColorGroup extends Sprite {
 		content.reset();
 	}
 	
-	override function onRemove() {
+	override function onDelete() {
 		object.primitive.dispose();
+		super.onDelete();
 	}
 	
 	public function setColor( rgb : Int, alpha = 1.0 ) {

+ 2 - 1
h2d/TileGroup.hx

@@ -98,8 +98,9 @@ class TileGroup extends Sprite {
 		content.reset();
 	}
 	
-	override function onRemove() {
+	override function onDelete() {
 		object.primitive.dispose();
+		super.onDelete();
 	}
 	
 	public inline function add(x, y, t) {