xurfer/ext/http-lovr moves http.request to its own thread
This commit is contained in:
parent
6cfdefe050
commit
497960163a
8 changed files with 135 additions and 23 deletions
10
xurfer.sh
10
xurfer.sh
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
export DEBUG=1
|
||||||
cd xurfer
|
cd xurfer
|
||||||
#appimage-run ~/apps/lovr*.AppImage . test.glb
|
runtime="/home/leon/apps/lovr-v0.18.0-x86_64.AppImage"
|
||||||
#appimage-run ~/apps/lovr*.AppImage . https://snips.sh/f/_U5-XctEVE?r=1
|
#appimage-run $runtime . test.glb
|
||||||
#appimage-run ~/apps/lovr*.AppImage . http://localhost:8080/simple-a.glb
|
appimage-run $runtime . https://snips.sh/f/_U5-XctEVE?r=1
|
||||||
appimage-run ~/apps/lovr*.AppImage . http://localhost:8080/level3-4-playaudio.glb
|
#appimage-run $runtime . http://localhost:8080/simple-a.glb
|
||||||
|
#appimage-run $runtime . http://localhost:8080/level3-4-playaudio.glb
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,19 @@ ecs.init = function()
|
||||||
baseEntify.filter = ecs.rejectAll('commit')
|
baseEntify.filter = ecs.rejectAll('commit')
|
||||||
baseEntify.updatethread = true
|
baseEntify.updatethread = true
|
||||||
function baseEntify:onAdd(obj)
|
function baseEntify:onAdd(obj)
|
||||||
|
|
||||||
obj.commit = api.util.commit( api.world, obj, api )
|
obj.commit = api.util.commit( api.world, obj, api )
|
||||||
api.world.commit = api.util.commit( api.world, false, api)
|
api.world.commit = api.util.commit( api.world, false, api)
|
||||||
|
api.world.get = function(filter)
|
||||||
|
local found = false
|
||||||
|
foreach( api.world.entities, function(k,obj)
|
||||||
|
if type(obj) == 'table' then
|
||||||
|
if filter(obj) then found = obj end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return found
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
ecs.addSystem( api.world, baseEntify )
|
ecs.addSystem( api.world, baseEntify )
|
||||||
end
|
end
|
||||||
|
|
@ -15,7 +26,6 @@ end
|
||||||
ecs.clear = function()
|
ecs.clear = function()
|
||||||
api.ext.exec("onClear")
|
api.ext.exec("onClear")
|
||||||
api.ecs.clearEntities( api.world )
|
api.ecs.clearEntities( api.world )
|
||||||
api.ecs.update( api.world )
|
|
||||||
api.world.commit()
|
api.world.commit()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ return {
|
||||||
obj = obj or {}
|
obj = obj or {}
|
||||||
print("[i] loading URL: " .. URI.url)
|
print("[i] loading URL: " .. URI.url)
|
||||||
obj.URL = api.url.parse(URI.url)
|
obj.URL = api.url.parse(URI.url)
|
||||||
|
trace(obj.URL)
|
||||||
obj.URLResponse = {}
|
obj.URLResponse = {}
|
||||||
local protocol = "file"
|
local protocol = "file"
|
||||||
foreach( api.protocol, function(name, p)
|
foreach( api.protocol, function(name, p)
|
||||||
|
|
@ -33,7 +34,8 @@ return {
|
||||||
if obj.URL.protocol == 'file' then
|
if obj.URL.protocol == 'file' then
|
||||||
return obj.commit('onURI')
|
return obj.commit('onURI')
|
||||||
end
|
end
|
||||||
local status, data, headers = protocol.request(URI.url)
|
protocol.request(URI.url, nil,
|
||||||
|
function(status,data,headers)
|
||||||
obj.URLResponse = {
|
obj.URLResponse = {
|
||||||
ok = (status ~= nil and status >= 200 and status < 300),
|
ok = (status ~= nil and status >= 200 and status < 300),
|
||||||
status = status,
|
status = status,
|
||||||
|
|
@ -43,6 +45,8 @@ return {
|
||||||
api.ecs.add( api.world, obj )
|
api.ecs.add( api.world, obj )
|
||||||
obj.commit('onURI')
|
obj.commit('onURI')
|
||||||
end
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
76
xurfer/ext/http-lovr/main.lua
Normal file
76
xurfer/ext/http-lovr/main.lua
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
-- this extension will make network requests run async in LoVR runtime
|
||||||
|
|
||||||
|
local api = ...
|
||||||
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
local http
|
||||||
|
http = {
|
||||||
|
name = "http-lovr",
|
||||||
|
enabled = true,
|
||||||
|
cache = {},
|
||||||
|
|
||||||
|
init = function()
|
||||||
|
if lovr ~= nil then
|
||||||
|
|
||||||
|
http.initThreadLovr()
|
||||||
|
api.protocol.http = {
|
||||||
|
request = function(url,opts,cb)
|
||||||
|
http.cache[ url ] = { url = url, opts = opts }
|
||||||
|
http.channel:push( http.cache[url] ) -- send to thread
|
||||||
|
http.cache[ url ].cb = cb -- stick callback to req
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
initThreadLovr = function()
|
||||||
|
threadCode = [[
|
||||||
|
local lovr = require("lovr")
|
||||||
|
require 'lovr.filesystem'
|
||||||
|
local util = require("util")
|
||||||
|
local http = require("http")
|
||||||
|
lovr.thread = require 'lovr.thread'
|
||||||
|
lovr.timer = require 'lovr.timer'
|
||||||
|
local channel = lovr.thread.getChannel('http')
|
||||||
|
while true do
|
||||||
|
local req, present = channel:peek()
|
||||||
|
if present and req.status == nil then
|
||||||
|
req.status = -1
|
||||||
|
local status, data, headers = http.request(req.url)
|
||||||
|
req.status = status
|
||||||
|
req.data = data
|
||||||
|
req.headers = headers
|
||||||
|
channel:pop() -- remove last
|
||||||
|
channel:push(req) -- re-push but with status (which thread ignores)
|
||||||
|
lovr.timer.sleep(.1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
|
http.channel = lovr.thread.getChannel('http')
|
||||||
|
http.thread = lovr.thread.newThread(threadCode)
|
||||||
|
http.thread:start()
|
||||||
|
end,
|
||||||
|
|
||||||
|
update = function()
|
||||||
|
if lovr ~= nil then
|
||||||
|
|
||||||
|
local msg
|
||||||
|
local res, present = http.channel:peek()
|
||||||
|
if present and res.status ~= nil then
|
||||||
|
msg = http.channel:pop()
|
||||||
|
-- we got our urlrequest response
|
||||||
|
if http.cache[ msg.url ] then
|
||||||
|
http.cache[ msg.url ].cb( msg.status, msg.data, msg.headers )
|
||||||
|
http.cache[ msg.url ] = nil
|
||||||
|
else
|
||||||
|
error("msg-object was not found in cache")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return http
|
||||||
|
|
@ -19,9 +19,9 @@ xrfimpl = {
|
||||||
trace("\n[xrf] href was clicked: " .. href)
|
trace("\n[xrf] href was clicked: " .. href)
|
||||||
api.ext.exec("onClick", obj, collider)
|
api.ext.exec("onClick", obj, collider)
|
||||||
|
|
||||||
--local ok = xrf.level2.load( href, obj, api.ext.URI.current, xrfimpl.onLoad)
|
local ok = xrf.level2.load( href, obj, api.ext.URI.current, xrfimpl.onLoad)
|
||||||
-- or
|
or
|
||||||
-- xrf.level4.import( href, obj, api.ext.URI.current, xrfimpl.onImport)
|
xrf.level4.import( href, obj, api.ext.URI.current, xrfimpl.onImport)
|
||||||
|
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|
@ -48,8 +48,17 @@ xrfimpl = {
|
||||||
|
|
||||||
onImport = function(absoluteHref,obj)
|
onImport = function(absoluteHref,obj)
|
||||||
trace("[xrf.level4] ! (import) operator found")
|
trace("[xrf.level4] ! (import) operator found")
|
||||||
|
local filter = function(o)
|
||||||
|
return (o.URL ~= nil and o.URL.URN:gsub("#.*","") == absoluteHref:gsub("#.*",""))
|
||||||
|
end
|
||||||
|
local obj = api.world.get(filter)
|
||||||
|
if obj then
|
||||||
|
obj.URL = url.parse(absoluteHref) -- re-parse to detect media fragment change
|
||||||
|
xrfimpl.onAudioFile(obj)
|
||||||
|
else
|
||||||
api.ecs.add( api.world, { URI = { url = absoluteHref, method = 'GET', target = obj } })
|
api.ecs.add( api.world, { URI = { url = absoluteHref, method = 'GET', target = obj } })
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
-- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
-- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
--
|
||||||
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
--
|
--
|
||||||
-- The views and conclusions contained in the software and documentation are those of the
|
-- The views and conclusions contained in the software and documentation are those of the
|
||||||
|
|
@ -145,15 +146,19 @@ function url.parse(url_string)
|
||||||
return URI
|
return URI
|
||||||
end
|
end
|
||||||
|
|
||||||
url.getAbsolute = function(href,referer)
|
url.getAbsolute = function(href,referer,keephash)
|
||||||
local URL = url.parse(href)
|
local URL = url.parse(href)
|
||||||
local URLref = url.parse(referer)
|
local URLref = url.parse(referer)
|
||||||
if referer ~= nil and URL.protocol == 'file' and URLref.protocol ~= 'file' then
|
if referer ~= nil and URL.protocol == 'file' and URLref.protocol ~= 'file' then
|
||||||
URL.protocol = URLref.protocol
|
URL.protocol = URLref.protocol
|
||||||
URL.domain = URLref.domain
|
URL.domain = URLref.domain
|
||||||
URL.string = URLref.protocol .. '://' .. URLref.domain .. '/' .. URL.path .. URL.hash
|
URL.string = URLref.protocol .. '://' .. URLref.domain .. '/' .. URL.path .. URL.hash
|
||||||
|
if keephash then
|
||||||
|
URL.URN = URL.string
|
||||||
|
else
|
||||||
URL.URN = URL.string:gsub("#.*", "")
|
URL.URN = URL.string:gsub("#.*", "")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
return URL
|
return URL
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,14 @@ backend.resourcePath = "lovr/" .. backend.resourcePath
|
||||||
api.iui = iui
|
api.iui = iui
|
||||||
api.backend = backend
|
api.backend = backend
|
||||||
-- decorate api
|
-- decorate api
|
||||||
api.protocol.http = require('http')
|
local http = require('http')
|
||||||
|
api.protocol.http = {
|
||||||
|
request = function(url,opts,cb)
|
||||||
|
local status, data, headers = http.request(url,opts)
|
||||||
|
if cb == nil then print("error: api.protocol.http.request called without callback") end
|
||||||
|
cb(status,data,headers)
|
||||||
|
end
|
||||||
|
}
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
ecs.filterDraw = ecs.requireAll('drawthread')
|
ecs.filterDraw = ecs.requireAll('drawthread')
|
||||||
ecs.filterUpdate = ecs.requireAll('updatethread')
|
ecs.filterUpdate = ecs.requireAll('updatethread')
|
||||||
|
|
@ -49,7 +56,6 @@ function lovr.load()
|
||||||
end
|
end
|
||||||
|
|
||||||
function lovr.update(dt)
|
function lovr.update(dt)
|
||||||
|
|
||||||
ecs.update( api.world, dt, ecs.filterUpdate )
|
ecs.update( api.world, dt, ecs.filterUpdate )
|
||||||
|
|
||||||
iui.beginFrame(dt)
|
iui.beginFrame(dt)
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ function util.traverseXML( parsedXml, cb)
|
||||||
return function() return parent end
|
return function() return parent end
|
||||||
end)(parent)
|
end)(parent)
|
||||||
end
|
end
|
||||||
cb(struct,raw)
|
cb(struct,node)
|
||||||
end,
|
end,
|
||||||
'___children'
|
'___children'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue