Closed sle118 closed 7 years ago
In lua, it is not possible to call functions from a "string" variable, as far as I know. So the recursive search in _G is used to find the function declaration "somewhere" in the lua globals, based on the function name. In this specific context, we have a global function (the data push function) which was created in the lua startup, which means it will exist inside a sub-table that cannot be accessed from the top level _G. By reading recursively, the hope is that we'll hit the startup lua code's "globals" from which we'll extract the current function definition (and address). Now recursively processing _G and all internal tables is time consuming as it is a deep rabbit hole. From my experience, the lua startup code in openLuup is well above level 5, and was chosen arbitrarily.
I believe it would be possible to speed up processing by only searching inside tables with names '_G' and ignore all other ones.
You can dump the content of the lua _G variable using a function similar to the one here: https://gist.github.com/stuby/5445834#file-rprint-lua
this is very usefull when dealing with lua outside of a proper debugging environment!
I understand, you can do simple debug in ALTUI test Lua screen and type this for instance for n,v in pairs(_G) do print(n , type(v)) end return true
but remains not clear to me is 2 things :
1) why would the function not be in the immediate first level ( _G["function name"] for instance ? why would we need to walk up the tree ?
2) if the function is found in _G then called directly by ALTUI lua device, then what will be the lua context it is called in ? ( same as altui one ? ) , meaning will your function be able to access ALTUI internal global variables ?
To answer your questions 1) the function seems to be loaded at a lower level and I am unsure why. I am declaring the function in a standard way and it just 'lands' in the lower context. 2) the context that the function is called is the one where the function got declared. Basically, whatever is available in the start up, which is not much.
I have thought about another way to implement this, possibly better. It would be possible to resolve the function pointers when calling "_loadDataProviders", which could loop through the providers and pull the functions as they are found.
so I think I would re-write to something like this (untested!)
local function _loadDataProviders()
local str = luup.variable_get(ALTUI_SERVICE, "DataStorageProviders", lul_device) or "{}"
DataProviders = json.decode(str)
for k,v in pairs (DataProviders) do
if (v["callback"] ~= nil) then
local callback_fn = table_search(_G,DataProviders[provider]["callback"],"",0)
if callback_fn ~= nil then
DataProvidersCallbacks[DataProviders[provider]["callback"]] = callback_fn
end
end
end
end
Refactored the code to align logic around loading data providers. Will open a new PR.
see post for details http://forum.micasaverde.com/index.php/topic,35860.msg297561.html#msg297561