__requestQueue = {} _requestCount = 0 _Request = { command = "", currentTime = 0, timeOut = 2, id = '0' } local os = love.system.getOS() local __defaultErrorFunction = nil local isDebugActive = false JS = {} function JS.callJS(funcToCall) if(os == "Web") then print("callJavascriptFunction " .. funcToCall) end end --You can pass a set of commands here and, it is a syntactic sugar for executing many commands inside callJS, as it only calls a function --If you pass arguments to the func beyond the string, it will perform automatically string.format --Return statement is possible inside this structure --This will return a string containing a function to be called by JS.callJS local _unpack if(_VERSION == "Lua 5.1" or _VERSION == "LuaJIT") then _unpack = unpack else _unpack = table.unpack end function JS.stringFunc(str, ...) str = "(function(){"..str.."})()" if(#arg > 0) then str = str:format(_unpack(arg)) end str = str:gsub("[\n\t]", "") return str end --The call will store in the webDB the return value from the function passed --it timeouts local function retrieveJS(funcToCall, id) --Used for retrieveData function JS.callJS("FS.writeFile('"..love.filesystem.getSaveDirectory().."/__temp"..id.."', "..funcToCall..");") end --Call JS.newRequest instead function _Request:new(isPromise, command, onDataLoaded, onError, timeout, id) local obj = {} setmetatable(obj, self) obj.command = command obj.onError = onError or __defaultErrorFunction if not isPromise then retrieveJS(command, id) else JS.callJS(command) end obj.onDataLoaded = onDataLoaded obj.timeOut = (timeout == nil) and obj.timeOut or timeout obj.id = id function obj:getData() --Try to read from webdb return love.filesystem.read("__temp"..self.id) end function obj:purgeData() --Data must be purged for not allowing old data to be retrieved love.filesystem.remove("__temp"..self.id) end function obj:update(dt) self.timeOut = self.timeOut - dt local retData = self:getData() if((retData ~= nil and retData ~= "nil") or self.timeOut <= 0) then if(retData ~= nil and retData:match("ERROR") == nil) then if isDebugActive then print("Data has been retrieved "..retData) end self.onDataLoaded(retData) else self.onError(self.id, retData) end self:purgeData() return false else return true end end return obj end --Place this function on love.update and set it to return if it returns false (This API is synchronous) function JS.retrieveData(dt) local isRetrieving = #__requestQueue ~= 0 local deadRequests = {} for i = 1, #__requestQueue do local isUpdating =__requestQueue[i]:update(dt) if not isUpdating then table.insert(deadRequests, i) end end for i = 1, #deadRequests do if(isDebugActive) then print("Request died: "..deadRequests[i]) end table.remove(__requestQueue, deadRequests[i]) end return isRetrieving end --May only be used for functions that don't return a promise function JS.newRequest(funcToCall, onDataLoaded, onError, timeout, optionalId) if(os ~= "Web") then return end table.insert(__requestQueue, _Request:new(false, funcToCall, onDataLoaded, onError, timeout or 5, optionalId or _requestCount)) end --This function can be handled manually (in JS code) --How to: add the function call when your events resolve: FS.writeFile("Put love.filesystem.getSaveDirectory here", "Pass a string here (NUMBER DONT WORK")) --Or it can be handled by Lua, it auto sets your data if you write the following command: -- _$_(yourStringOrFunctionHere) function JS.newPromiseRequest(funcToCall, onDataLoaded, onError, timeout, optionalId) if(os ~= "Web") then return end optionalId = optionalId or _requestCount funcToCall = funcToCall:gsub("_$_%(", "FS.writeFile('"..love.filesystem.getSaveDirectory().."/__temp"..optionalId.."', ") table.insert(__requestQueue, _Request:new(true, funcToCall, onDataLoaded, onError, timeout or 5, optionalId)) end --It receives the ID from ther request --Don't try printing the request.command, as it will execute the javascript command function JS.setDefaultErrorFunction(func) __defaultErrorFunction = func end JS.setDefaultErrorFunction(function(id, error) if( isDebugActive ) then local msg = "Data could not be loaded for id:'"..id.."'" if(error)then msg = msg.."\nError: "..error end print(msg) end end)