From 1e9538c40b24047d33a21470128bca894afa70d3 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Thu, 10 Oct 2024 00:44:51 +0300 Subject: [PATCH 01/13] init --- .../gmod_wire_expression2/core/timer.lua | 221 ++++++++++++++++++ lua/wire/client/e2descriptions.lua | 18 ++ 2 files changed, 239 insertions(+) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index a2c1b97550..2fecc1eb18 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -116,7 +116,228 @@ e2function void stopAllTimers() end /******************************************************************************/ +-- Lambda timers +local gtimers = { + /*EXAMPLE: + '[342]e2entity' = { + [342]e2entity_gmod_wire_expression2_gtimer_examplename = { + context = {...} (e2 context), + callback = {...} (e2 callback), + delay = 1, + repetitions = 1 + } + } + */ +} + +local gtimersIncrementalKeys = {} + +local function gtimerGetNextIncrementalKey(self) + local key = (gtimersIncrementalKeys[self.entity:EntIndex()] or 0)+1 + gtimersIncrementalKeys[self.entity:EntIndex()] = key + return key +end + +local function gtimerGetPrefix(name) + return '_gmod_wire_expression2_gtimer_' .. name +end + +local function gtimerExists(self, name) + return gtimers[self.entity:EntIndex()] and gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)] and true or false +end + +local function createGTimer(self, name, delay, repetitions, callback) + ogname = name + name = gtimerGetPrefix(name) + if not gtimers[self.entity:EntIndex()] then + gtimers[self.entity:EntIndex()] = {} + elseif gtimerExists(self, ogname) then + return self:throw("Timer with name " .. name .. " already exists", nil) + end + + gtimers[self.entity:EntIndex()][name] = { + name = ogname, + context = self, + callback = callback, + delay = delay, + repetitions = repetitions + } + + timer.Create(name, delay, repetitions, function() + if timer.RepsLeft(name) == 0 then + gtimers[name] = nil + end + + callback:UnsafeExtCall({}, self) + end) +end + +local function destroyGTimer(self, name) + + if not gtimers[self.entity:EntIndex()] then + gtimers[self.entity:EntIndex()] = {} + return self:throw("Timer with name " .. name .. " does not exist", nil) + elseif not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + name = gtimerGetPrefix(name) + timer.Remove(name) + gtimers[self.entity:EntIndex()][name] = nil +end + +registerCallback("destruct", function( self ) + for k, _ in pairs(gtimers[self.entity:EntIndex()] or {}) do + timer.Remove(k) + end + + gtimers[self.entity:EntIndex()] = nil +end) + + + +__e2setcost(2) +e2function void gtimerSetDelay(string name, number delay) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + local name = gtimerGetPrefix(name) + gtimers[self.entity:EntIndex()][name].delay = delay + timer.Adjust(name, delay, 0) +end + +e2function number gtimerSetReps(string name, number repetitions) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + local name = gtimerGetPrefix(name) + gtimers[self.entity:EntIndex()][name].repetitions = repetitions + timer.Adjust(name, gtimers[self.entity:EntIndex()][name].delay, repetitions) +end + +__e2setcost(20) +e2function void gtimerSetCallback(string name, function callback) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + local int_name = gtimerGetPrefix(name) + local gtimer = table.Copy(gtimers[self.entity:EntIndex()][int_name]) + destroyGTimer(self, name) + + gtimer['callback'] = callback + createGTimer(self, name, gtimer.delay, gtimer.repetitions, callback) +end + +__e2setcost(10) +e2function void gtimerCreate(string name, number delay, number repetitions, function callback) + createGTimer(self, name, delay, repetitions, callback) +end + +e2function string gtimerCreate(number delay, number repetitions, function callback) + local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) + createGTimer(self, name, delay, repetitions, callback) + return name +end + +e2function string gtimerCreate(number delay, function callback) + local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) + createGTimer(self, "simpletimer_"..gtimerGetNextIncrementalKey(self), delay, 1, callback) + return name +end +e2function void gtimerCreate(string name, number delay, function callback) + createGTimer(self, name, delay, 1, callback) +end + +-- Complete alias of gtimerCreate, but a lot of newbies will look for delay +e2function string delay(number delay, function callback) + local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) + createGTimer(self, name, delay, 1, callback) + return name +end + +e2function void gtimerRestart(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + local name = gtimerGetPrefix(name) + timer.Stop(name) + timer.Start(name) +end + +__e2setcost(1) +[nodiscard] +e2function number gtimerExists(string name) + return gtimerExists(self, name) and 1 or 0 +end + +e2function void gtimerPause(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + + --return timer.Pause(gtimerGetPrefix(name)) and 1 or 0 + timer.Pause(gtimerGetPrefix(name)) +end + +e2function void gtimerResume(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + + -- return timer.UnPause(gtimerGetPrefix(name)) and 1 or 0 + timer.UnPause(gtimerGetPrefix(name)) +end +-- This and that^ is commented due to timer.Pause being broken for some reason. It just does not return anything. +-- e2function number gtimerToggle(string name) +-- if not gtimerExists(self, name) then +-- return self:throw("Timer with name " .. name .. " does not exist", 0) +-- end +-- return timer.Toggle(gtimerGetPrefix(name)) and 1 or 0 +-- end + +__e2setcost(5) +e2function void gtimerRemove(string name) + destroyGTimer(self, name) +end + +__e2setcost(10) +e2function void gtimerPurge() + for _, tbl in pairs(gtimers[self.entity:EntIndex()]) do + destroyGTimer(self, tbl.name) + end +end + +__e2setcost(5) +[nodiscard] +e2function number gtimerRepsLeft(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + return timer.RepsLeft(gtimerGetPrefix(name)) +end + +[nodiscard] +e2function number gtimerTimeLeft(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + return timer.TimeLeft(gtimerGetPrefix(name)) +end + +[nodiscard] +e2function array gtimerList() + for _, timerTbl in pairs(gtimers[self.entity:EntIndex()]) do + ret[#ret+1] = timerTbl.name + end +end + +/******************************************************************************/ +__e2setcost(1) [nodiscard] e2function number curtime() return CurTime() diff --git a/lua/wire/client/e2descriptions.lua b/lua/wire/client/e2descriptions.lua index 39b6a0e5db..c091a93cac 100644 --- a/lua/wire/client/e2descriptions.lua +++ b/lua/wire/client/e2descriptions.lua @@ -976,6 +976,24 @@ E2Helper.Descriptions["runOnTick(n)"] = "DEPRECATED. Use 'event tick()' instead! E2Helper.Descriptions["timer(sn)"] = "Sets a one-time timer with entered name and delay in milliseconds" E2Helper.Descriptions["stoptimer(s)"] = "Stops a timer, can stop interval with stoptimer(\"interval\")" E2Helper.Descriptions["stopAllTimers()"] = "Stops all timers" +E2Helper.Descriptions["gtimerSetDelay(s,n)"] = "Sets the delay of the timer with the name S to N seconds" +E2Helper.Descriptions["gtimerSetReps(s,n)"] = "Sets the number of repetitions of the timer with the name S to N" +E2Helper.Descriptions["gtimerSetCallback(s,f)"] = "Sets the callback function of the timer with the name S to the function F" +E2Helper.Descriptions["gtimerCreate(snnf)"] = "Creates a callback timer with the name S, delay of N seconds, N repeats and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["gtimerCreate(nnf)"] = "Creates a simple callback timer with delay of N seconds, N repeats and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["gtimerCreate(nf)"] = "Creates a simple callback timer delay of N seconds, 1 repeat(one-time timer) and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["gtimerCreate(snf)"] = "Creates a callback timer with the name S, delay of N seconds, 1 repeat(one-time timer) and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["gtimerRestart(s)"] = "Restarts the callback timer with the name S. Uses the same amount of repetitions/delay/callback function as when was created. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["delay(nf)"] = "Creates a one-time callback timer with delay of N seconds and callback function F. Returns autogenerated name which you can use. Complete alias of gtimerCreate(nf). NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["gtimerExists(s)"] = "Returns 1 if a callback timer with the name S exists. 0 otherwise" +E2Helper.Descriptions["gtimerPause(s)"] = "Pauses the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already stopped" +E2Helper.Descriptions["gtimerResume(s)"] = "Resumes the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already running" +--E2Helper.Descriptions["gtimerToggle(s)"] = "Toggles the callback timer with the name S. Returns 1 if timer is now running, 0 otherwise" +E2Helper.Descriptions["gtimerRemove(s)"] = "Deletes the callback timer with the name S" +E2Helper.Descriptions["gtimerPurge()"] = "Deletes all callback timers" +E2Helper.Descriptions["gtimerRepsLeft(s)"] = "Returns the number of repetitions left for the callback timer with the name S" +E2Helper.Descriptions["gtimerTimeLeft(s)"] = "Returns the time left for the callback timer with the name S until the next execution" +E2Helper.Descriptions["gtimerList()"] = "Returns an array with all callback timers names" -- Unit conversion E2Helper.Descriptions["toUnit(sn)"] = "Converts default garrysmod units to specified units" From 871e359d912e348ce444fb0c51bdfddd55ac12e6 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Thu, 10 Oct 2024 00:52:35 +0300 Subject: [PATCH 02/13] Add getters + adjust method --- .../gmod_wire_expression2/core/timer.lua | 40 +++++++++++++++++++ lua/wire/client/e2descriptions.lua | 10 +++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 2fecc1eb18..3c965412ce 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -217,6 +217,18 @@ e2function number gtimerSetReps(string name, number repetitions) timer.Adjust(name, gtimers[self.entity:EntIndex()][name].delay, repetitions) end +__e2setcost(5) +e2function void gtimerAdjust(string name, number delay, number repetitions) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + local name = gtimerGetPrefix(name) + gtimers[self.entity:EntIndex()][name].delay = delay + gtimers[self.entity:EntIndex()][name].repetitions = repetitions + timer.Adjust(name, delay, repetitions) +end + __e2setcost(20) e2function void gtimerSetCallback(string name, function callback) if not gtimerExists(self, name) then @@ -231,6 +243,34 @@ e2function void gtimerSetCallback(string name, function callback) createGTimer(self, name, gtimer.delay, gtimer.repetitions, callback) end +__e2setcost(1) +[nodiscard] +e2function number gtimerGetDelay(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + + return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].delay +end + +[nodiscard] +e2function number gtimerGetReps(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) + end + + return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].repetitions +end + +[nodiscard] +e2function string gtimerGetCallback(string name) + if not gtimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", "") + end + + return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].callback +end + __e2setcost(10) e2function void gtimerCreate(string name, number delay, number repetitions, function callback) createGTimer(self, name, delay, repetitions, callback) diff --git a/lua/wire/client/e2descriptions.lua b/lua/wire/client/e2descriptions.lua index c091a93cac..58e35044f8 100644 --- a/lua/wire/client/e2descriptions.lua +++ b/lua/wire/client/e2descriptions.lua @@ -976,9 +976,13 @@ E2Helper.Descriptions["runOnTick(n)"] = "DEPRECATED. Use 'event tick()' instead! E2Helper.Descriptions["timer(sn)"] = "Sets a one-time timer with entered name and delay in milliseconds" E2Helper.Descriptions["stoptimer(s)"] = "Stops a timer, can stop interval with stoptimer(\"interval\")" E2Helper.Descriptions["stopAllTimers()"] = "Stops all timers" -E2Helper.Descriptions["gtimerSetDelay(s,n)"] = "Sets the delay of the timer with the name S to N seconds" -E2Helper.Descriptions["gtimerSetReps(s,n)"] = "Sets the number of repetitions of the timer with the name S to N" -E2Helper.Descriptions["gtimerSetCallback(s,f)"] = "Sets the callback function of the timer with the name S to the function F" +E2Helper.Descriptions["gtimerSetDelay(sn)"] = "Sets the delay of the timer with the name S to N seconds" +E2Helper.Descriptions["gtimerSetReps(sn)"] = "Sets the number of repetitions of the timer with the name S to N" +E2Helper.Descriptions["gtimerAdjust(snn)"] = "Sets the delay and repetitions of the timer with the name S to N seconds and N repetitions" +E2Helper.Descriptions["gtimerSetCallback(sf)"] = "Sets the callback function of the timer with the name S to the function F" +E2Helper.Descriptions["gtimerGetDelay(s)"] = "Returns the delay of the timer with the name S" +E2Helper.Descriptions["gtimerGetReps(s)"] = "Returns the number of repetitions of the timer with the name S" +E2Helper.Descriptions["gtimerGetCallback(s)"] = "Returns the callback function of the timer with the name S" E2Helper.Descriptions["gtimerCreate(snnf)"] = "Creates a callback timer with the name S, delay of N seconds, N repeats and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" E2Helper.Descriptions["gtimerCreate(nnf)"] = "Creates a simple callback timer with delay of N seconds, N repeats and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" E2Helper.Descriptions["gtimerCreate(nf)"] = "Creates a simple callback timer delay of N seconds, 1 repeat(one-time timer) and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" From 2b03d4c327cf5eb30d053b4cdaeb55d5000285df Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Mon, 21 Oct 2024 19:37:12 +0300 Subject: [PATCH 03/13] deprecate original timers --- .../gmod_wire_expression2/core/timer.lua | 346 +++++++++--------- lua/wire/client/e2descriptions.lua | 50 ++- 2 files changed, 187 insertions(+), 209 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 3c965412ce..5f5f9fbed7 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -46,6 +46,76 @@ local function RemoveTimer(self, name) end end +-- Lambda timers + +local luaTimers = { + /*EXAMPLE: + '[342]e2entity' = { + [342]e2entity_gmod_wire_expression2_luatimer_examplename = { + context = {...} (e2 context), + callback = {...} (e2 callback), + delay = 1, + repetitions = 1 + } + } + */ +} + +local luaTimerIncrementalKeys = {} + +local function luaTimerGetNextIncrementalKey(self) + local key = (luaTimerIncrementalKeys[self.entity:EntIndex()] or 0)+1 + luaTimerIncrementalKeys[self.entity:EntIndex()] = key + return key +end + +local function luaTimerGetPrefix(name) + return '_gmod_wire_expression2_luatimer_' .. name +end + +local function luaTimerExists(self, name) + return luaTimers[self.entity:EntIndex()] and luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)] and true or false +end + +local function luaTimerCreate(self, name, delay, repetitions, callback) + originalName = name + name = luaTimerGetPrefix(name) + if not luaTimers[self.entity:EntIndex()] then + luaTimers[self.entity:EntIndex()] = {} + elseif luaTimerExists(self, originalName) then + return self:throw("Timer with name " .. name .. " already exists", nil) + end + + luaTimers[self.entity:EntIndex()][name] = { + name = originalName, + context = self, + callback = callback, + delay = delay, + repetitions = repetitions + } + + timer.Create(name, delay, repetitions, function() + callback:UnsafeExtCall({}, self) + + if timer.RepsLeft(name) == 0 then + luaTimers[name] = nil + end + end) +end + +local function luaTimerRemove(self, name) + if not luaTimers[self.entity:EntIndex()] then + luaTimers[self.entity:EntIndex()] = {} + return self:throw("Timer with name " .. name .. " does not exist", nil) + elseif not luaTimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", nil) + end + + name = luaTimerGetPrefix(name) + timer.Remove(name) + luaTimers[self.entity:EntIndex()][name] = nil +end + /******************************************************************************/ registerCallback("construct", function(self) @@ -60,51 +130,59 @@ registerCallback("destruct", function(self) for name,_ in pairs(self.data['timer'].timers) do RemoveTimer(self, name) end + + for k, _ in pairs(luaTimers[self.entity:EntIndex()] or {}) do + timer.Remove(k) + end + + luaTimers[self.entity:EntIndex()] = nil end) /******************************************************************************/ __e2setcost(20) - +[deprecated = "Use lambda timers instead"] e2function void interval(rv1) AddTimer(self, "interval", rv1) end +[deprecated = "Use lambda timers instead"] e2function void timer(string rv1, rv2) AddTimer(self, rv1, rv2) end __e2setcost(5) - e2function void stoptimer(string rv1) RemoveTimer(self, rv1) + pcall(luaTimerRemove, self, rv1) end __e2setcost(1) -[nodiscard] +[nodiscard, deprecated = "Use lambda timers instead"] e2function number clk() return self.data.timer.runner == "interval" and 1 or 0 end -[nodiscard] +[nodiscard, deprecated = "Use lambda timers instead"] e2function number clk(string rv1) return self.data.timer.runner == rv1 and 1 or 0 end -[nodiscard] +[nodiscard, deprecated = "Use lambda timers instead"] e2function string clkName() return self.data.timer.runner or "" end e2function array getTimers() local ret = {} - local i = 0 for name in pairs( self.data.timer.timers ) do - i = i + 1 ret[i] = name end - self.prf = self.prf + i * 5 + for name in pairs( luaTimers[self.entity:EntIndex()] or {} ) do + ret[i] = name + end + self.prf = self.prf + #ret * 5 return ret end @@ -113,267 +191,171 @@ e2function void stopAllTimers() self.prf = self.prf + 5 RemoveTimer(self,name) end + for name in pairs(luaTimers[self.entity:EntIndex()] or {}) do + self.prf = self.prf + 5 + luaTimerRemove(self, name) + end end /******************************************************************************/ -- Lambda timers -local gtimers = { - /*EXAMPLE: - '[342]e2entity' = { - [342]e2entity_gmod_wire_expression2_gtimer_examplename = { - context = {...} (e2 context), - callback = {...} (e2 callback), - delay = 1, - repetitions = 1 - } - } - */ -} -local gtimersIncrementalKeys = {} - -local function gtimerGetNextIncrementalKey(self) - local key = (gtimersIncrementalKeys[self.entity:EntIndex()] or 0)+1 - gtimersIncrementalKeys[self.entity:EntIndex()] = key - return key -end - -local function gtimerGetPrefix(name) - return '_gmod_wire_expression2_gtimer_' .. name +__e2setcost(10) +e2function void timer(string name, number delay, number repetitions, function callback) + luaTimerCreate(self, name, delay, repetitions, callback) end -local function gtimerExists(self, name) - return gtimers[self.entity:EntIndex()] and gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)] and true or false +e2function string timer(number delay, number repetitions, function callback) + local name = "simpletimer_"..luaTimerGetNextIncrementalKey(self) + luaTimerCreate(self, name, delay, repetitions, callback) + return name end -local function createGTimer(self, name, delay, repetitions, callback) - ogname = name - name = gtimerGetPrefix(name) - if not gtimers[self.entity:EntIndex()] then - gtimers[self.entity:EntIndex()] = {} - elseif gtimerExists(self, ogname) then - return self:throw("Timer with name " .. name .. " already exists", nil) - end - - gtimers[self.entity:EntIndex()][name] = { - name = ogname, - context = self, - callback = callback, - delay = delay, - repetitions = repetitions - } - - timer.Create(name, delay, repetitions, function() - if timer.RepsLeft(name) == 0 then - gtimers[name] = nil - end - - callback:UnsafeExtCall({}, self) - end) +e2function string timer(number delay, function callback) + local name = "simpletimer_"..luaTimerGetNextIncrementalKey(self) + luaTimerCreate(self, "simpletimer_"..luaTimerGetNextIncrementalKey(self), delay, 1, callback) + return name end -local function destroyGTimer(self, name) - - if not gtimers[self.entity:EntIndex()] then - gtimers[self.entity:EntIndex()] = {} - return self:throw("Timer with name " .. name .. " does not exist", nil) - elseif not gtimerExists(self, name) then - return self:throw("Timer with name " .. name .. " does not exist", nil) - end - - name = gtimerGetPrefix(name) - timer.Remove(name) - gtimers[self.entity:EntIndex()][name] = nil +e2function void timer(string name, number delay, function callback) + luaTimerCreate(self, name, delay, 1, callback) end -registerCallback("destruct", function( self ) - for k, _ in pairs(gtimers[self.entity:EntIndex()] or {}) do - timer.Remove(k) - end - - gtimers[self.entity:EntIndex()] = nil -end) - - - __e2setcost(2) -e2function void gtimerSetDelay(string name, number delay) - if not gtimerExists(self, name) then +e2function void timerSetDelay(string name, number delay) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = gtimerGetPrefix(name) - gtimers[self.entity:EntIndex()][name].delay = delay + local name = luaTimerGetPrefix(name) + luaTimers[self.entity:EntIndex()][name].delay = delay timer.Adjust(name, delay, 0) end -e2function number gtimerSetReps(string name, number repetitions) - if not gtimerExists(self, name) then +e2function number timerSetReps(string name, number repetitions) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = gtimerGetPrefix(name) - gtimers[self.entity:EntIndex()][name].repetitions = repetitions - timer.Adjust(name, gtimers[self.entity:EntIndex()][name].delay, repetitions) + local name = luaTimerGetPrefix(name) + luaTimers[self.entity:EntIndex()][name].repetitions = repetitions + timer.Adjust(name, luaTimers[self.entity:EntIndex()][name].delay, repetitions) end __e2setcost(5) -e2function void gtimerAdjust(string name, number delay, number repetitions) - if not gtimerExists(self, name) then +e2function void timerAdjust(string name, number delay, number repetitions) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = gtimerGetPrefix(name) - gtimers[self.entity:EntIndex()][name].delay = delay - gtimers[self.entity:EntIndex()][name].repetitions = repetitions + local name = luaTimerGetPrefix(name) + luaTimers[self.entity:EntIndex()][name].delay = delay + luaTimers[self.entity:EntIndex()][name].repetitions = repetitions timer.Adjust(name, delay, repetitions) end -__e2setcost(20) -e2function void gtimerSetCallback(string name, function callback) - if not gtimerExists(self, name) then - return self:throw("Timer with name " .. name .. " does not exist", nil) - end +-- __e2setcost(20) +-- e2function void timerSetCallback(string name, function callback) +-- if not luaTimerExists(self, name) then +-- return self:throw("Timer with name " .. name .. " does not exist", nil) +-- end - local int_name = gtimerGetPrefix(name) - local gtimer = table.Copy(gtimers[self.entity:EntIndex()][int_name]) - destroyGTimer(self, name) +-- local int_name = luaTimerGetPrefix(name) +-- local luaTimer = table.Copy(luaTimers[self.entity:EntIndex()][int_name]) +-- luaTimerRemove(self, name) - gtimer['callback'] = callback - createGTimer(self, name, gtimer.delay, gtimer.repetitions, callback) -end +-- luaTimer['callback'] = callback +-- luaTimerCreate(self, name, luaTimer.delay, luaTimer.repetitions, callback) +-- end __e2setcost(1) [nodiscard] -e2function number gtimerGetDelay(string name) - if not gtimerExists(self, name) then +e2function number timerGetDelay(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].delay + return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].delay end [nodiscard] -e2function number gtimerGetReps(string name) - if not gtimerExists(self, name) then +e2function number timerGetReps(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].repetitions + return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].repetitions end [nodiscard] -e2function string gtimerGetCallback(string name) - if not gtimerExists(self, name) then +e2function function timerGetCallback(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", "") end - return gtimers[self.entity:EntIndex()][gtimerGetPrefix(name)].callback -end - -__e2setcost(10) -e2function void gtimerCreate(string name, number delay, number repetitions, function callback) - createGTimer(self, name, delay, repetitions, callback) -end - -e2function string gtimerCreate(number delay, number repetitions, function callback) - local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) - createGTimer(self, name, delay, repetitions, callback) - return name -end - -e2function string gtimerCreate(number delay, function callback) - local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) - createGTimer(self, "simpletimer_"..gtimerGetNextIncrementalKey(self), delay, 1, callback) - return name -end - -e2function void gtimerCreate(string name, number delay, function callback) - createGTimer(self, name, delay, 1, callback) + return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].callback end --- Complete alias of gtimerCreate, but a lot of newbies will look for delay -e2function string delay(number delay, function callback) - local name = "simpletimer_"..gtimerGetNextIncrementalKey(self) - createGTimer(self, name, delay, 1, callback) - return name -end - -e2function void gtimerRestart(string name) - if not gtimerExists(self, name) then +__e2setcost(5) +e2function void timerRestart(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = gtimerGetPrefix(name) + local name = luaTimerGetPrefix(name) timer.Stop(name) + timer.Adjust(name, luaTimers[self.entity:EntIndex()][name].delay, luaTimers[self.entity:EntIndex()][name].repetitions) timer.Start(name) end __e2setcost(1) [nodiscard] -e2function number gtimerExists(string name) - return gtimerExists(self, name) and 1 or 0 +e2function number timerExists(string name) + return luaTimerExists(self, name) and 1 or 0 end -e2function void gtimerPause(string name) - if not gtimerExists(self, name) then +e2function void timerPause(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - --return timer.Pause(gtimerGetPrefix(name)) and 1 or 0 - timer.Pause(gtimerGetPrefix(name)) + --return timer.Pause(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.Pause(luaTimerGetPrefix(name)) end -e2function void gtimerResume(string name) - if not gtimerExists(self, name) then +e2function void timerResume(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - -- return timer.UnPause(gtimerGetPrefix(name)) and 1 or 0 - timer.UnPause(gtimerGetPrefix(name)) + -- return timer.UnPause(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.UnPause(luaTimerGetPrefix(name)) end --- This and that^ is commented due to timer.Pause being broken for some reason. It just does not return anything. --- e2function number gtimerToggle(string name) --- if not gtimerExists(self, name) then --- return self:throw("Timer with name " .. name .. " does not exist", 0) --- end --- return timer.Toggle(gtimerGetPrefix(name)) and 1 or 0 --- end -__e2setcost(5) -e2function void gtimerRemove(string name) - destroyGTimer(self, name) -end - -__e2setcost(10) -e2function void gtimerPurge() - for _, tbl in pairs(gtimers[self.entity:EntIndex()]) do - destroyGTimer(self, tbl.name) +e2function number timerToggle(string name) + if not luaTimerExists(self, name) then + return self:throw("Timer with name " .. name .. " does not exist", 0) end + + --return timer.Toggle(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.Toggle(luaTimerGetPrefix(name)) end __e2setcost(5) [nodiscard] -e2function number gtimerRepsLeft(string name) - if not gtimerExists(self, name) then +e2function number timerRepsLeft(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return timer.RepsLeft(gtimerGetPrefix(name)) + return timer.RepsLeft(luaTimerGetPrefix(name)) end [nodiscard] -e2function number gtimerTimeLeft(string name) - if not gtimerExists(self, name) then +e2function number timerTimeLeft(string name) + if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return timer.TimeLeft(gtimerGetPrefix(name)) -end - -[nodiscard] -e2function array gtimerList() - for _, timerTbl in pairs(gtimers[self.entity:EntIndex()]) do - ret[#ret+1] = timerTbl.name - end + return timer.TimeLeft(luaTimerGetPrefix(name)) end /******************************************************************************/ diff --git a/lua/wire/client/e2descriptions.lua b/lua/wire/client/e2descriptions.lua index 58e35044f8..7bbe5980df 100644 --- a/lua/wire/client/e2descriptions.lua +++ b/lua/wire/client/e2descriptions.lua @@ -967,37 +967,33 @@ E2Helper.Descriptions["tickInterval()"] = "Returns the time (in seconds) between E2Helper.Descriptions["curtime()"] = "Returns the current game time since server-start in seconds" E2Helper.Descriptions["realtime()"] = "Returns the current real time since server-start in seconds" E2Helper.Descriptions["systime()"] = "Returns a highly accurate time (also in seconds) since the server was started. Ideal for benchmarking" -E2Helper.Descriptions["clk(s)"] = "Returns 1 if the current execution was caused by the inserted name" -E2Helper.Descriptions["clk()"] = "Returns 1 if the current execution was caused by the interval" -E2Helper.Descriptions["clkName()"] = "Returns the name of the timer that caused current execution" +E2Helper.Descriptions["clk(s)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns 1 if the current execution was caused by the inserted name" +E2Helper.Descriptions["clk()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns 1 if the current execution was caused by the interval" +E2Helper.Descriptions["clkName()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns the name of the timer that caused current execution" E2Helper.Descriptions["getTimers()"] = "Returns an array of all timers used in the E2" -E2Helper.Descriptions["interval(n)"] = "Sets a one-time timer with name \"interval\" and delay in milliseconds (minimum delay for timers is 10ms)" +E2Helper.Descriptions["interval(n)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Sets a one-time timer with name \"interval\" and delay in milliseconds (minimum delay for timers is 10ms)" E2Helper.Descriptions["runOnTick(n)"] = "DEPRECATED. Use 'event tick()' instead! If set to 1, the expression will execute once every game tick" -E2Helper.Descriptions["timer(sn)"] = "Sets a one-time timer with entered name and delay in milliseconds" +E2Helper.Descriptions["timer(sn)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Sets a one-time timer with entered name and delay in milliseconds" E2Helper.Descriptions["stoptimer(s)"] = "Stops a timer, can stop interval with stoptimer(\"interval\")" E2Helper.Descriptions["stopAllTimers()"] = "Stops all timers" -E2Helper.Descriptions["gtimerSetDelay(sn)"] = "Sets the delay of the timer with the name S to N seconds" -E2Helper.Descriptions["gtimerSetReps(sn)"] = "Sets the number of repetitions of the timer with the name S to N" -E2Helper.Descriptions["gtimerAdjust(snn)"] = "Sets the delay and repetitions of the timer with the name S to N seconds and N repetitions" -E2Helper.Descriptions["gtimerSetCallback(sf)"] = "Sets the callback function of the timer with the name S to the function F" -E2Helper.Descriptions["gtimerGetDelay(s)"] = "Returns the delay of the timer with the name S" -E2Helper.Descriptions["gtimerGetReps(s)"] = "Returns the number of repetitions of the timer with the name S" -E2Helper.Descriptions["gtimerGetCallback(s)"] = "Returns the callback function of the timer with the name S" -E2Helper.Descriptions["gtimerCreate(snnf)"] = "Creates a callback timer with the name S, delay of N seconds, N repeats and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["gtimerCreate(nnf)"] = "Creates a simple callback timer with delay of N seconds, N repeats and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["gtimerCreate(nf)"] = "Creates a simple callback timer delay of N seconds, 1 repeat(one-time timer) and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["gtimerCreate(snf)"] = "Creates a callback timer with the name S, delay of N seconds, 1 repeat(one-time timer) and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["gtimerRestart(s)"] = "Restarts the callback timer with the name S. Uses the same amount of repetitions/delay/callback function as when was created. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["delay(nf)"] = "Creates a one-time callback timer with delay of N seconds and callback function F. Returns autogenerated name which you can use. Complete alias of gtimerCreate(nf). NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" -E2Helper.Descriptions["gtimerExists(s)"] = "Returns 1 if a callback timer with the name S exists. 0 otherwise" -E2Helper.Descriptions["gtimerPause(s)"] = "Pauses the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already stopped" -E2Helper.Descriptions["gtimerResume(s)"] = "Resumes the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already running" ---E2Helper.Descriptions["gtimerToggle(s)"] = "Toggles the callback timer with the name S. Returns 1 if timer is now running, 0 otherwise" -E2Helper.Descriptions["gtimerRemove(s)"] = "Deletes the callback timer with the name S" -E2Helper.Descriptions["gtimerPurge()"] = "Deletes all callback timers" -E2Helper.Descriptions["gtimerRepsLeft(s)"] = "Returns the number of repetitions left for the callback timer with the name S" -E2Helper.Descriptions["gtimerTimeLeft(s)"] = "Returns the time left for the callback timer with the name S until the next execution" -E2Helper.Descriptions["gtimerList()"] = "Returns an array with all callback timers names" +E2Helper.Descriptions["timerSetDelay(sn)"] = "Sets the delay of the timer with the name S to N seconds" +E2Helper.Descriptions["timerSetReps(sn)"] = "Sets the number of repetitions of the timer with the name S to N" +E2Helper.Descriptions["timerAdjust(snn)"] = "Sets the delay and repetitions of the timer with the name S to N seconds and N repetitions" +--E2Helper.Descriptions["timerSetCallback(sf)"] = "Sets the callback function of the timer with the name S to the function F" +E2Helper.Descriptions["timerGetDelay(s)"] = "Returns the delay of the timer with the name S" +E2Helper.Descriptions["timerGetReps(s)"] = "Returns the number of repetitions of the timer with the name S" +E2Helper.Descriptions["timerGetCallback(s)"] = "Returns the callback function of the timer with the name S" +E2Helper.Descriptions["timer(snnf)"] = "Creates a callback timer with the name S, delay of N seconds, N repeats and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["timer(nnf)"] = "Creates a simple callback timer with delay of N seconds, N repeats and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["timer(nf)"] = "Creates a simple callback timer delay of N seconds, 1 repeat(one-time timer) and callback function F. Returns autogenerated name which you can use. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["timer(snf)"] = "Creates a callback timer with the name S, delay of N seconds, 1 repeat(one-time timer) and callback function F. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["timerRestart(s)"] = "Restarts the callback timer with the name S. Uses the same amount of repetitions/delay/callback function as when was created. NOTE: If the timer finished running, it will not exist (and you won't be able to restart/configure it)" +E2Helper.Descriptions["timerExists(s)"] = "Returns 1 if a callback timer with the name S exists. 0 otherwise" +E2Helper.Descriptions["timerPause(s)"] = "Pauses the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already stopped" +E2Helper.Descriptions["timerResume(s)"] = "Resumes the callback timer with the name S"--. Returns 1 if successful, 0 if the timer is already running" +E2Helper.Descriptions["timerToggle(s)"] = "Toggles the callback timer with the name S. Returns 1 if timer is now resumed, 0 if paused" +E2Helper.Descriptions["timerRepsLeft(s)"] = "Returns the number of repetitions left for the callback timer with the name S." +E2Helper.Descriptions["timerTimeLeft(s)"] = "Returns the time left for the callback timer with the name S until the next execution" -- Unit conversion E2Helper.Descriptions["toUnit(sn)"] = "Converts default garrysmod units to specified units" From 07083890ea262bf99d38dd4ea6fd57c4c54125a0 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Tue, 22 Oct 2024 10:22:04 +0300 Subject: [PATCH 04/13] Remove trailing whitespace from e2lib.lua --- lua/entities/gmod_wire_expression2/core/e2lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/e2lib.lua b/lua/entities/gmod_wire_expression2/core/e2lib.lua index 167bf434b9..20c1537a76 100644 --- a/lua/entities/gmod_wire_expression2/core/e2lib.lua +++ b/lua/entities/gmod_wire_expression2/core/e2lib.lua @@ -271,7 +271,7 @@ end function Function:ExtCall(args, types, ctx) if self.arg_sig == types then local success,ret = pcall(self.fn,args) - if success then + if success then return ret else local _,msg,trace = E2Lib.unpackException(ret) From ecfb47e64aae5dc7d0a9ca3f196380df66273781 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Tue, 22 Oct 2024 23:43:58 +0300 Subject: [PATCH 05/13] Bring back previously removed code lol --- lua/entities/gmod_wire_expression2/core/timer.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 5f5f9fbed7..9ec117d30e 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -176,13 +176,16 @@ end e2function array getTimers() local ret = {} + local i = 0 for name in pairs( self.data.timer.timers ) do + i = i + 1 ret[i] = name end for name in pairs( luaTimers[self.entity:EntIndex()] or {} ) do + i = i + 1 ret[i] = name end - self.prf = self.prf + #ret * 5 + self.prf = self.prf + i * 5 return ret end From 9c3ee2cc6e433bdd86affe22ed328fb8fb94cd85 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 23 Oct 2024 00:30:18 +0300 Subject: [PATCH 06/13] Get Vurv's internals implementations --- .../gmod_wire_expression2/base/compiler.lua | 4 +- .../gmod_wire_expression2/core/e2lib.lua | 2 +- lua/entities/gmod_wire_expression2/init.lua | 72 +++++++++---------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/base/compiler.lua b/lua/entities/gmod_wire_expression2/base/compiler.lua index 8f7a5fa83a..202faba047 100644 --- a/lua/entities/gmod_wire_expression2/base/compiler.lua +++ b/lua/entities/gmod_wire_expression2/base/compiler.lua @@ -1440,6 +1440,8 @@ local CompileVisitors = { function(args) local s_scopes, s_scope, s_scopeid = state.Scopes, state.Scope, state.ScopeID + state.prf = state.prf + 10 + local scope = { vclk = {} } state.Scopes = inherited_scopes state.ScopeID = after @@ -1872,8 +1874,6 @@ local CompileVisitors = { end end, ret_type elseif expr_ty == "f" then - self.scope.data.ops = self.scope.data.ops + 15 -- Since functions are 10 ops, this is pretty lenient. I will decrease this slightly when functions are made static and cheaper. - local nargs = #args local sig = table.concat(arg_types) diff --git a/lua/entities/gmod_wire_expression2/core/e2lib.lua b/lua/entities/gmod_wire_expression2/core/e2lib.lua index 20c1537a76..0449bc7bee 100644 --- a/lua/entities/gmod_wire_expression2/core/e2lib.lua +++ b/lua/entities/gmod_wire_expression2/core/e2lib.lua @@ -291,7 +291,7 @@ function Function:Ret() return self.ret end ---- If given the correct arguments, returns the inner untyped function you can call. +--- If given the correct arguments, returns the inner untyped function you can then call with ENT:Execute(f). --- Otherwise, throws an error to the given E2 Context. ---@param arg_sig string ---@param ctx RuntimeContext diff --git a/lua/entities/gmod_wire_expression2/init.lua b/lua/entities/gmod_wire_expression2/init.lua index 3f8fe34db9..a68b17a702 100644 --- a/lua/entities/gmod_wire_expression2/init.lua +++ b/lua/entities/gmod_wire_expression2/init.lua @@ -116,80 +116,80 @@ function ENT:UpdatePerf(selfTbl) context.time = 0 end -function ENT:Execute() - local selfTbl = self:GetTable() - local context = selfTbl.context - if not context or selfTbl.error or context.resetting then return end +function ENT:Execute(script, args) + if self.error or not self.context or self.context.resetting then return end + + script = script or self.script + args = args or self.context self:PCallHook("preexecute") - context.stackdepth = context.stackdepth + 1 + self.context.stackdepth = self.context.stackdepth + 1 - if context.stackdepth >= 150 then - self:Error("Expression 2 (" .. selfTbl.name .. "): stack quota exceeded", "stack quota exceeded") + if self.context.stackdepth >= 150 then + self:Error("Expression 2 (" .. self.name .. "): stack quota exceeded", "stack quota exceeded") end local bench = SysTime() - local ok, msg = pcall(selfTbl.script, context) + local ok, msg = pcall(script, args) if not ok then local _catchable, msg, trace = E2Lib.unpackException(msg) if msg == "exit" then - self:UpdatePerf(selfTbl) + self:UpdatePerf() elseif msg == "perf" then - local trace = context.trace - self:UpdatePerf(selfTbl) - self:Error("Expression 2 (" .. selfTbl.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "tick quota exceeded") + local trace = self.context.trace + self:UpdatePerf() + self:Error("Expression 2 (" .. self.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "tick quota exceeded") elseif trace then - self:Error("Expression 2 (" .. selfTbl.name .. "): Runtime error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") + self:Error("Expression 2 (" .. self.name .. "): Runtime error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") else - local trace = context.trace - self:Error("Expression 2 (" .. selfTbl.name .. "): Internal error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") + local trace = self.context.trace + self:Error("Expression 2 (" .. self.name .. "): Internal error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") end end - context.time = context.time + (SysTime() - bench) - context.stackdepth = context.stackdepth - 1 + self.context.time = self.context.time + (SysTime() - bench) + self.context.stackdepth = self.context.stackdepth - 1 - local forceTriggerOutputs = selfTbl.first or selfTbl.duped - selfTbl.first = false -- if hooks call execute - selfTbl.duped = false -- if hooks call execute - context.triggerinput = nil -- if hooks call execute + local forceTriggerOutputs = self.first or self.duped + self.first = false -- if hooks call execute + self.duped = false -- if hooks call execute + self.context.triggerinput = nil -- if hooks call execute self:PCallHook("postexecute") self:TriggerOutputs(forceTriggerOutputs) - local globalScope = selfTbl.GlobalScope - local inputs = selfTbl.Inputs - - for k, v in pairs(selfTbl.inports[3]) do - if globalScope[k] then - if wire_expression_types[inputs[k].Type][3] then - globalScope[k] = wire_expression_types[inputs[k].Type][3](context, inputs[k].Value) + for k, v in pairs(self.inports[3]) do + if self.GlobalScope[k] then + if wire_expression_types[self.Inputs[k].Type][3] then + self.GlobalScope[k] = wire_expression_types[self.Inputs[k].Type][3](self.context, self.Inputs[k].Value) else - globalScope[k] = inputs[k].Value + self.GlobalScope[k] = self.Inputs[k].Value end end end - globalScope.vclk = {} - if not selfTbl.directives.strict then - for k, var in pairs(selfTbl.globvars_mut) do - globalScope[k] = fixDefault(wire_expression_types2[var.type][2]) + self.GlobalScope.vclk = {} + if not self.directives.strict then + for k, var in pairs(self.globvars_mut) do + self.GlobalScope[k] = fixDefault(wire_expression_types2[var.type][2]) end end - if context.prfcount + context.prf - e2_softquota > e2_hardquota then - local trace = context.trace - self:Error("Expression 2 (" .. selfTbl.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "hard quota exceeded") + if self.context.prfcount + self.context.prf - e2_softquota > e2_hardquota then + local trace = self.context.trace + self:Error("Expression 2 (" .. self.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "hard quota exceeded") end if self.error then self:Destruct() end + + return msg end ---@param evt string From 139ff8ea0982f5ede1e30ae4bda2ece8b580a2f9 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 23 Oct 2024 00:43:42 +0300 Subject: [PATCH 07/13] Use ent:Execute instead of UnsafeExtCall --- lua/entities/gmod_wire_expression2/core/timer.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 9ec117d30e..1ed143f7d1 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -86,16 +86,18 @@ local function luaTimerCreate(self, name, delay, repetitions, callback) return self:throw("Timer with name " .. name .. " already exists", nil) end - luaTimers[self.entity:EntIndex()][name] = { + local callback, ent = callback:Unwrap("", self), self.entity + + luaTimers[ent:EntIndex()][name] = { name = originalName, - context = self, + ent = ent, callback = callback, delay = delay, repetitions = repetitions } timer.Create(name, delay, repetitions, function() - callback:UnsafeExtCall({}, self) + ent:Execute(callback) if timer.RepsLeft(name) == 0 then luaTimers[name] = nil From 979fbfe96e602eca634b226744a9977899f92000 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 23 Oct 2024 00:56:52 +0300 Subject: [PATCH 08/13] Slight indexing refactor --- .../gmod_wire_expression2/core/timer.lua | 115 ++++++++++-------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 1ed143f7d1..139360178a 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -69,53 +69,54 @@ local function luaTimerGetNextIncrementalKey(self) return key end -local function luaTimerGetPrefix(name) - return '_gmod_wire_expression2_luatimer_' .. name +local function luaTimerGetInternalName(entIndex, name) + return entIndex .. '_gmod_wire_expression2_luatimer_' .. name end local function luaTimerExists(self, name) - return luaTimers[self.entity:EntIndex()] and luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)] and true or false + local tbl = luaTimers[self.entity:EntIndex()] + return tbl and tbl[name] and true or false end local function luaTimerCreate(self, name, delay, repetitions, callback) - originalName = name - name = luaTimerGetPrefix(name) - if not luaTimers[self.entity:EntIndex()] then - luaTimers[self.entity:EntIndex()] = {} - elseif luaTimerExists(self, originalName) then + local entIndex = self.entity:EntIndex() + + if not luaTimers[entIndex] then + luaTimers[entIndex] = {} + elseif luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " already exists", nil) end + local internalName = luaTimerGetInternalName(self.entity:EntIndex(), name) local callback, ent = callback:Unwrap("", self), self.entity - luaTimers[ent:EntIndex()][name] = { - name = originalName, + luaTimers[entIndex][name] = { ent = ent, callback = callback, delay = delay, repetitions = repetitions } - timer.Create(name, delay, repetitions, function() + timer.Create(internalName, delay, repetitions, function() ent:Execute(callback) - if timer.RepsLeft(name) == 0 then + if timer.RepsLeft(internalName) == 0 then luaTimers[name] = nil end end) end local function luaTimerRemove(self, name) - if not luaTimers[self.entity:EntIndex()] then - luaTimers[self.entity:EntIndex()] = {} + local entIndex = self.entity:EntIndex() + if not luaTimers[entIndex] then + luaTimers[entIndex] = {} return self:throw("Timer with name " .. name .. " does not exist", nil) elseif not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - - name = luaTimerGetPrefix(name) - timer.Remove(name) - luaTimers[self.entity:EntIndex()][name] = nil + + timer.Remove(luaTimerGetInternalName(self.entity:EntIndex(), name)) + luaTimers[entIndex][name] = nil end /******************************************************************************/ @@ -133,11 +134,12 @@ registerCallback("destruct", function(self) RemoveTimer(self, name) end - for k, _ in pairs(luaTimers[self.entity:EntIndex()] or {}) do - timer.Remove(k) + local entIndex = self.entity:EntIndex() + for k, _ in pairs(luaTimers[entIndex] or {}) do + timer.Remove(luaTimerGetInternalName(entIndex, k)) end - luaTimers[self.entity:EntIndex()] = nil + luaTimers[entIndex] = nil end) /******************************************************************************/ @@ -183,10 +185,12 @@ e2function array getTimers() i = i + 1 ret[i] = name end - for name in pairs( luaTimers[self.entity:EntIndex()] or {} ) do + + for k, _ in pairs( luaTimers[self.entity:EntIndex()] or {} ) do i = i + 1 - ret[i] = name + ret[i] = k end + self.prf = self.prf + i * 5 return ret end @@ -196,9 +200,10 @@ e2function void stopAllTimers() self.prf = self.prf + 5 RemoveTimer(self,name) end - for name in pairs(luaTimers[self.entity:EntIndex()] or {}) do + + for k, _ in pairs(luaTimers[self.entity:EntIndex()] or {}) do self.prf = self.prf + 5 - luaTimerRemove(self, name) + luaTimerRemove(self, k) end end @@ -218,7 +223,7 @@ end e2function string timer(number delay, function callback) local name = "simpletimer_"..luaTimerGetNextIncrementalKey(self) - luaTimerCreate(self, "simpletimer_"..luaTimerGetNextIncrementalKey(self), delay, 1, callback) + luaTimerCreate(self, name, delay, 1, callback) return name end @@ -226,15 +231,15 @@ e2function void timer(string name, number delay, function callback) luaTimerCreate(self, name, delay, 1, callback) end -__e2setcost(2) +__e2setcost(5) e2function void timerSetDelay(string name, number delay) if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = luaTimerGetPrefix(name) - luaTimers[self.entity:EntIndex()][name].delay = delay - timer.Adjust(name, delay, 0) + local entIndex = self.entity:EntIndex() + luaTimers[entIndex][name].delay = delay + timer.Adjust(luaTimerGetInternalName(entIndex, name), delay, 0) end e2function number timerSetReps(string name, number repetitions) @@ -242,21 +247,20 @@ e2function number timerSetReps(string name, number repetitions) return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = luaTimerGetPrefix(name) - luaTimers[self.entity:EntIndex()][name].repetitions = repetitions - timer.Adjust(name, luaTimers[self.entity:EntIndex()][name].delay, repetitions) + local entIndex = self.entity:EntIndex() + luaTimers[entIndex][name].repetitions = repetitions + timer.Adjust(luaTimerGetInternalName(entIndex, name), luaTimers[entIndex][name].delay, repetitions) end -__e2setcost(5) e2function void timerAdjust(string name, number delay, number repetitions) if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = luaTimerGetPrefix(name) - luaTimers[self.entity:EntIndex()][name].delay = delay - luaTimers[self.entity:EntIndex()][name].repetitions = repetitions - timer.Adjust(name, delay, repetitions) + local entIndex = self.entity:EntIndex() + luaTimers[entIndex][name].delay = delay + luaTimers[entIndex][name].repetitions = repetitions + timer.Adjust(luaTimerGetInternalName(entIndex, name), delay, repetitions) end -- __e2setcost(20) @@ -265,7 +269,7 @@ end -- return self:throw("Timer with name " .. name .. " does not exist", nil) -- end --- local int_name = luaTimerGetPrefix(name) +-- local int_name = luaTimerGetInternalName(self.entity:EntIndex(), name) -- local luaTimer = table.Copy(luaTimers[self.entity:EntIndex()][int_name]) -- luaTimerRemove(self, name) @@ -280,7 +284,7 @@ e2function number timerGetDelay(string name) return self:throw("Timer with name " .. name .. " does not exist", 0) end - return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].delay + return luaTimers[self.entity:EntIndex()][name].delay end [nodiscard] @@ -289,7 +293,7 @@ e2function number timerGetReps(string name) return self:throw("Timer with name " .. name .. " does not exist", 0) end - return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].repetitions + return luaTimers[self.entity:EntIndex()][name].repetitions end [nodiscard] @@ -298,7 +302,7 @@ e2function function timerGetCallback(string name) return self:throw("Timer with name " .. name .. " does not exist", "") end - return luaTimers[self.entity:EntIndex()][luaTimerGetPrefix(name)].callback + return luaTimers[self.entity:EntIndex()][name].callback end __e2setcost(5) @@ -307,10 +311,11 @@ e2function void timerRestart(string name) return self:throw("Timer with name " .. name .. " does not exist", nil) end - local name = luaTimerGetPrefix(name) - timer.Stop(name) - timer.Adjust(name, luaTimers[self.entity:EntIndex()][name].delay, luaTimers[self.entity:EntIndex()][name].repetitions) - timer.Start(name) + local entIndex = self.entity:EntIndex() + local internalName = luaTimerGetInternalName(entIndex, name) + timer.Stop(internalName) + timer.Adjust(name, luaTimers[entIndex][name].delay, luaTimers[entIndex][name].repetitions) + timer.Start(internalName) end __e2setcost(1) @@ -324,8 +329,8 @@ e2function void timerPause(string name) return self:throw("Timer with name " .. name .. " does not exist", 0) end - --return timer.Pause(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. - timer.Pause(luaTimerGetPrefix(name)) + --return timer.Pause(luaTimerGetInternalName(self.entity:EntIndex(), name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.Pause(luaTimerGetInternalName(self.entity:EntIndex(), name)) end e2function void timerResume(string name) @@ -333,8 +338,8 @@ e2function void timerResume(string name) return self:throw("Timer with name " .. name .. " does not exist", 0) end - -- return timer.UnPause(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. - timer.UnPause(luaTimerGetPrefix(name)) + -- return timer.UnPause(luaTimerGetInternalName(self.entity:EntIndex(), name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.UnPause(luaTimerGetInternalName(self.entity:EntIndex(), name)) end e2function number timerToggle(string name) @@ -342,8 +347,8 @@ e2function number timerToggle(string name) return self:throw("Timer with name " .. name .. " does not exist", 0) end - --return timer.Toggle(luaTimerGetPrefix(name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. - timer.Toggle(luaTimerGetPrefix(name)) + --return timer.Toggle(luaTimerGetInternalName(self.entity:EntIndex(), name)) and 1 or 0 -- This is commented due to timer.Pause being broken for some reason. It just does not return anything. + timer.Toggle(luaTimerGetInternalName(self.entity:EntIndex(), name)) end __e2setcost(5) @@ -352,7 +357,8 @@ e2function number timerRepsLeft(string name) if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return timer.RepsLeft(luaTimerGetPrefix(name)) + + return timer.RepsLeft(luaTimerGetInternalName(self.entity:EntIndex(), name)) end [nodiscard] @@ -360,7 +366,8 @@ e2function number timerTimeLeft(string name) if not luaTimerExists(self, name) then return self:throw("Timer with name " .. name .. " does not exist", 0) end - return timer.TimeLeft(luaTimerGetPrefix(name)) + + return timer.TimeLeft(luaTimerGetInternalName(self.entity:EntIndex(), name)) end /******************************************************************************/ From 4182d976c40cf2362dfcffa96f7a10dcacb7ef20 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 23 Oct 2024 00:58:51 +0300 Subject: [PATCH 09/13] Update e2descriptions.lua --- lua/wire/client/e2descriptions.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lua/wire/client/e2descriptions.lua b/lua/wire/client/e2descriptions.lua index 7bbe5980df..a95190f286 100644 --- a/lua/wire/client/e2descriptions.lua +++ b/lua/wire/client/e2descriptions.lua @@ -967,13 +967,13 @@ E2Helper.Descriptions["tickInterval()"] = "Returns the time (in seconds) between E2Helper.Descriptions["curtime()"] = "Returns the current game time since server-start in seconds" E2Helper.Descriptions["realtime()"] = "Returns the current real time since server-start in seconds" E2Helper.Descriptions["systime()"] = "Returns a highly accurate time (also in seconds) since the server was started. Ideal for benchmarking" -E2Helper.Descriptions["clk(s)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns 1 if the current execution was caused by the inserted name" -E2Helper.Descriptions["clk()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns 1 if the current execution was caused by the interval" -E2Helper.Descriptions["clkName()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Returns the name of the timer that caused current execution" +E2Helper.Descriptions["clk(s)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead! Returns 1 if the current execution was caused by the inserted name" +E2Helper.Descriptions["clk()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead! Returns 1 if the current execution was caused by the interval" +E2Helper.Descriptions["clkName()"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead! Returns the name of the timer that caused current execution" E2Helper.Descriptions["getTimers()"] = "Returns an array of all timers used in the E2" -E2Helper.Descriptions["interval(n)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Sets a one-time timer with name \"interval\" and delay in milliseconds (minimum delay for timers is 10ms)" +E2Helper.Descriptions["interval(n)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead! Sets a one-time timer with name \"interval\" and delay in milliseconds (minimum delay for timers is 10ms)" E2Helper.Descriptions["runOnTick(n)"] = "DEPRECATED. Use 'event tick()' instead! If set to 1, the expression will execute once every game tick" -E2Helper.Descriptions["timer(sn)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead!Sets a one-time timer with entered name and delay in milliseconds" +E2Helper.Descriptions["timer(sn)"] = "DEPRECATED. Use 'timer(sf)' (lambda timer) instead! Sets a one-time timer with entered name and delay in milliseconds" E2Helper.Descriptions["stoptimer(s)"] = "Stops a timer, can stop interval with stoptimer(\"interval\")" E2Helper.Descriptions["stopAllTimers()"] = "Stops all timers" E2Helper.Descriptions["timerSetDelay(sn)"] = "Sets the delay of the timer with the name S to N seconds" From c534dd0e10b41a849f4a83550edc264fb17d6dcb Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Tue, 29 Oct 2024 01:45:25 +0200 Subject: [PATCH 10/13] fix --- .../gmod_wire_expression2/core/timer.lua | 18 +---- lua/entities/gmod_wire_expression2/init.lua | 66 +++++++++---------- 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/timer.lua b/lua/entities/gmod_wire_expression2/core/timer.lua index 139360178a..4b8679b4b2 100644 --- a/lua/entities/gmod_wire_expression2/core/timer.lua +++ b/lua/entities/gmod_wire_expression2/core/timer.lua @@ -263,19 +263,6 @@ e2function void timerAdjust(string name, number delay, number repetitions) timer.Adjust(luaTimerGetInternalName(entIndex, name), delay, repetitions) end --- __e2setcost(20) --- e2function void timerSetCallback(string name, function callback) --- if not luaTimerExists(self, name) then --- return self:throw("Timer with name " .. name .. " does not exist", nil) --- end - --- local int_name = luaTimerGetInternalName(self.entity:EntIndex(), name) --- local luaTimer = table.Copy(luaTimers[self.entity:EntIndex()][int_name]) --- luaTimerRemove(self, name) - --- luaTimer['callback'] = callback --- luaTimerCreate(self, name, luaTimer.delay, luaTimer.repetitions, callback) --- end __e2setcost(1) [nodiscard] @@ -313,9 +300,8 @@ e2function void timerRestart(string name) local entIndex = self.entity:EntIndex() local internalName = luaTimerGetInternalName(entIndex, name) - timer.Stop(internalName) - timer.Adjust(name, luaTimers[entIndex][name].delay, luaTimers[entIndex][name].repetitions) - timer.Start(internalName) + + timer.Adjust(internalName, luaTimers[entIndex][name].delay, luaTimers[entIndex][name].repetitions) end __e2setcost(1) diff --git a/lua/entities/gmod_wire_expression2/init.lua b/lua/entities/gmod_wire_expression2/init.lua index a68b17a702..29c23bc41f 100644 --- a/lua/entities/gmod_wire_expression2/init.lua +++ b/lua/entities/gmod_wire_expression2/init.lua @@ -117,22 +117,21 @@ function ENT:UpdatePerf(selfTbl) end function ENT:Execute(script, args) - if self.error or not self.context or self.context.resetting then return end - - script = script or self.script - args = args or self.context + local selfTbl = self:GetTable() + local context = selfTbl.context + if not context or selfTbl.error or context.resetting then return end self:PCallHook("preexecute") - self.context.stackdepth = self.context.stackdepth + 1 + context.stackdepth = context.stackdepth + 1 - if self.context.stackdepth >= 150 then - self:Error("Expression 2 (" .. self.name .. "): stack quota exceeded", "stack quota exceeded") + if context.stackdepth >= 150 then + self:Error("Expression 2 (" .. selfTbl.name .. "): stack quota exceeded", "stack quota exceeded") end local bench = SysTime() - local ok, msg = pcall(script, args) + local ok, msg = pcall(script or selfTbl.script, args or context) if not ok then local _catchable, msg, trace = E2Lib.unpackException(msg) @@ -140,56 +139,57 @@ function ENT:Execute(script, args) if msg == "exit" then self:UpdatePerf() elseif msg == "perf" then - local trace = self.context.trace + local trace = context.trace self:UpdatePerf() - self:Error("Expression 2 (" .. self.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "tick quota exceeded") + self:Error("Expression 2 (" .. selfTbl.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "tick quota exceeded") elseif trace then - self:Error("Expression 2 (" .. self.name .. "): Runtime error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") + self:Error("Expression 2 (" .. selfTbl.name .. "): Runtime error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") else - local trace = self.context.trace - self:Error("Expression 2 (" .. self.name .. "): Internal error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") + local trace = context.trace + self:Error("Expression 2 (" .. selfTbl.name .. "): Internal error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") end end - self.context.time = self.context.time + (SysTime() - bench) - self.context.stackdepth = self.context.stackdepth - 1 + context.time = context.time + (SysTime() - bench) + context.stackdepth = context.stackdepth - 1 - local forceTriggerOutputs = self.first or self.duped - self.first = false -- if hooks call execute - self.duped = false -- if hooks call execute - self.context.triggerinput = nil -- if hooks call execute + local forceTriggerOutputs = selfTbl.first or selfTbl.duped + selfTbl.first = false -- if hooks call execute + selfTbl.duped = false -- if hooks call execute + context.triggerinput = nil -- if hooks call execute self:PCallHook("postexecute") self:TriggerOutputs(forceTriggerOutputs) - for k, v in pairs(self.inports[3]) do - if self.GlobalScope[k] then - if wire_expression_types[self.Inputs[k].Type][3] then - self.GlobalScope[k] = wire_expression_types[self.Inputs[k].Type][3](self.context, self.Inputs[k].Value) + local globalScope = selfTbl.GlobalScope + local inputs = selfTbl.Inputs + + for k, v in pairs(selfTbl.inports[3]) do + if globalScope[k] then + if wire_expression_types[inputs[k].Type][3] then + globalScope[k] = wire_expression_types[inputs[k].Type][3](context, inputs[k].Value) else - self.GlobalScope[k] = self.Inputs[k].Value + globalScope[k] = inputs[k].Value end end end - self.GlobalScope.vclk = {} - if not self.directives.strict then - for k, var in pairs(self.globvars_mut) do - self.GlobalScope[k] = fixDefault(wire_expression_types2[var.type][2]) + globalScope.vclk = {} + if not selfTbl.directives.strict then + for k, var in pairs(selfTbl.globvars_mut) do + globalScope[k] = fixDefault(wire_expression_types2[var.type][2]) end end - if self.context.prfcount + self.context.prf - e2_softquota > e2_hardquota then - local trace = self.context.trace - self:Error("Expression 2 (" .. self.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "hard quota exceeded") + if context.prfcount + context.prf - e2_softquota > e2_hardquota then + local trace = context.trace + self:Error("Expression 2 (" .. selfTbl.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "hard quota exceeded") end if self.error then self:Destruct() end - - return msg end ---@param evt string From 98f1a2c7fc81ec57b925c865e8df9377a5325204 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Tue, 29 Oct 2024 10:08:26 +0200 Subject: [PATCH 11/13] Return UpdatePerf dep injection in ENT:Execute() --- lua/entities/gmod_wire_expression2/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/init.lua b/lua/entities/gmod_wire_expression2/init.lua index 29c23bc41f..3eb25cbaa5 100644 --- a/lua/entities/gmod_wire_expression2/init.lua +++ b/lua/entities/gmod_wire_expression2/init.lua @@ -137,10 +137,10 @@ function ENT:Execute(script, args) local _catchable, msg, trace = E2Lib.unpackException(msg) if msg == "exit" then - self:UpdatePerf() + self:UpdatePerf(selfTbl) elseif msg == "perf" then local trace = context.trace - self:UpdatePerf() + self:UpdatePerf(selfTbl) self:Error("Expression 2 (" .. selfTbl.name .. "): tick quota exceeded (at line " .. trace.start_line .. ", char " .. trace.start_col .. ")", "tick quota exceeded") elseif trace then self:Error("Expression 2 (" .. selfTbl.name .. "): Runtime error '" .. msg .. "' at line " .. trace.start_line .. ", char " .. trace.start_col, "script error") From 83fb6b5214d5a1494351542d2b2d638e88205147 Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 30 Oct 2024 09:41:21 +0200 Subject: [PATCH 12/13] Use args instead of selfTbl.context when provided --- lua/entities/gmod_wire_expression2/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/init.lua b/lua/entities/gmod_wire_expression2/init.lua index 3eb25cbaa5..6e7a3d9a84 100644 --- a/lua/entities/gmod_wire_expression2/init.lua +++ b/lua/entities/gmod_wire_expression2/init.lua @@ -118,7 +118,7 @@ end function ENT:Execute(script, args) local selfTbl = self:GetTable() - local context = selfTbl.context + local context = args or selfTbl.context if not context or selfTbl.error or context.resetting then return end self:PCallHook("preexecute") @@ -131,7 +131,7 @@ function ENT:Execute(script, args) local bench = SysTime() - local ok, msg = pcall(script or selfTbl.script, args or context) + local ok, msg = pcall(script or selfTbl.script, context) if not ok then local _catchable, msg, trace = E2Lib.unpackException(msg) From e58bb005474d1793e6e38ae60233696137d2ccda Mon Sep 17 00:00:00 2001 From: deltamolfar Date: Wed, 30 Oct 2024 22:37:41 +0200 Subject: [PATCH 13/13] Update init.lua --- lua/entities/gmod_wire_expression2/init.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/init.lua b/lua/entities/gmod_wire_expression2/init.lua index 6e7a3d9a84..b21b3db219 100644 --- a/lua/entities/gmod_wire_expression2/init.lua +++ b/lua/entities/gmod_wire_expression2/init.lua @@ -116,9 +116,10 @@ function ENT:UpdatePerf(selfTbl) context.time = 0 end -function ENT:Execute(script, args) +function ENT:Execute(script, context) local selfTbl = self:GetTable() - local context = args or selfTbl.context + context = context or selfTbl.context + script = script or selfTbl.script if not context or selfTbl.error or context.resetting then return end self:PCallHook("preexecute") @@ -131,7 +132,7 @@ function ENT:Execute(script, args) local bench = SysTime() - local ok, msg = pcall(script or selfTbl.script, context) + local ok, msg = pcall(script, context) if not ok then local _catchable, msg, trace = E2Lib.unpackException(msg)