Skip to content

Commit 503ff87

Browse files
committed
Add property parsing and cloning property values
1 parent bcde8c8 commit 503ff87

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed

source/funkin/backend/utils/CoolUtil.hx

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,124 @@ class CoolUtil
865865

866866
return result.join(seperator);
867867
}
868+
869+
public inline static function parsePropertyString(fieldPath:String):Array<OneOfTwo<String, Int>> {
870+
return FlxTween.parseFieldString(fieldPath);
871+
}
872+
873+
function stringifyFieldsPath(fields:Array<OneOfTwo<String, Int>>):String {
874+
var str = new StringBuf();
875+
var first = true;
876+
for (field in fields) {
877+
if (Type.typeof(field) == TInt) {
878+
str.add('[${field}]');
879+
} else {
880+
if (!first)
881+
str.add('.');
882+
str.add(field);
883+
}
884+
first = false;
885+
}
886+
return str.toString();
887+
}
888+
889+
public static function parseProperty(target:Dynamic, fields:OneOfTwo<String, Array<OneOfTwo<String, Int>>>):Dynamic {
890+
var fields:Array<OneOfTwo<String, Int>> = {
891+
if((fields is String)) CoolUtil.parsePropertyString(fields);
892+
else fields;
893+
}
894+
895+
var field = CoolUtil.last(fields);
896+
for (i in 0...fields.length - 1) {
897+
var component = fields[i];
898+
if (Type.typeof(component) == TInt) {
899+
if ((target is Array)) {
900+
var index:Int = cast component;
901+
var arr:Array<Dynamic> = cast target;
902+
target = arr[index];
903+
}
904+
} else { // TClass(String)
905+
target = Reflect.getProperty(target, component);
906+
}
907+
if (!Reflect.isObject(target) && !(target is Array))
908+
throw 'The object does not have the property "$component" in "${stringifyFieldsPath(fields)}"';
909+
}
910+
return new PropertyInfo(target, field);
911+
}
912+
913+
public static function cloneProperty(toTarget:Dynamic, fields:OneOfTwo<String, Array<OneOfTwo<String, Int>>>, fromTarget:Dynamic):Dynamic {
914+
var fields:Array<OneOfTwo<String, Int>> = {
915+
if((fields is String)) CoolUtil.parsePropertyString(fields);
916+
else fields;
917+
}
918+
919+
var toProperty = CoolUtil.parseProperty(toTarget, fields);
920+
var fromProperty = CoolUtil.parseProperty(fromTarget, fields);
921+
922+
return toProperty.setValue(fromProperty.getValue());
923+
}
924+
}
925+
926+
class PropertyInfo {
927+
public var object:Dynamic;
928+
public var field:OneOfTwo<String, Int>;
929+
public var typeOfField:Type.ValueType;
930+
#if hscript_improved
931+
public var isCustom:Bool = false;
932+
public var custom:hscript.IHScriptCustomBehaviour;
933+
#end
934+
935+
public function new(object:Dynamic, field:OneOfTwo<String, Int>) {
936+
this.object = object;
937+
this.field = field;
938+
#if hscript_improved
939+
if (object is hscript.IHScriptCustomBehaviour)
940+
{
941+
isCustom = true;
942+
custom = cast object;
943+
}
944+
#end
945+
946+
typeOfField = Type.typeof(field);
947+
}
948+
949+
public function getValue():Dynamic
950+
{
951+
if (typeOfField == TInt)
952+
{
953+
var index:Int = cast field;
954+
var arr:Array<Dynamic> = cast object;
955+
return arr[index];
956+
}
957+
else
958+
{
959+
#if hscript_improved
960+
if (isCustom)
961+
return custom.hget(field);
962+
else
963+
#end
964+
return Reflect.getProperty(object, field);
965+
}
966+
}
967+
968+
public function setValue(value:Dynamic):Void
969+
{
970+
if (typeOfField == TInt)
971+
{
972+
var index:Int = cast field;
973+
var arr:Array<Dynamic> = cast object;
974+
arr[index] = value;
975+
}
976+
else
977+
{
978+
#if hscript_improved
979+
if (isCustom)
980+
custom.hset(field, value);
981+
else
982+
#end
983+
Reflect.setProperty(object, field, value);
984+
}
985+
}
868986
}
869987

870988
/**

source/funkin/game/Strum.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class Strum extends FlxSprite {
107107

108108
updateNotePos(daNote);
109109
for (field in extraCopyFields)
110-
Reflect.setProperty(daNote, field, Reflect.getProperty(this, field));
110+
CoolUtil.cloneProperty(daNote, field, this); // TODO: make this cached to reduce the reflection calls - Neo
111111
}
112112

113113
private inline function updateNotePos(daNote:Note) {

0 commit comments

Comments
 (0)