Skip to content

Commit e151e9f

Browse files
committed
Mark FallbackStack operations as obsolete and introduce overloads with fallback parameter
1 parent 8be5e6f commit e151e9f

2 files changed

Lines changed: 44 additions & 18 deletions

File tree

Celeste.Mod.mm/Patches/Monocle/Atlas.cs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
namespace Monocle {
1717
class patch_Atlas : Atlas {
18+
private const string MessageFallbackStackObsolete = "Fallback stack is obsolete, use overloads with fallback parameter instead.";
19+
private const string MessageGetFallbackObsolete = "Fallback stack is obsolete, use GetDefaultFallback if you are getting the default one.";
1820

1921
// We're effectively in Atlas, but still need to "expose" private fields to our mod.
2022
private Dictionary<string, MTexture> textures;
@@ -338,13 +340,20 @@ public void ResetCaches() {
338340
orderedTexturesCache = new Dictionary<string, List<MTexture>>();
339341
}
340342

341-
public MTexture GetFallback() {
343+
private MTexture GetFallbackInternal() {
342344
if (FallbackStack.IsValueCreated) {
343345
Stack<MTexture> stack = FallbackStack.Value;
344346
if (stack.Count > 0)
345347
return stack.Peek();
346348
}
349+
return GetDefaultFallback();
350+
}
351+
352+
[Obsolete(MessageGetFallbackObsolete)]
353+
public MTexture GetFallback()
354+
=> GetFallbackInternal();
347355

356+
public MTexture GetDefaultFallback() {
348357
// we may encounter concurrent issue here but it's safe
349358
// since the worst result is making multiple lookups
350359
if (DefaultFallback != null || textures.TryGetValue("__fallback", out DefaultFallback))
@@ -353,10 +362,12 @@ public MTexture GetFallback() {
353362
return null;
354363
}
355364

365+
[Obsolete(MessageFallbackStackObsolete)]
356366
public void PushFallback(MTexture fallback) {
357367
FallbackStack.Value.Push(fallback);
358368
}
359369

370+
[Obsolete(MessageFallbackStackObsolete)]
360371
public MTexture PopFallback() {
361372
return FallbackStack.Value.Pop();
362373
}
@@ -436,12 +447,14 @@ public bool HasAtlasSubtexturesAt(string key, int index) {
436447
// log missing subtextures when getting an animation (for example, decals)
437448
public extern List<MTexture> orig_GetAtlasSubtextures(string key);
438449
public new List<MTexture> GetAtlasSubtextures(string key) {
439-
PushFallback(null);
450+
return GetAtlasSubtextures(key, GetFallbackInternal());
451+
}
452+
453+
public List<MTexture> GetAtlasSubtextures(string key, MTexture fallback) {
440454
List<MTexture> result = orig_GetAtlasSubtextures(key);
441-
PopFallback();
455+
442456
if (result == null || result.Count == 0) {
443457
Logger.Warn("Atlas", $"Requested atlas subtextures but none were found: {RelativeDataPath}{key}");
444-
MTexture fallback = GetFallback();
445458
if (fallback != null)
446459
return new List<MTexture>() { fallback };
447460
}
@@ -453,17 +466,21 @@ public bool HasAtlasSubtexturesAt(string key, int index) {
453466

454467
[MonoModReplace]
455468
public new MTexture GetAtlasSubtexturesAt(string key, int index) {
469+
MTexture fallback = GetFallbackInternal();
470+
return GetAtlasSubtexturesAt(key, index, fallback);
471+
}
472+
473+
public MTexture GetAtlasSubtexturesAt(string key, int index, MTexture fallback) {
456474
if (orderedTexturesCache.TryGetValue(key, out List<MTexture> list)) {
457475
if (index < 0 || index >= list.Count) {
458476
Logger.Warn("Atlas", $"Requested atlas subtexture that falls out of range: {RelativeDataPath}{key} {index}");
459-
return GetFallback();
477+
return fallback;
460478
}
461479
return list[index];
462480
}
463481

464482
MTexture result = GetAtlasSubtextureFromAtlasAt(key, index);
465483
if (result == null) {
466-
MTexture fallback = GetFallback();
467484
if (fallback != null) {
468485
// SpriteData and other places use GetAtlasSubtextureAt to check if textures exist.
469486
// Logging this verbosely when no fallback exists doesn't make sense in those cases.
@@ -474,21 +491,26 @@ public bool HasAtlasSubtexturesAt(string key, int index) {
474491
return result;
475492
}
476493

477-
// log missing texture when getting one by ID (for example, tilesets)
478494
public new MTexture this[string id] {
479495
[MonoModReplace]
480496
get {
481-
if (!textures.TryGetValue(id, out MTexture result)) {
482-
Logger.Warn("Atlas", $"Requested texture that does not exist: {RelativeDataPath}{id}");
483-
return GetFallback();
484-
}
485-
return result;
497+
MTexture fallback = GetFallbackInternal();
498+
return GetWithFallback(id, fallback);
486499
}
487500

488501
// we don't want to modify the setter, but want it to exist in the patch class so that we can call it from within our patches.
489502
[MonoModIgnore]
490503
set { }
491504
}
505+
506+
// log missing texture when getting one by ID (for example, tilesets)
507+
public MTexture GetWithFallback(string id, MTexture fallback) {
508+
if (!textures.TryGetValue(id, out MTexture result)) {
509+
Logger.Warn("Atlas", $"Requested texture that does not exist: {RelativeDataPath}{id}");
510+
return fallback;
511+
}
512+
return result;
513+
}
492514
}
493515
public static class AtlasExt {
494516

Celeste.Mod.mm/Patches/Monocle/SpriteData.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ public patch_SpriteData(Atlas atlas)
1111
// no-op. MonoMod ignores this - we only need this to make the compiler shut up.
1212
}
1313

14-
private extern bool orig_HasFrames(patch_Atlas atlas, string path, int[] frames = null);
14+
[MonoModReplace]
1515
private bool HasFrames(patch_Atlas atlas, string path, int[] frames = null) {
16-
atlas.PushFallback(null);
17-
bool rv = orig_HasFrames(atlas, path, frames);
18-
atlas.PopFallback();
19-
return rv;
16+
if (frames == null || frames.Length == 0) {
17+
return atlas.GetAtlasSubtexturesAt(path, 0, null) != null;
18+
}
19+
for (int i = 0; i < frames.Length; i++) {
20+
if (atlas.GetAtlasSubtexturesAt(path, frames[i], null) == null) {
21+
return false;
22+
}
23+
}
24+
return true;
2025
}
21-
2226
}
2327
}

0 commit comments

Comments
 (0)