• Announcement: Lua.org now officially recommends this forum as a meeting place for the Lua community
  • The forum is currently open to new registrations. The registration will close for a short period of time when reaching 500 active members, to upgrade the server resources.

Function return value is coming out of a subfunction (1 Viewer)

Tainor

Newcomer
Joined
Jan 13, 2021
Messages
1
Reaction score
0
I am not quite sure whether the thread title fits perfectly, but I am not entirely sure how else I could call it.

Lua:
local meta = FindMetaTable("Player")

function meta:GetCharacterTable()
    if not self:IsPlayer() then return {} end

    local q = db:query("SELECT * FROM sid_" .. self:SteamID64() .. ";")
    
    function q:onSuccess(data)
        return data
    end

    q:start()
end

I know why it isn't working. It isn't working because I have my return value in a subfunction, but i would like the function meta:GetCharacterTable() to return the data table. Everything else of the Code does work. For example if I would put PrintTable(data) instead of return data I at least get the table printed to my console, but I want the data table to be returned when executing meta:GetCharacterTable(). Could somebody please hep me with it?

Thank you.
 
Solution
I'm not sure I understood how this works, but it seems to me that q:eek:nSuccess() is a callback that meta:GetCharacterTable() sets, and that will be called at some point in time after meta:GetCharacterTable() returns, presumably in a main event loop at the occurrence of a 'success'.

If this is the case, there is no way that meta:GetCharacterTable() itself can return the data table. The function q:eek:nSuccess() returns it
to its caller, whoever this is, but this happens (if at all) only after meta:GetCharacterTable() has already returned.

What you should probably do in q:eek:nSuccess() is saving the data somewhere instead of returning it, and then retrieve it after the 'success' event has occurred.

stetre

Member
Rank: I
Joined
Jan 8, 2020
Messages
45
Reaction score
28
Location
Italy
Website
github.com
I'm not sure I understood how this works, but it seems to me that q:eek:nSuccess() is a callback that meta:GetCharacterTable() sets, and that will be called at some point in time after meta:GetCharacterTable() returns, presumably in a main event loop at the occurrence of a 'success'.

If this is the case, there is no way that meta:GetCharacterTable() itself can return the data table. The function q:eek:nSuccess() returns it
to its caller, whoever this is, but this happens (if at all) only after meta:GetCharacterTable() has already returned.

What you should probably do in q:eek:nSuccess() is saving the data somewhere instead of returning it, and then retrieve it after the 'success' event has occurred.
 
Solution

dinsdale247

Moderator
Staff member
Community Patron
Creator of WinLua
Joined
Nov 17, 2020
Messages
73
Reaction score
31
Location
Victoria BC
Website
winlua.net
This looks to be an asynchronous call. There is no guarantee that the data will be available when "meta:GetCharacterTable()" returns. You may need to employ strategies to ensure your data is there:
- Use a callback function - This is ALWAYS the preference because you are likely in an asynchronous environment.
- Poll to see if the data is available.
- "sleep" for a chunk of time and hope that the data is there. This is the last resort and should only be used if you need a short period and are guaranteed success. Sleeping is better used with polling (see below).

A callback function would likely be part of whatever calls meta:GetCharacterTable() like a UI. Here is an example if you wanted to wait in this module until the callback is complete. Waiting is not recommended; this code is just for example sake. Since this is likely in a game or a UI, waiting is probably unnecessary. There is also likely already a timeout/error function for the "db".

Lua:
local meta = FindMetaTable("Player")
local completeFlag = false

local function useMyData(data)
  --Display data in a UI
  -- make a decision
--store the data
completeFlag = true
end

function meta:GetCharacterTable()
    completeFlag = false
    if not self:IsPlayer() then return {} end

    local q = db:query("SELECT * FROM sid_" .. self:SteamID64() .. ";")
  
    function q:onSuccess(data)
        useMyData(data)
    end

    q:start()
end

--Do some stuff
meta:GetCharacterTable()

local count = 1
repeat
    if not completeFlag then
        sleep(100) --milliseconds
    end
    count=count+1
until completeFlag or count > 100

if count > 100 then
    --ERROR condition
end
 
Top