Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

MetaTable to JSON?

Asked by 9 years ago

Simply put I have a script similar to this-->

local maintable = {}
local addtable = {"Stuff","MoreStuff"}
local metatable = {"MoreMoreStuff","ExtraMoreStuff"} 
setmetatable(addtable,metatable)
table.insert(maintable,1,addtable)


local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore")
local http = game:GetService("HttpService")
local JSON = http:JSONEncode(maintable)
DataStore:SetAsync("JsonSave",JSON)

The whole thing works fine and when I load the JSON again I have everything... except the meta table. I try-->

--Of course not in the same script
local DataStore = game:GetService("DataStoreService"):GetDataStore("FakeDataStore")
local LoadedMainTable = DataStore:GetAsync("JsonSave")
local Decodedtable = http:JSONDecode(LoadedMainTable)
local addtable = Decodedtable[1] 
 if addtable then
    local metatable = getmetatable(addtable)
    if metatable then
        print("GotMetaTable")
    else
        print("--MetaTable = nil")
    end
end

This script results in this in the output-->

--MetaTable = nil

So my question is: Does JSONEncode/Decode get ride of all meta tables? If not then how would you successfully get a meta table from a decoded JSON format?

0
This looks like a job for, BlueTaslem! Validark 1580 — 9y
0
Updated with code -- apologies, I've been without internet BlueTaslem 18071 — 9y

1 answer

Log in to vote
2
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

Metatables can't be meaningfully serialized (turned into text) because they have functions attached to them. (This is documented)

This is impossible because functions can be closures--they can refer to particular variables ruining in the program, which doesn't make sense to give to someone on another computer.

I would suggest making an extra property recording the "type" of the thing, and looking up the appropriate metatable and then applying it.


Here is an example of the kind of thing I am suggesting:

function setupHouse(data)
    setmetatable(data, houseMeta)
end

function setupLine(data)
    setmetatable(data, lineMeta)
end

-- `data` is the result of DecodeJSON.
-- It attaches the appropriate metatable
function receiveData(data)
    if data.type == "house" then
        setupHouse(data)
    elseif data.type == "line" then
        setupLine(data)
    elseif ... etc then

    end
end

Then you have to remember that when you serialize to JSON, you have to include the proper .type property.

You can shorten all of the elseifs using a dictionary:

local metas = {
    house = houseMeta,
    line = lineMeta,
    dog = dogMeta,
    -- etc
}

function receiveData(data)
    local meta = metas[data.type]
    if meta then
        setmetatable(data, meta)
    end
end

-- adds the `.type` property to `.data`, which is an object with (maybe) a metatable
-- (use :EncodeJSON on the `data` after this)
function sendData(data)
    local meta = getmetatable(data)
    for kind, m in pairs(metas) do
        if m == meta then
            data.type = kind
        end
    end
end
0
Could you please give me some example code to go off of. ClassicTheBlue 65 — 9y
Ad

Answer this question