Move Noita specific stuff out of JSON library

- Add JSON marshal "interface" that objects can implement
- Fix EmmyLua annotation
- Move JSON marshaler into noita-api.lua

#9
This commit is contained in:
David Vogel 2022-07-18 11:47:59 +02:00
parent 833ab41eeb
commit cfe4193974
3 changed files with 55 additions and 45 deletions

View File

@ -7,7 +7,7 @@
local noitaAPI = dofile_once("mods/noita-mapcap/files/noita-api.lua") local noitaAPI = dofile_once("mods/noita-mapcap/files/noita-api.lua")
---@type JSONLib ---@type JSONLib
local jsonSerialize = dofile_once("mods/noita-mapcap/files/json-serialize.lua") local json = dofile_once("mods/noita-mapcap/files/json-serialize.lua")
CAPTURE_PIXEL_SIZE = 1 -- Screen to virtual pixel ratio. CAPTURE_PIXEL_SIZE = 1 -- Screen to virtual pixel ratio.
CAPTURE_GRID_SIZE = 512 -- in virtual (world) pixels. There will always be exactly 4 images overlapping if the virtual resolution is 1024x1024. CAPTURE_GRID_SIZE = 512 -- in virtual (world) pixels. There will always be exactly 4 images overlapping if the virtual resolution is 1024x1024.
@ -102,11 +102,11 @@ local function captureScreenshot(x, y, rx, ry, entityFile)
-- Well, as long as it does not crash between write and flush. -- Well, as long as it does not crash between write and flush.
if entityFile:seek("end") == 0 then if entityFile:seek("end") == 0 then
-- First line. -- First line.
entityFile:write("[\n\t", jsonSerialize.Marshal(rootEntity), "\n", "]") entityFile:write("[\n\t", json.Marshal(rootEntity), "\n", "]")
else else
-- Following lines. -- Following lines.
entityFile:seek("end", -2) -- Seek a few bytes back, so we can overwrite some stuff. entityFile:seek("end", -2) -- Seek a few bytes back, so we can overwrite some stuff.
entityFile:write(",\n\t", jsonSerialize.Marshal(rootEntity), "\n", "]") entityFile:write(",\n\t", json.Marshal(rootEntity), "\n", "]")
end end
rootEntity:AddTag("MapCaptured") -- Prevent recapturing. rootEntity:AddTag("MapCaptured") -- Prevent recapturing.

View File

@ -5,9 +5,6 @@
-- Simple library to marshal JSON values. -- Simple library to marshal JSON values.
---@type NoitaAPI
local noitaAPI = dofile_once("mods/noita-mapcap/files/noita-api.lua")
---@class JSONLib ---@class JSONLib
local lib = {} local lib = {}
@ -63,7 +60,7 @@ function lib.MarshalNumber(val)
end end
---MarshalBoolean returns the JSON representation of a boolean value. ---MarshalBoolean returns the JSON representation of a boolean value.
---@param val number ---@param val boolean
---@return string ---@return string
function lib.MarshalBoolean(val) function lib.MarshalBoolean(val)
return tostring(val) return tostring(val)
@ -118,37 +115,6 @@ function lib.MarshalArray(val, customMarshalFunction)
return result return result
end end
---MarshalNoitaComponent returns the JSON representation of the given Noita component.
---@param component NoitaComponent
---@return string
function lib.MarshalNoitaComponent(component)
local resultObject = {
typeName = component:GetTypeName(),
members = component:GetMembers(),
--objectMembers = component:ObjectGetMembers
}
return lib.Marshal(resultObject)
end
---MarshalNoitaEntity returns the JSON representation of the given Noita entity.
---@param entity NoitaEntity
---@return string
function lib.MarshalNoitaEntity(entity)
local result = {
name = entity:GetName(),
filename = entity:GetFilename(),
tags = entity:GetTags(),
children = entity:GetAllChildren(),
components = entity:GetAllComponents(),
transform = {},
}
result.transform.x, result.transform.y, result.transform.rotation, result.transform.scaleX, result.transform.scaleY = entity:GetTransform()
return lib.Marshal(result)
end
---Marshal marshals any value into JSON representation. ---Marshal marshals any value into JSON representation.
---@param val any ---@param val any
---@return string ---@return string
@ -164,11 +130,9 @@ function lib.Marshal(val)
elseif t == "boolean" then elseif t == "boolean" then
return lib.MarshalBoolean(val) return lib.MarshalBoolean(val)
elseif t == "table" then elseif t == "table" then
-- Check if object is instance of class... -- Check if object implements the JSON marshaler interface.
if getmetatable(val) == noitaAPI.MetaTables.Component then if val.MarshalJSON ~= nil and type(val.MarshalJSON) == "function" then
return lib.MarshalNoitaComponent(val) return val:MarshalJSON()
elseif getmetatable(val) == noitaAPI.MetaTables.Entity then
return lib.MarshalNoitaEntity(val)
end end
-- If not, fall back to array or object handling. -- If not, fall back to array or object handling.

View File

@ -9,6 +9,13 @@
-- State: Working but incomplete. If something is missing, add it by hand! -- State: Working but incomplete. If something is missing, add it by hand!
-- It would be optimal to generate this API wrapper automatically... -- It would be optimal to generate this API wrapper automatically...
---@type JSONLib
local json = dofile_once("mods/noita-mapcap/files/json-serialize.lua")
-------------
-- Classes --
-------------
local EntityAPI = {} local EntityAPI = {}
---@class NoitaEntity ---@class NoitaEntity
@ -23,6 +30,43 @@ local ComponentAPI = {}
local NoitaComponent = {} local NoitaComponent = {}
NoitaComponent.__index = NoitaComponent NoitaComponent.__index = NoitaComponent
-------------------------
-- JSON Implementation --
-------------------------
---MarshalJSON implements the JSON marshaler interface.
---@return string
function NoitaComponent:MarshalJSON()
local resultObject = {
typeName = self:GetTypeName(),
members = self:GetMembers(),
--objectMembers = component:ObjectGetMembers
}
return json.Marshal(resultObject)
end
---MarshalJSON implements the JSON marshaler interface.
---@return string
function NoitaEntity:MarshalJSON()
local result = {
name = self:GetName(),
filename = self:GetFilename(),
tags = self:GetTags(),
children = self:GetAllChildren(),
components = self:GetAllComponents(),
transform = {},
}
result.transform.x, result.transform.y, result.transform.rotation, result.transform.scaleX, result.transform.scaleY = self:GetTransform()
return json.Marshal(result)
end
------------------------
-- Noita API wrappers --
------------------------
--- ---
---@param filename string ---@param filename string
---@param posX number -- X coordinate in world (virtual) pixels. ---@param posX number -- X coordinate in world (virtual) pixels.
@ -458,6 +502,10 @@ end
-- TODO: Add missing Noita API methods and functions. -- TODO: Add missing Noita API methods and functions.
--------------------
-- Noita API root --
--------------------
---@class NoitaAPI ---@class NoitaAPI
local api = { local api = {
Component = ComponentAPI, Component = ComponentAPI,
@ -468,6 +516,4 @@ local api = {
}, },
} }
return api return api