Quellcode durchsuchen

added live update support in AIR (on by default in debug)

ncannasse vor 11 Jahren
Ursprung
Commit
ed3cf4ea1e
4 geänderte Dateien mit 97 neuen und 38 gelöschten Zeilen
  1. 10 8
      hxd/res/FileEntry.hx
  2. 12 0
      hxd/res/Image.hx
  3. 65 25
      hxd/res/LocalFileSystem.hx
  4. 10 5
      hxd/res/Resource.hx

+ 10 - 8
hxd/res/FileEntry.hx

@@ -1,33 +1,35 @@
 package hxd.res;
 
 class FileEntry {
-	
+
 	public var name(default, null) : String;
 	public var path(get, never) : String;
 	public var extension(get, never) : String;
 	public var size(get, never) : Int;
 	public var isDirectory(get, never) : Bool;
 	public var isAvailable(get, never) : Bool;
-	
+
 	// first four bytes of the file
 	public function getSign() : Int return 0;
-	
+
 	public function getBytes() : haxe.io.Bytes return null;
-	
+
 	public function open() { }
 	public function skip( nbytes : Int ) { }
 	public function readByte() : Int return 0;
 	public function read( out : haxe.io.Bytes, pos : Int, size : Int ) {}
 	public function close() {}
-	
+
 	public function load( ?onReady : Void -> Void ) : Void {}
-	public function loadBitmap( onLoaded : hxd.BitmapData -> Void ) : Void {}
+	public function loadBitmap( onLoaded : hxd.BitmapData -> Void ) : Void { }
+
+	public function watch( onChanged : Null<Void -> Void> ) { }
 
 	public function exists( name : String ) : Bool return false;
 	public function get( name : String ) : FileEntry return null;
-	
+
 	public function iterator() : hxd.impl.ArrayIterator<FileEntry> return null;
-	
+
 	function get_isAvailable() return true;
 	function get_isDirectory() return false;
 	function get_size() return 0;

+ 12 - 0
hxd/res/Image.hx

@@ -89,6 +89,16 @@ class Image extends Resource {
 		return bmp;
 	}
 
+	function watchCallb() {
+		var w = inf.width, h = inf.height;
+		inf = null;
+		var s = getSize();
+		if( w != s.width || h != s.height )
+			tex.resize(w, h);
+		tex.realloc = null;
+		loadTexture();
+	}
+
 	function loadTexture() {
 		if( inf.isPNG ) {
 			function load() {
@@ -100,6 +110,7 @@ class Image extends Resource {
 				tex.uploadPixels(pixels);
 				pixels.dispose();
 				tex.realloc = loadTexture;
+				watch(watchCallb);
 			}
 			if( entry.isAvailable )
 				load();
@@ -118,6 +129,7 @@ class Image extends Resource {
 					tex.uploadBitmap(bmp);
 				bmp.dispose();
 				tex.realloc = loadTexture;
+				watch(watchCallb);
 			});
 		}
 	}

+ 65 - 25
hxd/res/LocalFileSystem.hx

@@ -5,7 +5,7 @@ package hxd.res;
 @:allow(hxd.res.LocalFileSystem)
 @:access(hxd.res.LocalFileSystem)
 private class LocalEntry extends FileEntry {
-	
+
 	var fs : LocalFileSystem;
 	var relPath : String;
 	#if air3
@@ -24,9 +24,9 @@ private class LocalEntry extends FileEntry {
 		if( fs.createXBX && extension == "fbx" )
 			convertToXBX();
 	}
-	
+
 	static var INVALID_CHARS = ~/[^A-Za-z0-9_]/g;
-	
+
 	function convertToXBX() {
 		function getXBX() {
 			var fbx = null;
@@ -85,7 +85,7 @@ private class LocalEntry extends FileEntry {
 		return sys.io.File.getBytes(file);
 		#end
 	}
-	
+
 	override function open() {
 		#if air3
 		if( fread != null )
@@ -101,7 +101,7 @@ private class LocalEntry extends FileEntry {
 			fread = sys.io.File.read(file);
 		#end
 	}
-	
+
 	override function skip(nbytes:Int) {
 		#if air3
 		fread.position += nbytes;
@@ -109,7 +109,7 @@ private class LocalEntry extends FileEntry {
 		fread.seek(nbytes, SeekCur);
 		#end
 	}
-	
+
 	override function readByte() {
 		#if air3
 		return fread.readUnsignedByte();
@@ -117,7 +117,7 @@ private class LocalEntry extends FileEntry {
 		return fread.readByte();
 		#end
 	}
-	
+
 	override function read( out : haxe.io.Bytes, pos : Int, size : Int ) : Void {
 		#if air3
 		fread.readBytes(out.getData(), pos, size);
@@ -139,7 +139,7 @@ private class LocalEntry extends FileEntry {
 		}
 		#end
 	}
-	
+
 	override function get_isDirectory() {
 		#if air3
 		return file.isDirectory;
@@ -148,7 +148,7 @@ private class LocalEntry extends FileEntry {
 		return false;
 		#end
 	}
-	
+
 	override function load( ?onReady : Void -> Void ) : Void {
 		#if air3
 		if( onReady != null ) haxe.Timer.delay(onReady, 1);
@@ -156,7 +156,7 @@ private class LocalEntry extends FileEntry {
 		throw "TODO";
 		#end
 	}
-	
+
 	override function loadBitmap( onLoaded : hxd.BitmapData -> Void ) : Void {
 		#if flash
 		var loader = new flash.display.Loader();
@@ -173,19 +173,19 @@ private class LocalEntry extends FileEntry {
 		throw "TODO";
 		#end
 	}
-	
+
 	override function get_path() {
 		return relPath == null ? "<root>" : relPath;
 	}
-	
+
 	override function exists( name : String ) {
 		return fs.exists(relPath == null ? name : relPath + "/" + name);
 	}
-	
+
 	override function get( name : String ) {
 		return fs.get(relPath == null ? name : relPath + "/" + name);
 	}
-	
+
 	override function get_size() {
 		#if air3
 		return Std.int(file.size);
@@ -218,16 +218,56 @@ private class LocalEntry extends FileEntry {
 		return new hxd.impl.ArrayIterator(arr);
 		#end
 	}
-	
+
+	#if air3
+
+	var watchCallback : Void -> Void;
+	var watchTime : Float;
+	static var WATCH_LIST : Array<LocalEntry> = null;
+
+	static function checkFiles(_) {
+		for( w in WATCH_LIST ) {
+			var t = try w.file.modificationDate.getTime() catch( e : Dynamic ) -1;
+			if( t != w.watchTime ) {
+				// check we can read (might be deleted/renamed/currently writing)
+				try { w.close(); w.open(); w.close(); } catch( e : Dynamic ) continue;
+				w.watchTime = t;
+				w.watchCallback();
+			}
+		}
+	}
+
+	override function watch( onChanged : Null < Void -> Void > ) {
+		if( onChanged == null ) {
+			if( watchCallback != null ) {
+				WATCH_LIST.remove(this);
+				watchCallback = null;
+			}
+			return;
+		}
+		if( watchCallback == null ) {
+			if( WATCH_LIST == null ) {
+				WATCH_LIST = [];
+				flash.Lib.current.stage.addEventListener(flash.events.Event.ENTER_FRAME, checkFiles);
+			}
+			WATCH_LIST.push(this);
+		}
+		watchTime = file.modificationDate.getTime();
+		watchCallback = onChanged;
+		return;
+	}
+
+	#end
+
 }
 
 class LocalFileSystem implements FileSystem {
-	
+
 	var root : FileEntry;
 	public var baseDir(default,null) : String;
 	public var createXBX : Bool;
 	public var tmpDir : String;
-	
+
 	public function new( dir : String ) {
 		baseDir = dir;
 		#if air3
@@ -248,11 +288,11 @@ class LocalFileSystem implements FileSystem {
 		#end
 		tmpDir = baseDir + ".tmp/";
 	}
-	
+
 	public dynamic function xbxFilter( entry : FileEntry, fbx : h3d.fbx.Data.FbxNode ) : h3d.fbx.Data.FbxNode {
 		return fbx;
 	}
-	
+
 	public function getRoot() : FileEntry {
 		return root;
 	}
@@ -272,7 +312,7 @@ class LocalFileSystem implements FileSystem {
 		return f;
 		#end
 	}
-	
+
 	public function exists( path : String ) {
 		#if air3
 		var f = open(path);
@@ -282,7 +322,7 @@ class LocalFileSystem implements FileSystem {
 		return f != null && sys.FileSystem.exists(f);
 		#end
 	}
-	
+
 	public function get( path : String ) {
 		#if air3
 		var f = open(path);
@@ -296,7 +336,7 @@ class LocalFileSystem implements FileSystem {
 		return new LocalEntry(this, path.split("/").pop(), path, f);
 		#end
 	}
-	
+
 }
 
 #else
@@ -304,7 +344,7 @@ class LocalFileSystem implements FileSystem {
 class LocalFileSystem implements FileSystem {
 
 	public var baseDir(default,null) : String;
-	
+
 	public function new( dir : String ) {
 		#if flash
 		if( flash.system.Capabilities.playerType == "Desktop" )
@@ -312,11 +352,11 @@ class LocalFileSystem implements FileSystem {
 		#end
 		throw "Local file system is not supported for this platform";
 	}
-	
+
 	public function exists(path:String) {
 		return false;
 	}
-	
+
 	public function get(path:String) : FileEntry {
 		return null;
 	}

+ 10 - 5
hxd/res/Resource.hx

@@ -1,21 +1,26 @@
 package hxd.res;
 
 class Resource {
-	
+
+	public static var LIVE_UPDATE = #if debug true #else false #end;
+
 	public var name(get, never) : String;
 	public var entry(default,null) : FileEntry;
-	
+
 	public function new(entry) {
 		this.entry = entry;
 	}
-	
+
 	inline function get_name() {
 		return entry.name;
 	}
-	
+
 	function toString() {
 		return entry.path;
 	}
 
-	
+	public function watch( onChanged : Null < Void -> Void > ) {
+		if( LIVE_UPDATE	) entry.watch(onChanged);
+	}
+
 }