Ver Fonte

added @:c for typed clone()

Nicolas Cannasse há 4 anos atrás
pai
commit
03350c2666

+ 1 - 1
hide/comp/SceneEditor.hx

@@ -1963,7 +1963,7 @@ class SceneEditor {
 		var undoes = [];
 		var newElements = [];
 		for(elt in elements) {
-			var clone = elt.clone();
+			var clone = elt.cloneData();
 			var index = elt.parent.children.indexOf(elt) + 1;
 			clone.parent = elt.parent;
 			elt.parent.children.remove(clone);

+ 48 - 9
hrt/impl/Macros.hx

@@ -7,16 +7,37 @@ class Macros {
 	#if macro
 	public static function buildPrefab() {
 		var fields = Context.getBuildFields();
-		var toSerialize = [];
+		var toSerialize = [], toCopy = [];
+		var isRoot = Context.getLocalClass().toString() == "hrt.prefab.Prefab";
+		var localType = haxe.macro.Tools.TTypeTools.toComplexType(Context.getLocalType());
+		var changed = false;
+
 		for( f in fields ) {
+			if( f.name == "copy" && !isRoot ) {
+				// inject auto cast to copy parameter
+				switch( f.kind ) {
+				case FFun(f) if( f.args.length == 1 && f.expr != null ):
+					var name = f.args[0].name;
+					var expr = f.expr;
+					f.expr = macro @:pos(f.expr.pos) { var $name : $localType = cast $i{name}; $expr; }
+					changed = true;
+				default:
+				}
+			}
 			if( f.meta == null ) continue;
-			for( m in f.meta )
-				if( m.name == ":s" )
+			for( m in f.meta ) {
+				switch( m.name ) {
+				case ":s":
 					toSerialize.push(f);
+				case ":c":
+					toCopy.push(f.name);
+				default:
+				}
+			}
 		}
-		if( toSerialize.length == 0 )
-			return null;
-		var ser = [], unser = [];
+		if( toSerialize.length + toCopy.length == 0 )
+			return changed ? fields : null;
+		var ser = [], unser = [], copy = [];
 		var pos = Context.currentPos();
 		for( f in toSerialize ) {
 			switch( f.kind ) {
@@ -52,14 +73,19 @@ class Macros {
 
 				ser.push(macro @:pos(pos) if( $serCond ) obj.$name = this.$name);
 				unser.push(macro @:pos(pos) this.$name = obj.$name == null ? $e : obj.$name);
+				copy.push(macro @:pos(pos) this.$name = p.$name);
 			default:
 				Context.error("Invalid serialization field", f.pos);
 			}
 		}
-		var isRoot = Context.getLocalClass().toString() == "hrt.prefab.Prefab";
+		for( name in toCopy ) {
+			copy.push(macro @:pos(pos) this.$name = p.$name);
+		}
 		if( !isRoot ) {
 			ser.unshift(macro @:pos(pos) super.saveSerializedFields(obj));
 			unser.unshift(macro @:pos(pos) super.loadSerializedFields(obj));
+			copy.unshift(macro @:pos(pos) var p : $localType = cast p);
+			copy.unshift(macro @:pos(pos) super.copySerializedFields(p));
 		}
 		function makeFun(name,block) : Field {
 			return {
@@ -74,8 +100,21 @@ class Macros {
 				pos : pos,
 			};
 		}
-		fields.push(makeFun("saveSerializedFields",ser));
-		fields.push(makeFun("loadSerializedFields",unser));
+		if( toSerialize.length > 0 ) {
+			fields.push(makeFun("saveSerializedFields",ser));
+			fields.push(makeFun("loadSerializedFields",unser));
+		}
+		fields.push({
+			name : "copySerializedFields",
+			kind : FFun({
+				ret : null,
+				expr : { expr : EBlock(copy), pos : pos },
+				args : [{ name : "p", type : macro : hrt.prefab.Prefab }],
+			}),
+			meta : [{ name : ":noCompletion", pos : pos }],
+			access : isRoot ? [] : [AOverride],
+			pos : pos,
+		});
 		return fields;
 	}
 	#end

+ 1 - 1
hrt/prefab/Curve.hx

@@ -33,7 +33,7 @@ class Curve extends Prefab {
 	@:s public var clampMin : Float = 0.;
 	@:s public var clampMax : Float = 0.;
 	@:s public var keyMode : CurveKeyMode = Linear;
-	public var keys : CurveKeys = [];
+	@:c public var keys : CurveKeys = [];
 
 	@:s public var loop : Bool = false;
 

+ 6 - 1
hrt/prefab/Light.hx

@@ -41,7 +41,7 @@ class Light extends Object3D {
 	@:s public var power : Float = 1.0;
 	@:s public var occlusionFactor = 0.0;
 	@:s public var isMainLight : Bool = false;
-	public var shadows : LightShadows = getShadowsDefault();
+	@:c public var shadows : LightShadows = getShadowsDefault();
 
 	// Point/Spot
 	@:s public var range : Float;
@@ -103,6 +103,11 @@ class Light extends Object3D {
 			shadows = getShadowsDefault();
 	}
 
+	override function copy(p:Prefab) {
+		super.copy(p);
+		shadows = copyValue(p.shadows);
+	}
+
 	override function applyTransform( o : h3d.scene.Object ) {
 		//super.applyTransform(o); // Disable scaling
 		o.x = x;

+ 1 - 1
hrt/prefab/Material.hx

@@ -11,7 +11,7 @@ class Material extends Prefab {
 	@:s public var normalMap : String;
 	@:s public var specularMap : String;
 	@:s public var materialName : String;
-	public var color : Array<Float> = [1,1,1,1];
+	@:c public var color : Array<Float> = [1,1,1,1];
 
 	public function new(?parent) {
 		super(parent);

+ 1 - 1
hrt/prefab/Object2D.hx

@@ -11,7 +11,7 @@ class Object2D extends Prefab {
 	@:s public var rotation : Float = 0.;
 
 	@:s public var visible : Bool = true;
-	public var blendMode : h2d.BlendMode = None;
+	@:c public var blendMode : h2d.BlendMode = None;
 
 	public function loadTransform(t) {
 		x = t.x;

+ 34 - 11
hrt/prefab/Prefab.hx

@@ -105,17 +105,25 @@ class Prefab {
 	/**
 		Override to implement your custom prefab data loading
 	**/
-	function load( v : Dynamic ) {
-		loadSerializedFields(v);
+	function load( obj : Dynamic ) {
+		loadSerializedFields(obj);
 	}
 
 	/**
 		Override to implement your custom prefab data saving
 	**/
 	function save() : {} {
-		var o = {};
-		saveSerializedFields(o);
-		return o;
+		var obj = {};
+		saveSerializedFields(obj);
+		return obj;
+	}
+
+	/**
+		Override to implement your custom prefab data copying.
+		You should copy the field from `p` to `this`, p being an instance of your class
+	**/
+	function copy( p : Prefab ) {
+		copySerializedFields(p);
 	}
 
 	/**
@@ -144,7 +152,7 @@ class Prefab {
 	/**
 		Save the whole prefab data and its children.
 	**/
-	@:final public function saveData() : {} {
+	public final function saveData() : {} {
 		var obj : Dynamic = save();
 		if( children.length > 0 )
 			obj.children = [for( s in children ) s.saveData()];
@@ -154,7 +162,7 @@ class Prefab {
 	/**
 		Load the whole prefab data and creates its children.
 	**/
-	@:final public function loadData( v : Dynamic ) {
+	public final function loadData( v : Dynamic ) {
 		load(v);
 		if( children.length > 0 )
 			children = [];
@@ -439,10 +447,25 @@ class Prefab {
 	}
 
 	/**
-		Clone this prefab, and all its children if recursive=true
+		Clone this prefab, and all its children if recursive=true.
+	**/
+	public final function clone( ?parent : Prefab, recursive = true ) : Prefab {
+		var obj = Type.createInstance(Type.getClass(this),[parent]);
+		obj.copy(this);
+		if( recursive ) {
+			for( c in children )
+				c.clone(obj);
+		}
+		return obj;
+	}
+
+	/**
+		Similar to clone() but uses full data copying to guarantee a whole copy with no data reference (but is slower).
 	**/
-	public function clone( recursive = true ) : Prefab {
-		var obj = recursive ? saveData() : save();
-		return loadPrefab(haxe.Json.parse(haxe.Json.stringify(obj)));
+	public final function cloneData( recursive = true ) {
+		var data = recursive ? saveData() : save();
+		data = haxe.Json.parse(haxe.Json.stringify(data));
+		return loadPrefab(data);
 	}
+
 }

+ 1 - 1
hrt/prefab/Unknown.hx

@@ -2,7 +2,7 @@ package hrt.prefab;
 
 class Unknown extends Prefab {
 
-	var data : Dynamic;
+	@:c var data : Dynamic;
 
 	public function getPrefabType() {
 		return data.type;

+ 3 - 3
hrt/prefab/fx/BaseFX.hx

@@ -59,9 +59,9 @@ typedef ObjectAnimation = {
 class BaseFX extends hrt.prefab.Library {
 
 	@:s public var duration : Float;
-	public var scriptCode : String;
-	public var cullingRadius : Float;
-	public var markers : Array<{t: Float}> = [];
+	@:c public var scriptCode : String;
+	@:c public var cullingRadius : Float;
+	@:c public var markers : Array<{t: Float}> = [];
 
 	public function new() {
 		super();

+ 1 - 1
hrt/prefab/l3d/Decal.hx

@@ -22,7 +22,7 @@ class Decal extends Object3D {
 	@:s var renderMode : DecalMode = Default;
 	@:s var centered : Bool = true;
 	@:s var autoAlpha : Bool = true;
-	var blendMode : h2d.BlendMode = Alpha;
+	@:c var blendMode : h2d.BlendMode = Alpha;
 
 	override function save() {
 		var obj : Dynamic = super.save();

+ 1 - 1
hrt/prefab/l3d/HeightMap.hx

@@ -361,7 +361,7 @@ class HeightMapMesh extends h3d.scene.Object {
 class HeightMap extends Object3D {
 
 	var tilesCache : Map<Int,HeightMapTile> = new Map();
-	var textures : Array<{ path : String, kind : HeightMapTextureKind, enable : Bool }> = [];
+	@:c var textures : Array<{ path : String, kind : HeightMapTextureKind, enable : Bool }> = [];
 	@:s var size = 128.;
 	@:s var heightScale = 0.2;
 	@:s var normalScale = 1.;

+ 1 - 1
hrt/prefab/l3d/MeshGenerator.hx

@@ -111,7 +111,7 @@ class MeshGeneratorRoot extends h3d.scene.Object {
 
 class MeshGenerator extends Object3D {
 
-	public var root : MeshPart;
+	@:c public var root : MeshPart;
 
 	#if editor
 	static var filterInit = false;

+ 2 - 2
hrt/prefab/l3d/Polygon.hx

@@ -13,8 +13,8 @@ typedef PrimCache = Map<Shape, h3d.prim.Polygon>;
 
 class Polygon extends Object3D {
 
-	public var shape(default, null) : Shape = Quad(0);
-	public var points : h2d.col.Polygon;
+	@:c public var shape(default, null) : Shape = Quad(0);
+	@:c public var points : h2d.col.Polygon;
 	@:s public var color : Int = 0xFFFFFFFF;
 	#if editor
 	public var editor : hide.prefab.PolygonEditor;

+ 2 - 2
hrt/prefab/l3d/Spline.hx

@@ -63,14 +63,14 @@ class SplinePoint extends h3d.scene.Object {
 class Spline extends Object3D {
 
 	public var points : Array<SplinePoint> = [];
-	public var shape : CurveShape = Quadratic;
+	@:c public var shape : CurveShape = Quadratic;
 
 	var data : SplineData;
 	@:s var step : Float = 1.0;
 	@:s var threshold : Float = 0.01;
 
 	// Save/Load the curve as an array of absPos
-	public var pointsData : Array<h3d.Matrix> = [];
+	@:c public var pointsData : Array<h3d.Matrix> = [];
 
 	// Graphic
 	@:s public var showSpline : Bool = true;

+ 2 - 2
hrt/prefab/l3d/SplineMesh.hx

@@ -111,8 +111,8 @@ class SplineMesh extends Spline {
 	@:s var splineUVy : Bool = false;
 
 	@:s var spacing: Float = 0.0;
-	var meshScale = new h3d.Vector(1,1,1);
-	var meshRotation = new h3d.Vector(0,0,0);
+	@:c var meshScale = new h3d.Vector(1,1,1);
+	@:c var meshRotation = new h3d.Vector(0,0,0);
 	var modelMat = new h3d.Matrix();
 
 	var meshBatch : SplineMeshBatch = null;

+ 3 - 3
hrt/prefab/terrain/Terrain.hx

@@ -35,10 +35,10 @@ class Terrain extends Object3D {
 	// Shadows Param
 	@:s public var castShadows = false;
 	// Data for binary save/load
-	var surfaceCount = 0;
-	var surfaceSize = 0;
+	@:c var surfaceCount = 0;
+	@:c var surfaceSize = 0;
 	// Utility
-	var tmpSurfacesProps : Array<SurfaceProps> = [];
+	@:c var tmpSurfacesProps : Array<SurfaceProps> = [];
 	var unpackWeight = new h3d.pass.ScreenFx(new UnpackWeight());
 	var modified = false;
 

+ 2 - 2
hrt/prefab/vlm/VolumetricLightmap.hx

@@ -15,7 +15,7 @@ class VolumetricLightmap extends Object3D {
 	var useGPU = true;
 
 	#if editor
-	var displaySH_field = false;
+	@:c var displaySH_field = false;
 	var maxOrderBaked = 0;
 	var baker : hide.view.l3d.ProbeBakerProcess;
 	#end
@@ -281,7 +281,7 @@ class VolumetricLightmap extends Object3D {
 			trace("Invalid renderer");
 
 		var sceneData = @:privateAccess ctx.scene.editor.sceneData;
-		baker.init(pbrRenderer.env, sceneData.clone(), cast ctx.rootContext.shared, ctx.scene);
+		baker.init(pbrRenderer.env, sceneData.cloneData(), cast ctx.rootContext.shared, ctx.scene);
 
 		baker.onEnd = function() {
 			if( onEnd != null ) onEnd();