Lua:Class:Timer

From Cheat Engine
Revision as of 06:13, 25 October 2025 by Mr millchick (talk | contribs) (added details and various examples)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Timer[edit]

Timer is a non-visual component class that fires an event at regular intervals. Timers are created with the createTimer function and inherit from the Component class.

Timers execute callbacks periodically (persistent mode) or once with auto-cleanup (one-shot mode).


Class Hierarchy[edit]


Creation[edit]

Timers are created using createTimer:

local timer = createTimer()              -- Persistent timer
createTimer(1000, function() end)        -- One-shot timer


Properties[edit]

Property Type Access Description
Interval integer Read/Write Timer interval in milliseconds (1000 = 1 second). Must be greater than 0. Changes take effect on next timer tick.
Enabled boolean Read/Write Whether the timer is currently active. true = timer fires events, false = paused. Setting to false pauses without destroying. Setting to true resumes or starts the timer.
OnTimer function Read/Write Callback function executed each time the timer fires. Function receives the timer object as first parameter (sender). For one-shot timers, set during creation; for persistent timers, set this property.


Methods[edit]

Inherits all methods from Component:

destroy()

  • Stops and destroys the timer
  • Frees allocated memory
  • Important: Do not call on one-shot timers (they auto-destroy)


Getter/Setter Methods[edit]

While properties can be accessed directly, you can also use explicit getter/setter methods:

getInterval() / setInterval(interval)

local timer = createTimer()
timer.setInterval(1000)
print(timer.getInterval())  -- Output: 1000

getEnabled() / setEnabled(enabled)

local timer = createTimer()
timer.setEnabled(false)
print(timer.getEnabled())  -- Output: false

getOnTimer() / setOnTimer(function)

local timer = createTimer()
timer.setOnTimer(function() print("Fired") end)

Note: Direct property access is preferred in Lua (e.g., timer.Interval instead of timer.setInterval())


Usage Examples[edit]

Basic Examples[edit]

Note: Examples in this section focus on timer functionality. For production code, ensure proper cleanup by using an owner (see Ownership and Cleanup) or manually calling destroy() when done.

Basic periodic callback:

-- Note: No cleanup - timer persists until CE closes
local timer = createTimer()
timer.Interval = 1000  -- 1 second
timer.OnTimer = function(sender)
  print("Current time: " .. os.date("%H:%M:%S"))
end

Self-stopping timer:

local timer = createTimer()
timer.Interval = 1000
local count = 0

timer.OnTimer = function(sender)
  count = count + 1
  print("Count: " .. count)
  
  if count >= 5 then
    sender.Enabled = false
    print("Timer stopped")
  end
end

Pause and resume timer:

-- Note: No cleanup - timer persists until CE closes
local timer = createTimer()
timer.Interval = 500
timer.OnTimer = function()
  print("Active")
end

-- Pause
timer.Enabled = false
print("Paused")

-- Resume after delay
sleep(2000)
timer.Enabled = true
print("Resumed")


Ownership and Cleanup[edit]

Timer with manual cleanup:

local timer = createTimer()
timer.Interval = 100
local iterations = 0

timer.OnTimer = function(sender)
  iterations = iterations + 1
  
  if iterations >= 100 then
    sender.destroy()
    timer = nil
    print("Timer destroyed after 100 iterations")
  end
end

Timer owned by form (auto-cleanup):

local form = createForm()
local timer = createTimer(form)

timer.Interval = 500
timer.OnTimer = function()
  form.Caption = "Time: " .. os.date("%H:%M:%S")
end

-- Timer is destroyed automatically when form closes

Timer owned by main form (auto-cleanup on CE close):

local timer = createTimer(getMainForm())
timer.Interval = 1000
timer.OnTimer = function()
  -- Runs until Cheat Engine closes
  print("Active: " .. os.date("%H:%M:%S"))
end


Advanced Examples[edit]

Dynamic interval adjustment:

-- Note: No cleanup - timer persists until CE closes
local timer = createTimer()
local speed = 1000

function setSpeed(newSpeed)
  speed = newSpeed
  timer.Interval = speed
end

timer.Interval = speed
timer.OnTimer = function()
  print("Tick at " .. speed .. "ms interval")
end

-- Change speed
setSpeed(500)

Memory monitoring:

-- Uses getMainForm() for automatic cleanup
local timer = createTimer(getMainForm())
timer.Interval = 100

