Skip to content

Commit 9eae7d2

Browse files
committed
Improve the assets path cache algorithm?
1 parent 3210dd6 commit 9eae7d2

3 files changed

Lines changed: 57 additions & 54 deletions

File tree

source/funkin/backend/assets/AssetsLibraryList.hx

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ class AssetsLibraryList extends AssetLibrary {
5757
var existsSpecificCacheLibrary:Map<AssetSource, Map<Null<String>, Map<String, AssetLibrary>>> = [];
5858
var existsSpecificCacheTime:Map<AssetSource, Map<Null<String>, Map<String, Float>>> = [];
5959

60-
public function existsSpecific(id:String, type:String, source:AssetSource = BOTH) {
61-
if (!id.startsWith("assets/") && existsSpecific('assets/$id', type, source))
62-
return true;
60+
private function shouldSkipLib(lib:AssetLibrary, source:AssetSource) {
61+
if (source == BOTH || lib.tag == BOTH) return false;
62+
return source != lib.tag;
63+
}
6364

65+
public function getAssetPathLibrary(id:String, type:Null<String>, source:AssetSource = BOTH):Null<AssetLibrary> {
6466
// Prevent massive lags on repetitive usage, primarily with getting note sprite sheets in mania charts (usually 2k+ notes)
6567
final time = haxe.Timer.stamp();
6668

@@ -77,47 +79,55 @@ class AssetsLibraryList extends AssetLibrary {
7779
}
7880

7981
if (cacheTimePaths.exists(id)) {
80-
final cacheSafeTime = cacheTimePaths.get(id) + 6, library = cacheLibraryPaths.get(id);
82+
final library = cacheLibraryPaths.get(id);
83+
final cacheSafeTime = (Flags.PATHS_CACHE_LIFETIME == null ? null : cacheTimePaths.get(id) + Flags.PATHS_CACHE_LIFETIME);
84+
8185
if (library != null) {
82-
if (time < cacheSafeTime) return true;
83-
else if (!shouldSkipLib(library, source) && library.exists(id, type)) {
86+
if (cacheSafeTime == null || time < cacheSafeTime) return library;
87+
else if (!shouldSkipLib(library, source)
88+
&& (type == null ? library.exists(id, @:privateAccess library.types.get(id)) : library.exists(id, type))
89+
) {
8490
cacheTimePaths.set(id, time);
85-
return true;
91+
return library;
8692
}
8793

8894
cacheLibraryPaths.remove(id);
8995
}
90-
else if (time < cacheSafeTime) {
91-
return false;
92-
}
96+
/*else if (time < cacheSafeTime) {
97+
return null;
98+
}*/
9399
}
94100

95101
cacheTimePaths.set(id, time);
96102

97103
for (library in libraries) {
98104
if (shouldSkipLib(library, source)) continue;
99-
if (library.exists(id, type)) {
105+
if (type == null ? library.exists(id, @:privateAccess library.types.get(id)) : library.exists(id, type)) {
100106
cacheLibraryPaths.set(id, library);
101-
return true;
107+
return library;
102108
}
103109
}
104110

105-
return false;
111+
return null;
112+
}
113+
114+
public function existsSpecific(id:String, type:String, source:AssetSource = BOTH) {
115+
if (!id.startsWith("assets/") && existsSpecific('assets/$id', type, source)) return true;
116+
return getAssetPathLibrary(id, type, source) != null;
106117
}
118+
107119
public override inline function exists(id:String, type:String):Bool
108120
return existsSpecific(id, type, BOTH);
109121

110-
public function getSpecificPath(id:String, source:AssetSource = BOTH) {
111-
for(k=>e in libraries) {
112-
if (shouldSkipLib(e, source)) continue;
113-
114-
@:privateAccess
115-
if (e.exists(id, e.types.get(id))) {
116-
var path = e.getPath(id);
117-
if (path != null)
118-
return path;
119-
}
122+
public function getSpecificPath(id:String, source:AssetSource = BOTH):Null<String> {
123+
// idk if this should be null ? cus theres no mentions of type here
124+
// but also adding one makes actions not work
125+
final library = getAssetPathLibrary(id, null, source);
126+
if (library != null) {
127+
final path = library.getPath(id);
128+
if (path != null) return path;
120129
}
130+
121131
return null;
122132
}
123133

@@ -163,36 +173,20 @@ class AssetsLibraryList extends AssetLibrary {
163173
}
164174

165175
public function getSpecificAsset(id:String, type:String, source:AssetSource = BOTH):Dynamic {
166-
try {
167-
if (!id.startsWith("assets/")) {
168-
var ass = getSpecificAsset('assets/$id', type, source);
169-
if (ass != null) {
170-
return ass;
171-
}
172-
}
173-
for(k=>l in libraries) {
174-
if (shouldSkipLib(l, source)) continue;
176+
if (!id.startsWith("assets/")) {
177+
final asset = getSpecificAsset('assets/$id', type, source);
178+
if (asset != null) return asset;
179+
}
175180

176-
@:privateAccess
177-
if (l.exists(id, l.types.get(id))) {
178-
var asset = l.getAsset(id, type);
179-
if (asset != null) {
180-
return asset;
181-
}
182-
}
183-
}
184-
return null;
185-
} catch(e) {
186-
// TODO: trace the error
187-
throw e;
181+
final library = getAssetPathLibrary(id, type, source);
182+
if (library != null) {
183+
final asset = library.getAsset(id, type);
184+
if (asset != null) return asset;
188185
}
186+
189187
return null;
190188
}
191189

192-
private function shouldSkipLib(lib:AssetLibrary, source:AssetSource) {
193-
if (source == BOTH || lib.tag == BOTH) return false;
194-
return source != lib.tag;
195-
}
196190
public override inline function getAsset(id:String, type:String):Dynamic
197191
return getSpecificAsset(id, type, BOTH);
198192

@@ -254,18 +248,21 @@ class AssetsLibraryList extends AssetLibrary {
254248

255249
public function reset() {
256250
unloadLibraries();
251+
resetAssetPathCache();
252+
253+
libraries.resize(0);
254+
255+
// adds default libraries in again
256+
for (d in __defaultLibraries) addLibrary(d);
257+
}
257258

258-
for(source in [AssetSource.SOURCE, AssetSource.MODS, AssetSource.BOTH]) {
259+
public function resetAssetPathCache() {
260+
for (source in [AssetSource.SOURCE, AssetSource.MODS, AssetSource.BOTH]) {
259261
existsSpecificCacheLibrary[source]?.clear();
260262
existsSpecificCacheTime[source]?.clear();
261263
}
262264
existsSpecificCacheLibrary.clear();
263265
existsSpecificCacheTime.clear();
264-
265-
libraries.resize(0);
266-
267-
// adds default libraries in again
268-
for (d in __defaultLibraries) addLibrary(d);
269266
}
270267

271268
public function addLibrary(lib:AssetLibrary, ?tag:AssetSource, ?addTransLib:Bool = true) {

source/funkin/backend/scripting/GlobalScript.hx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class GlobalScript {
7171
FlxG.signals.preStateSwitch.add(function() {
7272
call("preStateSwitch");
7373

74+
if (Flags.PATHS_CACHE_RESET_ON_SWITCH_STATE) Paths.assetsTree.resetAssetPathCache();
75+
7476
var stateName = Type.getClassName(Type.getClass(@:privateAccess FlxG.game._requestedState));
7577
stateName = stateName.substring(stateName.lastIndexOf(".") + 1);
7678
if (Flags.MOD_REDIRECT_STATES.exists(stateName)) {

source/funkin/backend/system/Flags.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class Flags {
6161
public static var REPO_OWNER:String = "CodenameCrew";
6262
public static var REPO_URL:String = 'https://github.com/$REPO_OWNER/$REPO_NAME';
6363

64+
@:lazy public static var PATHS_CACHE_LIFETIME:Null<Int> = null;
65+
public static var PATHS_CACHE_RESET_ON_SWITCH_STATE:Bool = true;
66+
//public static var PATHS_CHECK_ASSETS_PREFIX:Bool = true; // Doesn't work fully
67+
6468
/**
6569
* Preferred sound extension for the game's audio files.
6670
* Currently is set to `mp3` for web targets, and `ogg` for other targets.

0 commit comments

Comments
 (0)