mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
188
lua/fprofiler/ui/model.lua
Normal file
188
lua/fprofiler/ui/model.lua
Normal file
@@ -0,0 +1,188 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
The model describes the data that the drives the UI
|
||||
Loosely based on the Elm architecture
|
||||
---------------------------------------------------------------------------]]
|
||||
|
||||
local model =
|
||||
{
|
||||
realm = "client", -- "client" or "server"
|
||||
serverAccess = false, -- Whether the player has access to profile the server
|
||||
frameVisible = false, -- Whether the frame is visible
|
||||
|
||||
client = {
|
||||
status = "Stopped", -- Started or Stopped
|
||||
shouldReset = true, -- Whether profiling should start anew
|
||||
recordTime = 0, -- Total time spent on the last full profiling session
|
||||
sessionStart = nil, -- When the last profiling session was started
|
||||
sessionStartSysTime = nil, -- When the last profiling session was started, measured in SysTime
|
||||
bottlenecks = {}, -- The list of bottleneck functions
|
||||
topLagSpikes = {}, -- Top of lagging functions
|
||||
currentSelected = nil, -- Currently selected function
|
||||
|
||||
focusObj = nil, -- The current function being focussed upon in profiling
|
||||
focusStr = "", -- The current function name being entered
|
||||
|
||||
toConsole = nil, -- Any functions that should be printed to console
|
||||
|
||||
sourceText = "", -- The text of the source function (if available)
|
||||
},
|
||||
|
||||
server = {
|
||||
status = "Stopped", -- Started or Stopped
|
||||
shouldReset = true, -- Whether profiling should start anew
|
||||
bottlenecks = {}, -- The list of bottleneck functions
|
||||
recordTime = 0, -- Total time spent on the last full profiling session
|
||||
sessionStart = nil, -- When the last profiling session was started
|
||||
topLagSpikes = {}, -- Top of lagging functions
|
||||
currentSelected = nil, -- Currently selected function
|
||||
|
||||
focusObj = nil, -- The current function being focussed upon in profiling
|
||||
focusStr = "", -- The current function name
|
||||
|
||||
toConsole = nil, -- Any functions that should be printed to console
|
||||
|
||||
sourceText = "", -- The text of the source function (if available)
|
||||
fromServer = false, -- Whether a change of the model came from the server.
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local updaters = {}
|
||||
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Update the model.
|
||||
Automatically calls the registered update hook functions
|
||||
|
||||
e.g. updating the realm would be:
|
||||
FProfiler.UI.updateModel("realm", "server")
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.updateModel(path, value)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
local updTbl = updaters
|
||||
local mdlTbl = model
|
||||
local key = path[#path]
|
||||
|
||||
for i = 1, #path - 1 do
|
||||
mdlTbl = mdlTbl[path[i]]
|
||||
updTbl = updTbl and updTbl[path[i]]
|
||||
end
|
||||
|
||||
local oldValue = mdlTbl[key]
|
||||
mdlTbl[key] = value
|
||||
|
||||
for _, updFunc in ipairs(updTbl and updTbl[key] or {}) do
|
||||
updFunc(value, oldValue)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Update the model of the current realm
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.updateCurrentRealm(path, value)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
table.insert(path, 1, model.realm)
|
||||
|
||||
FProfiler.UI.updateModel(path, value)
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Retrieve a value of the model
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.getModelValue(path)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
local mdlTbl = model
|
||||
local key = path[#path]
|
||||
|
||||
for i = 1, #path - 1 do
|
||||
mdlTbl = mdlTbl[path[i]]
|
||||
end
|
||||
|
||||
return mdlTbl[key]
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Retrieve a value of the model regardless of realm
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.getCurrentRealmValue(path)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
table.insert(path, 1, model.realm)
|
||||
|
||||
return FProfiler.UI.getModelValue(path)
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Registers a hook that gets triggered when a certain part of the model is updated
|
||||
e.g. FProfiler.UI.onModelUpdate("realm", print) prints when the realm is changed
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.onModelUpdate(path, func)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
local updTbl = updaters
|
||||
local mdlTbl = model
|
||||
local key = path[#path]
|
||||
|
||||
for i = 1, #path - 1 do
|
||||
mdlTbl = mdlTbl[path[i]]
|
||||
updTbl[path[i]] = updTbl[path[i]] or {}
|
||||
updTbl = updTbl[path[i]]
|
||||
end
|
||||
|
||||
updTbl[key] = updTbl[key] or {}
|
||||
|
||||
table.insert(updTbl[key], func)
|
||||
|
||||
-- Call update with the initial value
|
||||
if mdlTbl[key] ~= nil then
|
||||
func(mdlTbl[key], mdlTbl[key])
|
||||
end
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
Registers a hook to both realms
|
||||
---------------------------------------------------------------------------]]
|
||||
function FProfiler.UI.onCurrentRealmUpdate(path, func)
|
||||
path = istable(path) and path or {path}
|
||||
|
||||
table.insert(path, 1, "client")
|
||||
FProfiler.UI.onModelUpdate(path, function(...)
|
||||
if FProfiler.UI.getModelValue("realm") == "server" then return end
|
||||
|
||||
func(...)
|
||||
end)
|
||||
|
||||
path[1] = "server"
|
||||
FProfiler.UI.onModelUpdate(path, function(...)
|
||||
if FProfiler.UI.getModelValue("realm") == "client" then return end
|
||||
|
||||
func(...)
|
||||
end)
|
||||
end
|
||||
|
||||
--[[-------------------------------------------------------------------------
|
||||
When the realm is changed, all update functions of the new realm are to be called
|
||||
---------------------------------------------------------------------------]]
|
||||
FProfiler.UI.onModelUpdate("realm", function(new, old)
|
||||
if not updaters[new] then return end
|
||||
|
||||
for k, funcTbl in pairs(updaters[new]) do
|
||||
for _, func in ipairs(funcTbl) do
|
||||
func(model[new][k], model[new][k])
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user