Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Datasaver module doesn't load — Gideros Forum

Datasaver module doesn't load

data = dataSaver.loadValue("data")


main.lua:226: attempt to call a nil value
stack traceback:
main.lua:226: in function



It works... mmm... two years ago)

Sorry, i haven't tracked what happened for two years:( It's my fault, I know.

May be anyone knows what should i change to start it works for me?

Comments

  • keszeghkeszegh Member
    edited February 2024
    since luau, modules won't work i think. i changed my dataSaver file so that it is a class, so it starts like this, i think you get the point:
    --module("dataSaver", package.seeall)
    DataSaver = Core.class()
     
    function DataSaver.init()
    end
     
    function DataSaver.saveValue(key, value)
  • @unlying if I recall both answers apply.
    you should load the json plugin in your project and make datasaver a class or a set of functions as in the attached file.
    If I am not mistaken there is also the need to change Json to json (without capital).

    I think this should work :)
    lua
    lua
    dataSaverU.lua
    3K

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • is it possible to resolve this data saver in luau?
  • hgy29hgy29 Maintainer
    @Xman, it depends on your use case. Saving strings/tables/numbers should be ok, but not functions nor userdata. What error do you get ?
  • function table.load( sfile )
    local tables, err, _
    -- catch marker for stringtable
    if string.sub( sfile,-3,-1 ) == "--|" then
    tables,err = loadstring( sfile )
    else
    tables,err = loadfile( sfile )
    end

    print('-----', err, tables, sfile)


    it print in Lua, that's correct
    ----- cannot open |D|sys.dat: No such file or directory nil |D|sys.dat
    but in luau, it seems loadfile not work
    ----- nil |D|sys.dat |D|sys.dat
  • hgy29hgy29 Maintainer
    edited February 2024
    Just checked and loadfile works here, actually Gideros uses it internally to mimic 'require' call. By the look of the error, it seems to complain that the searched file (sys.dat) doesn't exists in the document folder.
    I misread your post, sorry, so in both cases it fails, but in luau the error message is absent. Yes it is that way in luau, it just returns nil.
  • Then it can not tell if loadfile succeed.
    I just hear about luau and have no ideas on how to migrate Lua to luau.
    Just searched and found this document
    https://luau-lang.org/compatibility
    loadfile, dofile removed for sandboxing, no direct file access

    Is there some guides on migration to luau if it's not possible to have a Lua release of engine.
  • @Xman what if you use io.open? Take a look at the datasaver functions posted above

    I am in the middle of a lua to luau conversion, and gideros so far is telling me every issue one by one just by running the project, fixing the line, rerunning the project and so on.. it's tedious but it's feasible. :smile:

    Likes: Xman

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    @Xman, you could just check if loadfile returned a function or not maybe ?

    Likes: Xman

    +1 -1 (+1 / -0 )Share on Facebook
  • @pie @hgy29 Thanks for your supports.
    Currently, change

    require 'aaaa.bbbb' to require 'aaaa/bbbb'
    check if loadfile returned a function or not

    make the project run.
    I can not guarantee every line of scripts has tested.
    So welcome to share your experiences on migrate to luau on the forum.

    If everyone shares some experiences, we will have a migrate guide.
  • hgy29hgy29 Maintainer
    I will have a look at what I can do within Gideros to have require and loadfile behave more like lua 5.1

    Likes: Xman

    +1 -1 (+1 / -0 )Share on Facebook
  • XmanXman Member
    edited February 2024
    for char in string.gfind("ABC", "([%z\1-\127\194-\244][\128-\191]*)") do
    print(char)
    end

    gfind is not support in luau

    output
    attempt to call a nil value
  • Xman said:

    for char in string.gfind("ABC", "([%z\1-\127\194-\244][\128-\191]*)") do
    print(char)
    end

    --for char in string.gfind("ABC", "([%z\1-\127\194-\244][\128-\191]*)") do
    for char in string.gmatch("ABC", "([%z\1-\127\194-\244][\128-\191]*)") do
    	print(char)
    end
    added to https://wiki.gideros.rocks/index.php/Lua_to_Luau_conversion_guide

    ;)

    Likes: Xman, pie

    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
    +1 -1 (+2 / -0 )Share on Facebook
  • keszeghkeszegh Member
    i'm using dataSaver which in turn uses json.encode and i get in the saved file such a table part:
    "target":{"1":true,"2":false,"3":false,"1":true,"3":false,"2":false,"fx2":false,"fx1":true}

    how is it possible that the same index appears multiple times? (i cannot pinpoint so far if i do anything strange, in any case it should not happen whatever i do in my code i guess)

    also json.decode seems to decode this incorrectly (e.g., no value is given to "1"), which is the bigger problem.

    any ideas?

  • hgy29hgy29 Maintainer
    Wild guess: your lua table before encoding contains both 1 as a number and "1" as a string, but json only allows string keys so both are written as a string in the resulting file.
    When reading back, one of those keys will be lost since they are the same.

    Test:
    require "json"
    local target={ [1]=true, ["1"]=true}
    for k,v in pairs(target) do print(k,v) end
    local jsont=json.encode(target)
    print(jsont)
    target=json.decode(jsont)
    for k,v in pairs(target) do print(k,v) end
    print("String 1",target["1"])
    print("Number 1",target[1])

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • MoKaLuxMoKaLux Member
    edited 3:48PM
    keszegh I use this to save my data:
    save_prefs.lua
    require "json"
     
    function saveData(filepath, value)
    	local contents = json.encode(value)
    	local file = io.open(filepath, "w") -- create file
    	file:write(contents) -- save json string in file
    	io.close(file)
    end
     
    function getData(filepath)
    	local result, value
    	local file = io.open(filepath, "r")
    	if file then
    		local contents = file:read("*a") -- read contents
    --		value = json.decode(contents) -- decode json
    		result, value = pcall(json.decode, contents) -- try to decode json
    		io.close(file)
    	end
    	return result, value
    end
    This seems to work pretty well for my use case. Some more code:
    init.lua
    g_gconfigfilepath = "|D|myprefs.txt"
     
    g_oprefcanvasw = 480 -- prefered default canvas size
    g_oprefcanvash = 270 -- prefered default canvas size
    g_prefcanvasw = 96 -- prefered default canvas size
    g_prefcanvash = 96 -- prefered default canvas size
    main.lua
    function myLoadgPrefs() -- GENERAL
    	local _result, mydata = getData(g_gconfigfilepath) -- try to read information from file
    	if not mydata then -- if no general prefs file, create it
    		mydata = {}
    		-- general prefs
    		mydata.g_oprefcanvasw = g_oprefcanvasw or 320
    		mydata.g_oprefcanvash = g_oprefcanvash or 240
    		mydata.g_prefcanvasw = g_prefcanvasw or 128
    		mydata.g_prefcanvash = g_prefcanvash or 128
    		-- create file and save datas
    		saveData(g_gconfigfilepath, mydata) -- create file and save datas
    		myLoadgPrefs() -- reload
    	else -- general prefs file exists, use it!
    		g_oprefcanvasw = mydata.g_oprefcanvasw or 320
    		g_oprefcanvash = mydata.g_oprefcanvash or 240
    		g_prefcanvasw = mydata.g_prefcanvasw or 128
    		g_prefcanvash = mydata.g_prefcanvash or 128
    	end
    end
     
    function mySavegPrefs() -- GENERAL
    	local mydata = {} -- clear the table
    	-- general prefs
    	mydata.g_oprefcanvasw = g_oprefcanvasw or 320
    	mydata.g_oprefcanvash = g_oprefcanvash or 240
    	mydata.g_prefcanvasw = g_prefcanvasw or 128
    	mydata.g_prefcanvash = g_prefcanvash or 128
    	-- save new data
    	saveData(g_gconfigfilepath, mydata)
    end
    When my app starts I load the the default values:
    	-- load general prefs
    	myLoadgPrefs()
    Then any time I need to save my prefs some places in my code I use:
    mySavegPrefs()
    Some output example:
    {
    	"g_persp":false,
    	"g_alphablend":true,
    	"g_outline":false,
    	"g_modelscalez":0.432804,
    	"g_partsstyle":[
    		{
    			"offsety":0,
    			"isvisible":true,
    			"scalez":1,
    			"scalex":1,
    			"alpha":255,
    		},
    		{
    			"offsety":0,
    			"isvisible":true,
    			"scalez":1,
    		}
    	],
    	"g_blue":255,
    	"g_alpha":255,
    	"g_canvash":256,
    	"g_canvasw":256,
    }
    https://wiki.gideros.rocks/index.php/Ftf_snippets#JSON_V2_.40mokalux
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • keszeghkeszegh Member
    thanks @hgy29 and @MoKaLux , i think @hgy29 is right, initially the table has only values for indices 1,2 (As an array), then new value for 'fx1' is added and then this is saved. then when i load back i guess my app does not recognize that there is a '1' index and adds a 1 index and when it is saved next they become the same.
    this will help me to make a workaround (checking and merging 1 and '1' if needed etc).
  • keszeghkeszegh Member
    edited 6:00PM
    yes, a code like this illustrates well what happens:
    require("json")
    t1={1,2}
    t1s=json.encode(t1)
    print(t1s)
    t2=json.decode(t1s)
    t2["fx"]=4
    t2s=json.encode(t2)
    print(t2s)
    t3=json.decode(t2s)
    t3[1]=3
    t3s=json.encode(t3)
    print(t3s)
    t4=json.decode(t3s)
    t4s=json.encode(t4)
    print(t4s)
    and the output is the following:
    [1,2]
    {"1":1,"2":2,"fx":4}
    {"1":3,"1":1,"fx":4,"2":2}
    {"1":1,"fx":4,"2":2}

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.