From c929e4c74b2453d8757bae04bfe99fc5f8d6ff0f Mon Sep 17 00:00:00 2001 From: RDW Date: Tue, 6 Feb 2024 13:23:57 +0100 Subject: [PATCH] GRF: Add support for optionally loading CGRF buffers This can drastically reduce the loading times if the TOC has been compiled before. --- Core/FileFormats/RagnarokGRF.lua | 18 +++++++++++++----- Tests/FileFormats/RagnarokGRF.spec.lua | 13 +++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Core/FileFormats/RagnarokGRF.lua b/Core/FileFormats/RagnarokGRF.lua index aa0c7ba9..16e2a2f6 100644 --- a/Core/FileFormats/RagnarokGRF.lua +++ b/Core/FileFormats/RagnarokGRF.lua @@ -1,3 +1,5 @@ +local CompiledGRF = require("Core.FileFormats.Optimized.CompiledGRF") + local cstring = require("Core.RuntimeExtensions.cstring") local bit = require("bit") @@ -58,16 +60,16 @@ function RagnarokGRF:Construct() fileTable = {}, } - setmetatable(instance, self) + setmetatable(instance, { + __index = self, + }) return instance end -RagnarokGRF.__index = RagnarokGRF -RagnarokGRF.__call = RagnarokGRF.Construct -setmetatable(RagnarokGRF, RagnarokGRF) +class("RagnarokGRF", RagnarokGRF) -function RagnarokGRF:Open(pathToGRF) +function RagnarokGRF:Open(pathToGRF, cgrfFileContents) local isValidPath = C_FileSystem.Exists(pathToGRF) if not isValidPath then error(format("Failed to open archive %s (No such file exists)", pathToGRF), 0) @@ -82,6 +84,7 @@ function RagnarokGRF:Open(pathToGRF) self.fileHandle = assert(io.open(pathToGRF, "rb")) self.pathToGRF = pathToGRF + self.cgrfFileContents = cgrfFileContents self:DecodeArchiveMetadata() end @@ -128,6 +131,11 @@ function RagnarokGRF:DecodeHeader() end function RagnarokGRF:DecodeFileTable() + if rawget(self, "cgrfFileContents") then + CompiledGRF:RestoreTableOfContents(self, self.cgrfFileContents) + return + end + self:DecodeTableHeader() self:DecodeFileEntries() end diff --git a/Tests/FileFormats/RagnarokGRF.spec.lua b/Tests/FileFormats/RagnarokGRF.spec.lua index 7aa2c18d..7ef37eae 100644 --- a/Tests/FileFormats/RagnarokGRF.spec.lua +++ b/Tests/FileFormats/RagnarokGRF.spec.lua @@ -54,6 +54,19 @@ describe("RagnarokGRF", function() assertEquals(grf.fileTable.entries["uppercase.png"].typeID, RagnarokGRF.COMPRESSED_FILE_ENTRY_TYPE) assertEquals(grf.fileTable.entries["uppercase.png"].offsetRelativeToHeader, 160) end) + + it("should be able to restore the file table from a CGRF buffer", function() + local cgrfFilePath = path.join("Tests", "Fixtures", "test.cgrf") + local cgrfFileContents = C_FileSystem.ReadFile(cgrfFilePath) + + local grf = RagnarokGRF() + grf:Open("Tests/Fixtures/test.grf", cgrfFileContents) + grf:Close() + + -- These aren't stored in the CGRF (because they're useless on their own) + assertEquals(grf.fileTable.compressedSizeInBytes, 0) + assertEquals(grf.fileTable.decompressedSizeInBytes, 0) + end) end) describe("FindLargestFileEntry", function()