Browse Source

review error handling, added filetree rename in prefabs

ncannasse 7 years ago
parent
commit
02e2735bda

+ 1 - 0
bin/defaultProps.json

@@ -76,6 +76,7 @@
 		"h3d.shader.ColorAdd"],
 
 	// reserved for internal ide usage
+	"debug.displayErrors" : true,
 	"hide" : {}
 
 }

+ 55 - 4
hide/Ide.hx

@@ -364,8 +364,11 @@ class Ide {
 		return resourceDir+"/"+relPath;
 	}
 
+	var showErrors = true;
 	public function error( e : Dynamic ) {
-		js.Browser.alert(e);
+		if( showErrors && !js.Browser.window.confirm(e) )
+			showErrors = false;
+		js.Browser.console.error(e);
 	}
 
 	function get_projectDir() return ideProps.currentProject.split("\\").join("/");
@@ -406,6 +409,18 @@ class Ide {
 			}
 		}
 
+		if( props.project.get("debug.displayErrors")  ) {
+			js.Browser.window.onerror = function(msg, url, line, col, error) {
+				var e = error.stack;
+				e = ~/\(?chrome-extension:\/\/[a-z0-9\-\.\/]+.js:[0-9]+:[0-9]+\)?/g.replace(e,"");
+				e = ~/at ([A-Za-z0-9_\.\$]+)/g.map(e,function(r) { var path = r.matched(1); path = path.split("$hx_exports.").pop().split("$hxClasses.").pop(); return path; });
+				e = e.split("\t").join("    ");
+				this.error(e);
+				return true;
+			};
+		} else
+			Reflect.deleteField(js.Browser.window, "onerror");
+
 		waitScripts(function() {
 			var extraRenderers = props.current.get("renderers");
 			for( name in Reflect.fields(extraRenderers) ) {
@@ -538,17 +553,17 @@ class Ide {
 		return str;
 	}
 
-	public function loadPrefab<T:hide.prefab.Prefab>( file : String, cl : Class<T> ) : T {
+	public function loadPrefab<T:hide.prefab.Prefab>( file : String, ?cl : Class<T> ) : T {
 		if( file == null )
 			return null;
-		var l = new hxd.prefab.Library();
+		var l = hxd.prefab.Library.create(file.split(".").pop().toLowerCase());
 		try {
 			l.load(parseJSON(sys.io.File.getContent(getPath(file))));
 		} catch( e : Dynamic ) {
 			error("Invalid prefab ("+e+")");
 			throw e;
 		}
-		if( Std.is(l,cl) )
+		if( cl == null || Std.is(l,cl) )
 			return cast l;
 		return l.get(cl);
 	}
@@ -565,6 +580,42 @@ class Ide {
 		sys.io.File.saveContent(getPath(file), toJSON(content));
 	}
 
+	public function filterPrefabs( callb : hxd.prefab.Prefab -> Bool ) {
+		var exts = Lambda.array({iterator : @:privateAccess hxd.prefab.Library.registeredExtensions.keys });
+		exts.push("prefab");
+		var todo = [];
+		browseFiles(function(path) {
+			var ext = path.split(".").pop();
+			if( exts.indexOf(ext) < 0 ) return;
+			var prefab = loadPrefab(path);
+			var changed = false;
+			function filterRec(p) {
+				if( callb(p) ) changed = true;
+				for( ps in p.children )
+					filterRec(ps);
+			}
+			filterRec(prefab);
+			if( !changed ) return;
+			todo.push(function() sys.io.File.saveContent(getPath(path), toJSON(prefab.save())));
+		});
+		for( t in todo )
+			t();
+	}
+
+	function browseFiles( callb : String -> Void ) {
+		function browseRec(path) {
+			for( p in sys.FileSystem.readDirectory(resourceDir + "/" + path) ) {
+				var p = path == "" ? p : path + "/" + p;
+				if( sys.FileSystem.isDirectory(resourceDir+"/"+p) ) {
+					browseRec(p);
+					continue;
+				}
+				callb(p);
+			}
+		}
+		browseRec("");
+	}
+
 	function initMenu() {
 
 		if( subView != null ) return;

+ 0 - 1
hide/comp/SceneEditor.hx

@@ -125,7 +125,6 @@ class SceneEditor {
 		};
 
 		context = new hide.prefab.Context();
-		context.onError = function(e) ide.error(e);
 		context.shared = new hide.prefab.ContextShared(scene);
 		context.shared.currentPath = view.state.path;
 		context.init();

+ 4 - 0
hide/prefab/ContextShared.hx

@@ -13,6 +13,10 @@ class ContextShared extends hxd.prefab.ContextShared {
 		return scene;
 	}
 
+	override function onError( e : Dynamic ) {
+		hide.Ide.inst.error(e);
+	}
+
 	override function loadShader( path : String ) {
 		return hide.Ide.inst.shaderLoader.loadSharedShader(path);
 	}

+ 1 - 0
hide/prefab/HideProps.hx

@@ -7,4 +7,5 @@ typedef HideProps = {
 	@:optional dynamic function allowChildren( type : String ) : Bool;
 	@:optional dynamic function allowParent( p : Prefab ) : Bool;
 	@:optional dynamic function onChildUpdate( p : Prefab ) : Void;
+	@:optional dynamic function onResourceRenamed( map : (oldPath : String) -> String ) : Void;
 }

+ 10 - 1
hide/prefab/Material.hx

@@ -139,7 +139,16 @@ class Material extends Prefab {
 	}
 
 	override function getHideProps() : HideProps {
-		return { icon : "cog", name : "Material", allowParent : function(p) return p.to(Object3D) != null };
+		return {
+			icon : "cog",
+			name : "Material",
+			allowParent : function(p) return p.to(Object3D) != null,
+			onResourceRenamed : function(f) {
+				diffuseMap = f(diffuseMap);
+				normalMap = f(normalMap);
+				specularMap = f(specularMap);
+			},
+		};
 	}
 	#end
 

+ 3 - 2
hide/prefab/Model.hx

@@ -45,7 +45,7 @@ class Model extends Object3D {
 
 			return ctx;
 		} catch( e : Dynamic ) {
-			ctx.onError(e);
+			ctx.shared.onError(e);
 		}
 		ctx.local3d = new h3d.scene.Object(ctx.local3d);
 		ctx.local3d.name = name;
@@ -104,7 +104,8 @@ class Model extends Object3D {
 	override function getHideProps() : HideProps {
 		return {
 			icon : "cube", name : "Model", fileSource : ["fbx","hmd"],
-			allowChildren : function(t) return hxd.prefab.Library.isOfType(t,Object3D) || ["material", "shader"].indexOf(t) >= 0
+			allowChildren : function(t) return hxd.prefab.Library.isOfType(t,Object3D) || ["material", "shader"].indexOf(t) >= 0,
+			onResourceRenamed : function(f) animation = f(animation),
 		};
 	}
 	#end

+ 1 - 1
hide/prefab/Noise.hx

@@ -202,7 +202,7 @@ class Noise extends Prefab {
 					var data = cast(ctx.getContext(this).local2d, h2d.Bitmap).tile.getTexture().capturePixels().toPNG();
 					sys.io.File.saveBytes(f, data);
 				} catch( e : Dynamic ) {
-					js.Browser.alert(e);
+					ctx.ide.error(e);
 				}
 			});
 		});

+ 1 - 1
hide/prefab/l3d/Instance.hx

@@ -20,7 +20,7 @@ class Instance extends Object3D {
 				obj.name = name;
 				ctx.local3d.addChild(obj);
 			} catch( e : hxd.res.NotFound ) {
-				ctx.onError(e);
+				ctx.shared.onError(e);
 			}
 		}
 		else {

+ 39 - 0
hide/view/FileTree.hx

@@ -63,6 +63,7 @@ class FileTree extends FileView {
 		var panel = new Element("<div class='hide-scroll'>").appendTo(element);
 		tree = new hide.comp.IconTree(null,panel);
 		tree.async = true;
+		tree.allowRename = true;
 		tree.saveDisplayKey = "FileTree:" + getPath().split("\\").join("/").substr(0,-1);
 		tree.get = function(path) {
 			if( path == null ) path = "";
@@ -86,6 +87,44 @@ class FileTree extends FileView {
 			return content;
 		};
 
+		tree.onRename = function(path, name) {
+			var parts = path.split("/");
+			parts.pop();
+			for( n in name.split("/") ) {
+				if( n == ".." )
+					parts.pop();
+				else
+					parts.push(n);
+			}
+			var newPath = parts.join("/");
+			var isDir = sys.FileSystem.isDirectory(ide.getPath(path));
+			if( isDir )
+				throw "TODO : rename directory";
+			ide.filterPrefabs(function(p:hxd.prefab.Prefab) {
+				var changed = false;
+				function filter(p:String) {
+					if( p == null )
+						return null;
+					if( p == path ) {
+						changed = true;
+						return newPath;
+					}
+					if( isDir && StringTools.startsWith(p,path+"/") ) {
+						changed = true;
+						return newPath + p.substr(path.length, p.length - path.length);
+					}
+					return p;
+				}
+				p.source = filter(p.source);
+				var h = p.getHideProps();
+				if( h.onResourceRenamed != null )
+					h.onResourceRenamed(filter);
+				return changed;
+			});
+			sys.FileSystem.rename(ide.getPath(path), ide.getPath(newPath));
+			return true;
+		};
+
 		// prevent dummy mouseLeft from breaking our quickOpen feature
 		var mouseLeft = false;
 		var leftCount = 0;