Browse Source

allow resume/cleanup in case of out of memory on some common operations

ncannasse 10 years ago
parent
commit
2aa19724a9
4 changed files with 35 additions and 3 deletions
  1. 19 1
      hxd/impl/Tmp.hx
  2. 8 1
      hxd/res/Image.hx
  3. 5 1
      hxd/res/Loader.hx
  4. 3 0
      hxd/snd/Worker.hx

+ 19 - 1
hxd/impl/Tmp.hx

@@ -4,6 +4,9 @@ class Tmp {
 
 	static var bytes = new Array<haxe.io.Bytes>();
 
+	public static dynamic function outOfMemory() {
+	}
+
 	public static function getBytes( size : Int ) {
 		var found = -1;
 		for( i in 0...bytes.length ) {
@@ -18,7 +21,22 @@ class Tmp {
 		var sz = 1024;
 		while( sz < size )
 			sz = (sz * 3) >> 1;
-		return haxe.io.Bytes.alloc(sz);
+		return allocBytes(sz);
+	}
+
+	public static function freeMemory() {
+		bytes = [];
+		outOfMemory();
+	}
+
+	public static function allocBytes( size : Int ) {
+		try {
+			return haxe.io.Bytes.alloc(size);
+		} catch( e : Dynamic ) {
+			// out of memory
+			freeMemory();
+			return haxe.io.Bytes.alloc(size);
+		}
 	}
 
 	public static function saveBytes( b : haxe.io.Bytes ) {

+ 8 - 1
hxd/res/Image.hx

@@ -73,7 +73,14 @@ class Image extends Resource {
 			png.checkCRC = false;
 			pixels = Pixels.alloc(inf.width, inf.height, BGRA);
 			#if( format >= "3.1.3" )
-			format.png.Tools.extract32(png.read(), pixels.bytes, flipY);
+			var pdata = png.read();
+			try {
+				format.png.Tools.extract32(pdata, pixels.bytes, flipY);
+			} catch( e : Dynamic ) {
+				// most likely, out of memory
+				hxd.impl.Tmp.freeMemory();
+				format.png.Tools.extract32(pdata, pixels.bytes, flipY);
+			}
 			if( flipY ) pixels.flags.set(FlipY);
 			#else
 			format.png.Tools.extract32(png.read(), pixels.bytes);

+ 5 - 1
hxd/res/Loader.hx

@@ -16,6 +16,10 @@ class Loader {
 		cache = new Map<String,Dynamic>();
 	}
 
+	public function cleanCache() {
+		cache = new Map();
+	}
+
 	public function exists( path : String ) : Bool {
 		return fs.exists(path);
 	}
@@ -74,7 +78,7 @@ class Loader {
 	}
 
 	public function dispose() {
-		cache = new Map();
+		cleanCache();
 		fs.dispose();
 	}
 

+ 3 - 0
hxd/snd/Worker.hx

@@ -15,6 +15,7 @@ private enum Message {
 	StopAll;
 	Sync( dst : Int, src : Int );
 	Dispose;
+	Clean;
 }
 
 private class WorkerChannel extends NativeChannel {
@@ -193,6 +194,8 @@ class Worker extends hxd.Worker<Message> {
 		case Dispose:
 			stopAll();
 			hxd.res.Loader.currentInstance.dispose();
+		case Clean:
+			hxd.res.Loader.currentInstance.cleanCache();
 		}
 	}