From 503ff87ab3f6ccd4b0ab74e2403a29fff70cc1e1 Mon Sep 17 00:00:00 2001 From: Ne_Eo Date: Sun, 2 Mar 2025 23:28:12 +0100 Subject: [PATCH] Add property parsing and cloning property values --- source/funkin/backend/utils/CoolUtil.hx | 118 ++++++++++++++++++++++++ source/funkin/game/Strum.hx | 2 +- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 3b8fff3d..32f5bd56 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -865,6 +865,124 @@ class CoolUtil return result.join(seperator); } + + public inline static function parsePropertyString(fieldPath:String):Array> { + return FlxTween.parseFieldString(fieldPath); + } + + function stringifyFieldsPath(fields:Array>):String { + var str = new StringBuf(); + var first = true; + for (field in fields) { + if (Type.typeof(field) == TInt) { + str.add('[${field}]'); + } else { + if (!first) + str.add('.'); + str.add(field); + } + first = false; + } + return str.toString(); + } + + public static function parseProperty(target:Dynamic, fields:OneOfTwo>>):Dynamic { + var fields:Array> = { + if((fields is String)) CoolUtil.parsePropertyString(fields); + else fields; + } + + var field = CoolUtil.last(fields); + for (i in 0...fields.length - 1) { + var component = fields[i]; + if (Type.typeof(component) == TInt) { + if ((target is Array)) { + var index:Int = cast component; + var arr:Array = cast target; + target = arr[index]; + } + } else { // TClass(String) + target = Reflect.getProperty(target, component); + } + if (!Reflect.isObject(target) && !(target is Array)) + throw 'The object does not have the property "$component" in "${stringifyFieldsPath(fields)}"'; + } + return new PropertyInfo(target, field); + } + + public static function cloneProperty(toTarget:Dynamic, fields:OneOfTwo>>, fromTarget:Dynamic):Dynamic { + var fields:Array> = { + if((fields is String)) CoolUtil.parsePropertyString(fields); + else fields; + } + + var toProperty = CoolUtil.parseProperty(toTarget, fields); + var fromProperty = CoolUtil.parseProperty(fromTarget, fields); + + return toProperty.setValue(fromProperty.getValue()); + } +} + +class PropertyInfo { + public var object:Dynamic; + public var field:OneOfTwo; + public var typeOfField:Type.ValueType; + #if hscript_improved + public var isCustom:Bool = false; + public var custom:hscript.IHScriptCustomBehaviour; + #end + + public function new(object:Dynamic, field:OneOfTwo) { + this.object = object; + this.field = field; + #if hscript_improved + if (object is hscript.IHScriptCustomBehaviour) + { + isCustom = true; + custom = cast object; + } + #end + + typeOfField = Type.typeof(field); + } + + public function getValue():Dynamic + { + if (typeOfField == TInt) + { + var index:Int = cast field; + var arr:Array = cast object; + return arr[index]; + } + else + { + #if hscript_improved + if (isCustom) + return custom.hget(field); + else + #end + return Reflect.getProperty(object, field); + } + } + + public function setValue(value:Dynamic):Void + { + if (typeOfField == TInt) + { + var index:Int = cast field; + var arr:Array = cast object; + arr[index] = value; + } + else + { + #if hscript_improved + if (isCustom) + custom.hset(field, value); + else + #end + Reflect.setProperty(object, field, value); + } + } } /** diff --git a/source/funkin/game/Strum.hx b/source/funkin/game/Strum.hx index 44ab53f3..d4a5cdb4 100644 --- a/source/funkin/game/Strum.hx +++ b/source/funkin/game/Strum.hx @@ -107,7 +107,7 @@ class Strum extends FlxSprite { updateNotePos(daNote); for (field in extraCopyFields) - Reflect.setProperty(daNote, field, Reflect.getProperty(this, field)); + CoolUtil.cloneProperty(daNote, field, this); // TODO: make this cached to reduce the reflection calls - Neo } private inline function updateNotePos(daNote:Note) {