timer.OnTimer = function()
  local playerHealthAddr = getAddress("player.health")
  if playerHealthAddr then
    local health = readInteger(playerHealthAddr)
    
    if health < 20 then
      print("WARNING: Low health!")
      -- Could trigger auto-heal here
    end
  else
    timer.Enabled = false
    print("Address not found, stopping monitor")
  end
end

Periodic auto-save:

-- Uses getMainForm() for automatic cleanup
local saveTimer = createTimer(getMainForm())
saveTimer.Interval = 60000  -- 1 minute

saveTimer.OnTimer = function()
  saveTable("autosave.ct")
  print("Table auto-saved at " .. os.date())
end

Multiple coordinated timers:

-- Note: No cleanup - timers persist until CE closes
local fastTimer = createTimer()
local slowTimer = createTimer()

fastTimer.Interval = 100
fastTimer.OnTimer = function()
  print("Fast: " .. os.clock())
end

slowTimer.Interval = 1000
slowTimer.OnTimer = function()
  print("Slow: " .. os.clock())
end

Throttled function execution:

-- Note: No cleanup - timer persists until CE closes
local timer = createTimer(nil, false)
timer.Interval = 1000

local actionQueue = {}

timer.OnTimer = function()
  if #actionQueue > 0 then
    local action = table.remove(actionQueue, 1)
    action()
  end
  
  if #actionQueue == 0 then
    timer.Enabled = false
  end
end

function queueAction(fn)
  table.insert(actionQueue, fn)
  timer.Enabled = true
end

-- Usage
queueAction(function() print("Action 1") end)
queueAction(function() print("Action 2") end)

Timer state machine:

-- Properly destroys itself when done
local timer = createTimer()
local state = "init"

timer.Interval = 1000
timer.OnTimer = function()
  if state == "init" then
    print("Initializing...")
    state = "loading"
    timer.Interval = 2000
    
  elseif state == "loading" then
    print("Loading...")
    state = "ready"
    timer.Interval = 100
    
  elseif state == "ready" then
    print("Ready!")
    timer.Enabled = false
    timer.destroy()
  end
end


Callback Details[edit]

The OnTimer callback receives the timer object as its first parameter:

timer.OnTimer = function(sender)
  -- sender is the timer object
  print("Interval: " .. sender.Interval)
  print("Enabled: " .. tostring(sender.Enabled))
  
  -- Can modify the timer from within callback
  sender.Interval = 500
  sender.Enabled = false
end

For one-shot timers, additional parameters can be passed:

createTimer(1000, function(arg1, arg2)
  print(arg1)  -- "Hello"
  print(arg2)  -- "World"
end, "Hello", "World")


Common Patterns[edit]

Initialization pattern:

local function createUpdateTimer(form, interval)
  local timer = createTimer(form)
  timer.Interval = interval
  return timer
end

local form = createForm()
local updateTimer = createUpdateTimer(form, 1000)
updateTimer.OnTimer = function()
  -- Update form
end

Delayed execution pattern:

function executeAfter(milliseconds, callback)
  createTimer(milliseconds, callback)
end

executeAfter(2000, function()
  print("Executed after 2 seconds")
end)

Periodic check pattern:

function watchAddress(address, checkInterval, callback)
  local timer = createTimer()
  timer.Interval = checkInterval
  timer.OnTimer = function()
    local value = readInteger(address)
    callback(value)
  end
  return timer
end

local watcher = watchAddress("game.exe+12345", 500, function(value)
  print("Current value: " .. value)
end)


Technical Notes[edit]

Timer Resolution and Accuracy[edit]

  • Timers have a system-dependent resolution (typically ~15ms on Windows)
  • Very short intervals (<15ms) may not fire exactly on schedule
  • Timers are not real-time and can be affected by system load
  • For high-precision timing, consider using createThread with sleep
  • Timer callbacks execute in the main CE thread, blocking the UI if they run too long


Memory Management[edit]

Persistent timers:

  • Destruction happens automatically if owned by a component that gets destroyed
  • Use getMainForm() as owner to auto-cleanup when CE closes: createTimer(getMainForm())
  • Otherwise must be explicitly destroyed with destroy()
  • Forgetting to destroy causes memory leaks

One-shot timers:

  • Automatically destroy themselves after firing
  • Never call destroy() on one-shot timers
  • Created with createTimer(interval, callback) syntax


Thread Safety[edit]

  • Timer callbacks execute in the main CE thread
  • Safe to update UI elements from timer callbacks
  • No synchronization needed for CE API calls
  • Long-running callbacks will freeze the CE interface


See also[edit]

Related Functions[edit]

Related Classes[edit]