Skip to content

Commit

Permalink
Use a code cache, massively improving performance
Browse files Browse the repository at this point in the history
  • Loading branch information
Miepee committed Aug 1, 2024
1 parent 4d5d57a commit 5de70c5
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 16 deletions.
51 changes: 44 additions & 7 deletions YAMS-LIB/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@ public static string GetGMLCode(this UndertaleCode code)

public static void ReplaceGMLInCode(this UndertaleCode code, string textToReplace, string replacementText, bool ignoreErrors = false)
{
var codeText = Decompiler.Decompile(code, decompileContext);
string codeText;

if (Patcher.CodeCache.TryGetValue(code, out string? value))
{
codeText = value;
}
else
{
codeText = Decompiler.Decompile(code, decompileContext);
Patcher.CodeCache.Add(code, codeText);
}

if (!codeText.Contains(textToReplace))
{
if (ignoreErrors)
Expand All @@ -34,26 +45,52 @@ public static void ReplaceGMLInCode(this UndertaleCode code, string textToReplac
throw new ApplicationException($"The text \"{textToReplace}\" was not found in \"{code.Name.Content}\"!");
}
codeText = codeText.Replace(textToReplace, replacementText);
code.ReplaceGML(codeText, gmData);
Patcher.CodeCache[code] = codeText;
}

public static void PrependGMLInCode(this UndertaleCode code, string prependedText)
{
var codeText = Decompiler.Decompile(code, decompileContext);
string codeText;
if (Patcher.CodeCache.TryGetValue(code, out string? value))
{
codeText = value;
}
else
{
codeText = Decompiler.Decompile(code, decompileContext);
Patcher.CodeCache.Add(code, codeText);
}
codeText = prependedText + "\n" + codeText;
code.ReplaceGML(codeText, gmData);
Patcher.CodeCache[code] = codeText;
}

public static void AppendGMLInCode(this UndertaleCode code, string appendedText)
{
var codeText = Decompiler.Decompile(code, decompileContext);
string codeText;
if (Patcher.CodeCache.TryGetValue(code, out string? value))
{
codeText = value;
}
else
{
codeText = Decompiler.Decompile(code, decompileContext);
Patcher.CodeCache.Add(code, codeText);
}
codeText = codeText + appendedText + "\n";
code.ReplaceGML(codeText, gmData);
Patcher.CodeCache[code] = codeText;
}

public static void SubstituteGMLCode(this UndertaleCode code, string newGMLCode)
{
code.ReplaceGML(newGMLCode, gmData);
Patcher.CodeCache[code] = newGMLCode;
}

public static void FlushCode()
{
foreach ((var codeName, var codeText) in Patcher.CodeCache)
{
codeName.ReplaceGML(codeText, gmData);
}
}

public static UndertaleRoom.Tile CreateRoomTile(int x, int y, int depth, UndertaleBackground tileset, uint sourceX, uint sourceY, uint width = 16, uint height = 16, uint? id = null)
Expand Down
4 changes: 4 additions & 0 deletions YAMS-LIB/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class Patcher
internal static GlobalDecompileContext? decompileContext;
internal static bool isHorde = false;

internal static Dictionary<UndertaleCode, string> CodeCache = new Dictionary<UndertaleCode, string>(1024);

private static string CreateVersionString()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Expand Down Expand Up @@ -628,7 +630,9 @@ public static void Main(string am2rPath, string outputAm2rPath, string jsonPath)
Multiworld.Apply(gmData, decompileContext, seedObject);
AddBossMWTracking.Apply(gmData, decompileContext, seedObject);


// Write back to disk
ExtensionMethods.FlushCode();
using (FileStream fs = new FileInfo(outputAm2rPath).OpenWrite())
{
UndertaleIO.Write(fs, gmData, Console.WriteLine);
Expand Down
4 changes: 2 additions & 2 deletions YAMS-LIB/patches/DecoupleItemsFromLocations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
}
""");
subscreenMenuStep.ReplaceGMLInCode("""
if (global.curropt == 7 && (!global.hasIbeam))
if (global.curropt == 7 && !global.hasIbeam)
global.curropt += 1
""", """
if (global.curropt == 7 && (!global.hasIbeam))
Expand All @@ -219,7 +219,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
global.curropt += 1
""");
subscreenMenuStep.ReplaceGMLInCode("""
if (global.curropt == 7 && (!global.hasIbeam))
if (global.curropt == 7 && !global.hasIbeam)
global.curropt -= 1
""", """
if (global.curropt == 8 && (!global.hasMorph))
Expand Down
2 changes: 1 addition & 1 deletion YAMS-LIB/patches/misc/DontRespawnBombBlocks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
// The bomb block puzzle in te room before varia don't need to have their special handling from am2random
var rm_a2a06 = gmData.Rooms.ByName("rm_a2a06");
rm_a2a06.GameObjects.First(go => go.X == 608 && go.Y == 112 && go.ObjectDefinition.Name.Content == "oBlockBomb").CreationCode.ReplaceGMLInCode(
"if (oControl.mod_randomgamebool == 1 && global.hasBombs == 0 && (!global.hasJumpball) && global.hasGravity == 0)",
"if (oControl.mod_randomgamebool == 1 && global.hasBombs == 0 && !global.hasJumpball && global.hasGravity == 0)",
"if (false)");
rm_a2a06.GameObjects.First(go => go.X == 624 && go.Y == 48 && go.ObjectDefinition.Name.Content == "oBlockBomb").CreationCode.ReplaceGMLInCode(
"if (oControl.mod_randomgamebool == 1 && global.hasBombs == 0 && global.hasGravity == 0)",
Expand Down
12 changes: 6 additions & 6 deletions YAMS-LIB/patches/qol/ShowFullyUnexploredMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC

// Don't ever draw the debug pipe tiles
gmData.Code.ByName("gml_Script_draw_mapblock").ReplaceGMLInCode($$"""
if (argument7 == "H"{{(isHorde ? " || argument8 == \"H\"" : "")}})
draw_sprite(sMapSP, 12, argument0, argument1)
if (argument7 == "V")
draw_sprite(sMapSP, 13, argument0, argument1)
if (argument7 == "C")
draw_sprite(sMapSP, 14, argument0, argument1)
if (argument7 == "H"{{(isHorde ? " || argument8 == \"H\"" : "")}})
draw_sprite(sMapSP, 12, argument0, argument1)
if (argument7 == "V")
draw_sprite(sMapSP, 13, argument0, argument1)
if (argument7 == "C")
draw_sprite(sMapSP, 14, argument0, argument1)
""", "");

// Also show item pickups and metroids
Expand Down

0 comments on commit 5de70c5

Please sign in to comment.