diff --git a/lua/entities/gmod_wire_digitalscreen/cl_init.lua b/lua/entities/gmod_wire_digitalscreen/cl_init.lua index ae6aedef67..9740f160ac 100644 --- a/lua/entities/gmod_wire_digitalscreen/cl_init.lua +++ b/lua/entities/gmod_wire_digitalscreen/cl_init.lua @@ -1,6 +1,6 @@ include("shared.lua") - +local dsDrawRate = CreateConVar("wire_digitalscreen_draw_rate", 1, { FCVAR_REPLICATED, FCVAR_ARCHIVE }, "Draw rate for digital screen", 0.1, 1000) function ENT:SendData() net.Start("wire_interactiveprop_action") @@ -81,13 +81,17 @@ function ENT:OnRemove() end local function stringToNumber(index, str, bytes) - local newpos = index+bytes - str = str:sub(index,newpos-1) local n = 0 - for j=1,bytes do - n = n + str:byte(j)*(256^(j-1)) - end - return n, newpos + local mult = 1 + + -- Read bytes directly from the original string using absolute offset (index + j). + -- This eliminates string allocations from str:sub() and prevents Garbage Collector spikes. + for j = 0, bytes - 1 do + n = n + str:byte(index + j) * mult + mult = mult * 256 -- Multiplication is faster than math.pow / exponentiation (256^j) + end + + return n, index + bytes end local pixelbits = {3, 1, 3, 4, 1} @@ -143,7 +147,7 @@ end function ENT:Think() if self.buffer[1] ~= nil then - local maxtime = SysTime() + RealFrameTime() * 0.05 -- do more depending on client FPS. Higher fps = more work + local maxtime = SysTime() + RealFrameTime() * (0.05*dsDrawRate:GetFloat()) -- do more depending on client FPS. Higher fps = more work while SysTime() < maxtime and self.buffer[1] do if not self.co or coroutine.status(self.co) == "dead" then @@ -320,7 +324,7 @@ function ENT:Draw(flags) if self.NeedRefresh then self.NeedRefresh = false - local maxtime = SysTime() + RealFrameTime() * 0.01 + local maxtime = SysTime() + RealFrameTime() * (0.01*dsDrawRate:GetFloat()) self.GPU:RenderToGPU(function() local idx = 0 diff --git a/lua/entities/gmod_wire_digitalscreen/init.lua b/lua/entities/gmod_wire_digitalscreen/init.lua index 3be26fc1ee..ff754bcb99 100644 --- a/lua/entities/gmod_wire_digitalscreen/init.lua +++ b/lua/entities/gmod_wire_digitalscreen/init.lua @@ -5,6 +5,9 @@ DEFINE_BASECLASS( "base_wire_entity" ) ENT.WireDebugName = "DigitalScreen" +local dsDrawRate = CreateConVar("wire_digitalscreen_draw_rate", 1, { FCVAR_REPLICATED, FCVAR_ARCHIVE }, "Draw rate for digital screen", 0.1, 1000) +local dsNetBandwidth = CreateConVar("wire_digitalscreen_net_bandwidth", 20000, { FCVAR_ARCHIVE }, "Net bandwidth limit for digital screen (20k default)", 1000, 200000) +local dsNetBandwidthValue = dsNetBandwidth:GetInt() function ENT:InitInteractive() local model = self:GetModel() @@ -127,7 +130,9 @@ end function ENT:ReadCell(Address) Address = math.floor(Address) if Address < 0 then return nil end - if Address >= 1048577 then return nil end + if Address >= 1048578 then return nil end + if (Address==1048577) then return math.Round(dsNetBandwidthValue/2) end -- report its netbandwidth + if (Address==1048576) then return dsDrawRate:GetFloat() end -- report its draw rate return self.Memory[Address] or 0 end @@ -170,9 +175,19 @@ end ---------------------------------------------------- -- Processing limiters and global bandwidth limiters local maxProcessingTime = engine.TickInterval() * 0.9 -local defaultMaxBandwidth = 10000 -- 10k per screen max limit - is arbitrary. needs to be smaller than the global limit. -local defaultMaxGlobalBandwidth = 20000 -- 20k is a good global limit in my testing. higher than that seems to cause issues + +local defaultMaxBandwidth = math.Round(dsNetBandwidthValue/2) -- 10k per screen max limit - is arbitrary. needs to be smaller than the global limit. +local defaultMaxGlobalBandwidth = dsNetBandwidthValue -- 20k is a good global limit in my testing. higher than that seems to cause issues local maxBandwidth = defaultMaxBandwidth + +local function updateBW() + dsNetBandwidthValue = dsNetBandwidth:GetInt() + + defaultMaxBandwidth = math.Round(dsNetBandwidthValue/2) + defaultMaxGlobalBandwidth = dsNetBandwidthValue +end +cvars.AddChangeCallback("wire_digitalscreen_net_bandwidth", updateBW) + local globalBandwidthLookup = {} local function calcGlobalBW() maxBandwidth = defaultMaxGlobalBandwidth