mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
262 lines
5.8 KiB
Lua
262 lines
5.8 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
local urlobj = _G.pac_urlobj
|
|
|
|
local TIMEOUT_VALUE = CreateConVar('pac_objdl_timeout', '15', {FCVAR_ARCHIVE}, 'OBJ download timeout in seconds')
|
|
local CACHE_OBJS = CreateConVar('pac_obj_cache', '1', {FCVAR_ARCHIVE}, 'DEBUG: Cache Object files on disk. Disables disk cache access (like cache does not exist in code)')
|
|
local QUEUEITEM = {}
|
|
|
|
-- Warning: This code is concurrency hell
|
|
-- Either the decode from the cache or the decode from the web could finish first / last
|
|
-- And the web request handler will often decide to not override the cache
|
|
|
|
local function CreateQueueItem(url)
|
|
local queueItem = {}
|
|
setmetatable (queueItem, { __index = QUEUEITEM })
|
|
|
|
queueItem:Initialize (url)
|
|
|
|
return queueItem
|
|
end
|
|
|
|
function QUEUEITEM:Initialize (url)
|
|
self.Url = url
|
|
self.Data = nil
|
|
self.UsingCachedData = false
|
|
|
|
-- Cache
|
|
self.CacheDecodeFinished = false
|
|
|
|
-- Download
|
|
self.DownloadAttemptCount = 0
|
|
self.DownloadTimeoutTime = 0
|
|
self.Downloading = false
|
|
self.DownloadFinished = false
|
|
|
|
-- Status
|
|
self.Status = nil
|
|
self.Finished = false
|
|
|
|
-- Model
|
|
self.Model = nil
|
|
|
|
-- Decoding parameters
|
|
self.GenerateNormals = false
|
|
|
|
-- Callbacks
|
|
self.CallbackSet = {}
|
|
self.DownloadCallbackSet = {}
|
|
self.StatusCallbackSet = {}
|
|
end
|
|
|
|
function QUEUEITEM:GetUrl ()
|
|
return self.Url
|
|
end
|
|
|
|
-- Cache
|
|
function QUEUEITEM:BeginCacheRetrieval ()
|
|
if not CACHE_OBJS:GetBool() then return end
|
|
self.Data = urlobj.DataCache:GetItem(self.Url)
|
|
if not self.Data then return end
|
|
|
|
self.Model = urlobj.CreateModelFromObjData(self.Data, self.GenerateNormals,
|
|
function (finished, statusMessage)
|
|
if self:IsFinished () then return end
|
|
if self.DownloadFinished and not self.UsingCachedData then return end
|
|
|
|
if finished and not self.DownloadFinished then
|
|
self:SetStatus ("")
|
|
else
|
|
self:SetStatus ("Cached model: " .. statusMessage)
|
|
end
|
|
|
|
if self.DownloadFinished and self.UsingCachedData then
|
|
self:SetFinished (finished)
|
|
end
|
|
|
|
if finished then
|
|
self.CacheDecodeFinished = true
|
|
end
|
|
end
|
|
)
|
|
|
|
self:DispatchCallbacks (self.Model)
|
|
end
|
|
|
|
function QUEUEITEM:IsCacheDecodeFinished ()
|
|
return self.CacheDecodeFinished
|
|
end
|
|
|
|
-- Download
|
|
function QUEUEITEM:AbortDownload ()
|
|
self.Downloading = false
|
|
|
|
self:SetStatus ("Download aborted")
|
|
end
|
|
|
|
function QUEUEITEM:BeginDownload ()
|
|
if self:IsDownloading () then return end
|
|
|
|
self:SetStatus ("Downloading")
|
|
|
|
self.Downloading = true
|
|
self.DownloadTimeoutTime = pac.RealTime + TIMEOUT_VALUE:GetFloat()
|
|
self.DownloadAttemptCount = self.DownloadAttemptCount + 1
|
|
|
|
local function success(data)
|
|
if not self.Downloading then return end
|
|
self.Downloading = false
|
|
self.DownloadFinished = true
|
|
|
|
pac.dprint("downloaded model %q %s", self.Url, string.NiceSize(#data))
|
|
pac.dprint("%s", data)
|
|
|
|
self:DispatchDownloadCallbacks ()
|
|
self:ClearDownloadCallbacks ()
|
|
|
|
self.UsingCachedData = self.Data == data
|
|
|
|
if self.UsingCachedData then
|
|
if self.CacheDecodeFinished then
|
|
self:SetFinished (true)
|
|
end
|
|
else
|
|
self.Data = data
|
|
|
|
if CACHE_OBJS:GetBool() then
|
|
urlobj.DataCache:AddItem (self.Url, self.Data)
|
|
end
|
|
|
|
self.Model = urlobj.CreateModelFromObjData(self.Data, self.GenerateNormals,
|
|
function (finished, statusMessage)
|
|
self:SetStatus (statusMessage)
|
|
self:SetFinished (finished)
|
|
|
|
if self:IsFinished () then
|
|
self:ClearStatusCallbacks ()
|
|
end
|
|
end
|
|
)
|
|
end
|
|
|
|
self:DispatchCallbacks (self.Model)
|
|
self:ClearCallbacks ()
|
|
end
|
|
|
|
local function failure(err, fatal)
|
|
-- dont bother with servezilf he said No
|
|
if fatal then
|
|
self.DownloadAttemptCount = 100
|
|
end
|
|
|
|
self.DownloadTimeoutTime = 0
|
|
self:SetStatus ("Failed - " .. err)
|
|
end
|
|
|
|
pac.HTTPGet(self.Url, success, failure)
|
|
end
|
|
|
|
function QUEUEITEM:GetDownloadAttemptCount ()
|
|
return self.DownloadAttemptCount
|
|
end
|
|
|
|
function QUEUEITEM:IsDownloading ()
|
|
return self.Downloading
|
|
end
|
|
|
|
function QUEUEITEM:HasDownloadTimedOut ()
|
|
return self:IsDownloading () and pac.RealTime > self.DownloadTimeoutTime
|
|
end
|
|
|
|
-- Status
|
|
function QUEUEITEM:GetStatus ()
|
|
return self.Status
|
|
end
|
|
|
|
function QUEUEITEM:IsFinished ()
|
|
return self.Finished
|
|
end
|
|
|
|
function QUEUEITEM:SetStatus (status)
|
|
if self.Status == status then return self end
|
|
|
|
self.Status = status
|
|
|
|
self:DispatchStatusCallbacks (self.Finished, self.Status)
|
|
|
|
return self
|
|
end
|
|
|
|
function QUEUEITEM:SetFinished (finished)
|
|
if self.Finished == finished then return self end
|
|
|
|
self.Finished = finished
|
|
|
|
self:DispatchStatusCallbacks (self.Finished, self.Status)
|
|
|
|
return self
|
|
end
|
|
|
|
-- Model
|
|
function QUEUEITEM:GetModel ()
|
|
return self.Model
|
|
end
|
|
|
|
-- Callbacks
|
|
function QUEUEITEM:AddCallback (callback)
|
|
self.CallbackSet [callback] = true
|
|
|
|
if self.Model then
|
|
callback (self.Model)
|
|
end
|
|
end
|
|
|
|
function QUEUEITEM:AddDownloadCallback (downloadCallback)
|
|
self.DownloadCallbackSet [downloadCallback] = true
|
|
end
|
|
|
|
function QUEUEITEM:AddStatusCallback (statusCallback)
|
|
self.StatusCallbackSet [statusCallback] = true
|
|
|
|
statusCallback (self.Finished, self.Status)
|
|
end
|
|
|
|
function QUEUEITEM:ClearCallbacks ()
|
|
self.CallbackSet = {}
|
|
end
|
|
|
|
function QUEUEITEM:ClearDownloadCallbacks ()
|
|
self.DownloadCallbackSet = {}
|
|
end
|
|
|
|
function QUEUEITEM:ClearStatusCallbacks ()
|
|
self.StatusCallbackSet = {}
|
|
end
|
|
|
|
function QUEUEITEM:DispatchCallbacks (...)
|
|
for callback, _ in pairs (self.CallbackSet) do
|
|
callback (...)
|
|
end
|
|
end
|
|
|
|
function QUEUEITEM:DispatchDownloadCallbacks (...)
|
|
for downloadCallback, _ in pairs (self.DownloadCallbackSet) do
|
|
downloadCallback (...)
|
|
end
|
|
end
|
|
|
|
function QUEUEITEM:DispatchStatusCallbacks (...)
|
|
for statusCallback, _ in pairs (self.StatusCallbackSet) do
|
|
statusCallback (...)
|
|
end
|
|
end
|
|
|
|
return CreateQueueItem |