Merge Aether tools

This commit is contained in:
Joshua Granick
2014-09-30 17:41:39 -07:00
parent f1e3707ad9
commit 540aa48c39
272 changed files with 35574 additions and 127 deletions

View File

@@ -0,0 +1,187 @@
package helpers;
import haxe.ds.IntMap;
import haxe.ds.StringMap;
@:generic class ObjectHelper {
public static function copyFields<T> (source:T, destination:T):T {
for (field in Reflect.fields (source)) {
Reflect.setField (destination, field, Reflect.field (source, field));
}
return destination;
}
public static function copyFieldsPreferObjectOverValue<T> (source:T, destination:T):T {
for (field in Reflect.fields (source)) {
var do_copy = true;
var exists = Reflect.hasField( destination, field );
if( exists ) {
var value_source = Reflect.field (source, field);
var value_dest = Reflect.field (destination, field);
var type_source = Type.typeof(value_source).getName();
var type_dest = Type.typeof(value_dest).getName();
// if(LogHelper.verbose) {
// LogHelper.println(field + " / existed in dest as " + type_dest + " / " + type_source );
// }
//if trying to copy a non object over an object, don't
if(type_source != "TObject" && type_dest == "TObject") {
do_copy = false;
if(LogHelper.verbose) {
LogHelper.println(field + " not merged by preference" );
}
}
}
if(do_copy) {
Reflect.setField (destination, field, Reflect.field (source, field));
}
}
return destination;
}
public static function copyMissingFields<T> (source:T, destination:T):T {
for (field in Reflect.fields (source)) {
if (!Reflect.hasField (destination, field)) {
Reflect.setField (destination, field, Reflect.field (source, field));
}
}
return destination;
}
public static function copyUniqueFields<T> (source:T, destination:T, defaultInstance:T):T {
for (field in Reflect.fields (source)) {
var value = Reflect.field (source, field);
if (value != Reflect.field (defaultInstance, field)) {
Reflect.setField (destination, field, value);
}
}
return destination;
}
public static function deepCopy<T> (v:T):T {
if (!Reflect.isObject (v)) { // simple type
return v;
} else if (Std.is (v, String)) { // string
return v;
} else if (Std.is (v, Array)) { // array
var result = Type.createInstance (Type.getClass (v), []);
untyped {
for (ii in 0...v.length) {
result.push (deepCopy (v[ii]));
}
}
return result;
} else if (Std.is (v, StringMap)) { // hashmap
var result = Type.createInstance (Type.getClass(v), []);
untyped {
var keys:Iterator<String> = v.keys ();
for (key in keys) {
result.set (key, deepCopy (v.get (key)));
}
}
return result;
} else if (Std.is (v, IntMap)) { // integer-indexed hashmap
var result = Type.createInstance (Type.getClass (v), []);
untyped {
var keys:Iterator<Int> = v.keys ();
for (key in keys) {
result.set (key, deepCopy (v.get (key)));
}
}
return result;
} else if (Std.is (v, List)) { // list
//List would be copied just fine without this special case, but I want to avoid going recursive
var result = Type.createInstance (Type.getClass (v), []);
untyped {
var iter:Iterator<Dynamic> = v.iterator ();
for (ii in iter) {
result.add (ii);
}
}
return result;
} else if (Type.getClass(v) == null) { // anonymous object
var obj:Dynamic = {};
for (ff in Reflect.fields (v)) {
Reflect.setField (obj, ff, deepCopy (Reflect.field (v, ff)));
}
return obj;
} else { // class
var obj = Type.createEmptyInstance (Type.getClass (v));
for (ff in Reflect.fields (v)) {
Reflect.setField (obj, ff, deepCopy (Reflect.field (v, ff)));
}
return obj;
}
return null;
}
}