ExperimentalGear/scripts/titlescreen/fields/boot/selftestfield.lua

134 lines
3.9 KiB
Lua
Raw Normal View History

require("common.class")
local Util = require("common.util")
local ServiceField = require("titlescreen.fields.service.servicefield")
---@class SelfTestStatusEnum
SelfTestStatusEnum = {
IDLE = 1,
INPROGRESS = 2,
OK = 3,
PASS = 4,
ERROR = 5
}
2022-04-24 01:39:48 +02:00
local function statusToString(status)
local statusName = {"IDLE", "INPROGRESS", "OK", "PASS", "ERROR"}
return statusName[status]
end
---@class SelfTestField: ServiceField
2022-04-24 01:39:48 +02:00
---@field checkTask nil|fun(obj: any): SelfTestStatusEnum # a function that will run asynchronously on activating the Field
---@field status SelfTestStatusEnum
2022-04-24 01:39:48 +02:00
---@field onStatusChange nil|fun(status) # a callback function on finishing the checkTask
---@field _thread thread
---@field _timer number
local SelfTestField = {
2022-04-24 01:39:48 +02:00
__tostring = function () return "SelfTestField" end,
COLOR_INPROGRESS = {255, 255, 255, 255},
COLOR_OK = {0, 255, 0, 255},
COLOR_PASS = {255, 255, 0, 255},
COLOR_ERROR = {255, 0, 0, 255},
INPROGRESS_FREQ = 1 / 20, --20Hz
}
---Create a new SelfTestField instance
---@param o? table
---@return SelfTestField
function SelfTestField.new(o)
o = o or {}
o.status = o.status or SelfTestStatusEnum.IDLE
o._timer = 0
2022-04-24 01:39:48 +02:00
o._thread = nil
assert((not o.onStatusChange) or (o.checkTask and o.onStatusChange),
"Failed to construct SelfTestField, checkTask is mandatory when onStatusChange is defined!\n" .. debug.traceback()
)
return CreateInstance(SelfTestField, o, ServiceField)
end
2022-04-24 01:39:48 +02:00
function SelfTestField:_closeThread()
if self._thread and coroutine.status(self._thread) ~= "dead" then
coroutine.close(self._thread)
end
end
function SelfTestField:_resumeThread()
if self._thread and coroutine.status(self._thread) == "suspended" then
local success, status = coroutine.resume(self._thread)
game.Log(self.label .. ": success: " .. tostring(success) ..
", status: " .. status .. " (" .. statusToString(status) .. ")",
game.LOGGER_DEBUG
)
if success and status ~= self.status then
self.status = status
if self.onStatusChange then
game.Log("SKIN CONFIG: onStatusChange(" .. status .. ") (" ..
statusToString(status) .. ")",
game.LOGGER_DEBUG
)
self.onStatusChange(status)
end
end
end
end
function SelfTestField:activate(obj)
2022-04-24 01:39:48 +02:00
self:_closeThread()
if self.checkTask then
self._thread = coroutine.create(self.checkTask)
self:_resumeThread()
end
end
2022-04-24 01:39:48 +02:00
function SelfTestField:deactivate(obj)
self:_closeThread()
end
function SelfTestField:tick(deltaTime)
self:_resumeThread()
self._timer = self._timer + deltaTime
end
function SelfTestField:drawValue(deltaTime)
gfx.Translate(self.VALUE_OFFSETX, 0)
gfx.TextAlign(gfx.TEXT_ALIGN_RIGHT | gfx.TEXT_ALIGN_TOP)
gfx.FillColor(table.unpack(self.FONT_COLOR))
gfx.Text(": ", 0, 0)
local color, text
if self.status == SelfTestStatusEnum.IDLE then
color = self.FONT_COLOR
text = ""
elseif self.status == SelfTestStatusEnum.INPROGRESS then
2022-04-24 01:39:48 +02:00
local progress = math.ceil(Util.lerp(self._timer % self.INPROGRESS_FREQ,
0, 0, self.INPROGRESS_FREQ, 4
))
color = self.COLOR_INPROGRESS
text = string.rep(".", progress)
elseif self.status == SelfTestStatusEnum.OK then
2022-04-24 01:39:48 +02:00
color = self.COLOR_OK
text = "OK"
elseif self.status == SelfTestStatusEnum.PASS then
2022-04-24 01:39:48 +02:00
color = self.COLOR_PASS
text = "PASS"
elseif self.status == SelfTestStatusEnum.ERROR then
2022-04-24 01:39:48 +02:00
color = self.COLOR_ERROR
text = "ERROR"
end
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT | gfx.TEXT_ALIGN_TOP)
gfx.FillColor(table.unpack(color))
gfx.Text(text, 0, 0)
end
2022-04-24 01:39:48 +02:00
function SelfTestField:render(deltaTime)
self:tick(deltaTime)
ServiceField.render(self, deltaTime)
end
return SelfTestField