mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-12-22 21:26:49 +00:00
Do some cleanup (replace several utility functions with a utility library we already depend on!)
This commit is contained in:
parent
f3868c2ee8
commit
fed6d1146c
|
@ -128,6 +128,7 @@
|
|||
|
||||
|
||||
<haxelib name="json2object" /> <!-- JSON parsing -->
|
||||
<haxelib name="thx.core" /> <!-- General utility library, "the lodash of Haxe" -->
|
||||
<haxelib name="thx.semver" /> <!-- Version string handling -->
|
||||
|
||||
<haxelib name="hxcpp-debug-server" if="desktop debug" /> <!-- VSCode debug support -->
|
||||
|
|
|
@ -11,6 +11,7 @@ import flixel.system.debug.watch.Tracker;
|
|||
// These are great.
|
||||
using Lambda;
|
||||
using StringTools;
|
||||
using thx.Arrays;
|
||||
using funkin.util.tools.ArraySortTools;
|
||||
using funkin.util.tools.ArrayTools;
|
||||
using funkin.util.tools.FloatTools;
|
||||
|
|
|
@ -439,12 +439,16 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta
|
|||
// so we have to map it to the actual difficulty names.
|
||||
// We also filter out difficulties that don't match the variation or that don't exist.
|
||||
|
||||
var diffFiltered:Array<String> = difficulties.keys().array().map(function(diffId:String):Null<String> {
|
||||
var difficulty:Null<SongDifficulty> = difficulties.get(diffId);
|
||||
if (difficulty == null) return null;
|
||||
if (variationIds.length > 0 && !variationIds.contains(difficulty.variation)) return null;
|
||||
return difficulty.difficulty;
|
||||
}).nonNull().unique();
|
||||
var diffFiltered:Array<String> = difficulties.keys()
|
||||
.array()
|
||||
.map(function(diffId:String):Null<String> {
|
||||
var difficulty:Null<SongDifficulty> = difficulties.get(diffId);
|
||||
if (difficulty == null) return null;
|
||||
if (variationIds.length > 0 && !variationIds.contains(difficulty.variation)) return null;
|
||||
return difficulty.difficulty;
|
||||
})
|
||||
.filterNull()
|
||||
.distinct();
|
||||
|
||||
diffFiltered = diffFiltered.filter(function(diffId:String):Bool {
|
||||
if (showHidden) return true;
|
||||
|
|
|
@ -28,8 +28,9 @@ class SaveDataMigrator
|
|||
version = VersionUtil.repairVersion(version);
|
||||
if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE))
|
||||
{
|
||||
// Simply import the structured data.
|
||||
var save:Save = new Save(StructureUtil.deepMerge(Save.getDefault(), inputData));
|
||||
// Import the structured data.
|
||||
var saveDataWithDefaults:RawSaveData = thx.Objects.deepCombine(Save.getDefault(), inputData);
|
||||
var save:Save = new Save(saveDataWithDefaults);
|
||||
return save;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -13,11 +13,10 @@ class LevelProp extends Bopper
|
|||
// Only reset the prop if the asset path has changed.
|
||||
if (propData == null || value?.assetPath != propData?.assetPath)
|
||||
{
|
||||
this.visible = (value != null);
|
||||
this.propData = value;
|
||||
danceEvery = this.propData?.danceEvery ?? 0;
|
||||
applyData();
|
||||
}
|
||||
this.visible = (value != null);
|
||||
danceEvery = this.propData?.danceEvery ?? 0;
|
||||
|
||||
return this.propData;
|
||||
}
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
package funkin.util;
|
||||
|
||||
import funkin.util.tools.MapTools;
|
||||
import haxe.DynamicAccess;
|
||||
|
||||
/**
|
||||
* Utilities for working with anonymous structures.
|
||||
*/
|
||||
class StructureUtil
|
||||
{
|
||||
/**
|
||||
* Merge two structures, with the second overwriting the first.
|
||||
* Performs a SHALLOW clone, where child structures are not merged.
|
||||
* @param a The base structure.
|
||||
* @param b The new structure.
|
||||
* @return The merged structure.
|
||||
*/
|
||||
public static function merge(a:Dynamic, b:Dynamic):Dynamic
|
||||
{
|
||||
var result:DynamicAccess<Dynamic> = Reflect.copy(a);
|
||||
|
||||
for (field in Reflect.fields(b))
|
||||
{
|
||||
result.set(field, Reflect.field(b, field));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function toMap(a:Dynamic):haxe.ds.Map<String, Dynamic>
|
||||
{
|
||||
var result:haxe.ds.Map<String, Dynamic> = [];
|
||||
|
||||
for (field in Reflect.fields(a))
|
||||
{
|
||||
result.set(field, Reflect.field(a, field));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static function isMap(a:Dynamic):Bool
|
||||
{
|
||||
return Std.isOfType(a, haxe.Constraints.IMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if `a` is an anonymous structure.
|
||||
* I believe this returns `false` even for class instances and arrays.
|
||||
*/
|
||||
public static function isStructure(a:Dynamic):Bool
|
||||
{
|
||||
// TODO: Is there a difference?
|
||||
// return Reflect.isObject(foo);
|
||||
|
||||
switch (Type.typeof(a))
|
||||
{
|
||||
case TObject:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if `a` is an array.
|
||||
*
|
||||
* NOTE: isObject and isInstance also return true,
|
||||
* since they're objects of the Array<> class, so check this first!
|
||||
*/
|
||||
public static function isArray(a:Dynamic):Bool
|
||||
{
|
||||
return Std.is(a, Array);
|
||||
}
|
||||
|
||||
public static function isInstance(a:Dynamic):Bool
|
||||
{
|
||||
return Type.getClass(a) != null;
|
||||
}
|
||||
|
||||
public static function isPrimitive(a:Dynamic):Bool
|
||||
{
|
||||
switch (Type.typeof(a))
|
||||
{
|
||||
case TInt | TFloat | TBool:
|
||||
return true;
|
||||
case TClass(c):
|
||||
return false;
|
||||
case TEnum(e):
|
||||
return false;
|
||||
case TObject:
|
||||
return false;
|
||||
case TFunction:
|
||||
return false;
|
||||
case TNull:
|
||||
return true;
|
||||
case TUnknown:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two structures, with the second overwriting the first.
|
||||
* Performs a DEEP clone, where child structures are also merged recursively.
|
||||
* @param a The base structure.
|
||||
* @param b The new structure.
|
||||
* @return The merged structure.
|
||||
*/
|
||||
public static function deepMerge(a:Dynamic, b:Dynamic):Dynamic
|
||||
{
|
||||
if (a == null) return b;
|
||||
if (b == null) return null;
|
||||
if (isArray(a) && isArray(b)) return b;
|
||||
if (isPrimitive(a) && isPrimitive(b)) return b;
|
||||
if (isMap(b))
|
||||
{
|
||||
if (isMap(a))
|
||||
{
|
||||
return MapTools.merge(a, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return StructureUtil.toMap(a).merge(b);
|
||||
}
|
||||
}
|
||||
if (Std.isOfType(b, haxe.ds.StringMap))
|
||||
{
|
||||
if (Std.isOfType(a, haxe.ds.StringMap))
|
||||
{
|
||||
return MapTools.merge(a, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
return StructureUtil.toMap(a).merge(b);
|
||||
}
|
||||
}
|
||||
if (!isStructure(a) || !isStructure(b)) return b;
|
||||
|
||||
var result:DynamicAccess<Dynamic> = Reflect.copy(a);
|
||||
|
||||
for (field in Reflect.fields(b))
|
||||
{
|
||||
if (isStructure(b))
|
||||
{
|
||||
result.set(field, deepMerge(Reflect.field(result, field), Reflect.field(b, field)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're here, b[field] is a primitive.
|
||||
result.set(field, Reflect.field(b, field));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -5,72 +5,6 @@ package funkin.util.tools;
|
|||
*/
|
||||
class ArrayTools
|
||||
{
|
||||
/**
|
||||
* Returns a copy of the array with all duplicate elements removed.
|
||||
* @param array The array to remove duplicates from.
|
||||
* @return A copy of the array with all duplicate elements removed.
|
||||
*/
|
||||
public static function unique<T>(array:Array<T>):Array<T>
|
||||
{
|
||||
var result:Array<T> = [];
|
||||
for (element in array)
|
||||
{
|
||||
if (!result.contains(element))
|
||||
{
|
||||
result.push(element);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array with all `null` elements removed.
|
||||
* @param array The array to remove `null` elements from.
|
||||
* @return A copy of the array with all `null` elements removed.
|
||||
*/
|
||||
public static function nonNull<T>(array:Array<Null<T>>):Array<T>
|
||||
{
|
||||
var result:Array<T> = [];
|
||||
for (element in array)
|
||||
{
|
||||
if (element != null)
|
||||
{
|
||||
result.push(element);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first element of the array that satisfies the predicate, or null if none do.
|
||||
* @param input The array to search
|
||||
* @param predicate The predicate to call
|
||||
* @return The result
|
||||
*/
|
||||
public static function find<T>(input:Array<T>, predicate:T->Bool):Null<T>
|
||||
{
|
||||
for (element in input)
|
||||
{
|
||||
if (predicate(element)) return element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the first element of the array that satisfies the predicate, or `-1` if none do.
|
||||
* @param input The array to search
|
||||
* @param predicate The predicate to call
|
||||
* @return The index of the result
|
||||
*/
|
||||
public static function findIndex<T>(input:Array<T>, predicate:T->Bool):Int
|
||||
{
|
||||
for (index in 0...input.length)
|
||||
{
|
||||
if (predicate(input[index])) return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Push an element to the array if it is not already present.
|
||||
* @param input The array to push to
|
||||
|
|
Loading…
Reference in a new issue