-
Notifications
You must be signed in to change notification settings - Fork 0
API Basic Timers
ClassicUO • Basic
CreateTimer создаёт остановленный таймер обратного вызова. Start планирует выполнение Sub в потоке этого скрипта. Это расширение проекта; Basic Timer() отдельно возвращает прошедшие секунды.
CreateTimer(milliseconds, handler) -> Object (ScriptTimer)
CreateTimer(milliseconds, handler, repeating) -> Object (ScriptTimer)
timer.Start() -> Unit
timer.Stop() -> Unit
timer.Dispose() -> Unit
timer.Enabled() -> Integer (0/1)
timer.Interval() -> Integer (ms)
timer.SetInterval(milliseconds) -> Unit
Using timer ... End Using
-
milliseconds— Integer, миллисекунды от 1 до 2147483647. Строка, дробь, ноль и отрицательное значение дают ошибку. У SetInterval те же правила. Interval() возвращает заданный интервал, а не оставшееся время. -
handler— AddressOf однозначно объявленной Sub строго без параметров либо переменная/фабрика обратного вызова этого скрипта. Function, Optional/ParamArray, строка с именем и чужая ссылка не подходят. Общие данные обработчиков храните в Module; локальное замыкание не создаётся. -
repeating— Третий параметр необязателен: True/1 — повторять, False/0 — один вызов. По умолчанию True. Именованная запись repeating:=. Другие числа и строки недопустимы. Однократный таймер отключается перед входом в обработчик. -
timer / Start / Stop / Dispose / SetInterval— Объект имеет Start(), Stop(), Dispose(), Enabled(), Interval(), SetInterval(milliseconds). Повторный Start включённого таймера ничего не меняет. После Stop разрешён Start. SetInterval отсчитывает новый интервал включённого таймера от текущего момента; остановленный остаётся остановленным. Dispose повторяем и окончателен: после него Start/SetInterval дают ошибку. Using освобождает захваченный объект при выходе.
CreateTimer возвращает Object (ScriptTimer), не ID предмета и не индекс скрипта. Start/Stop/Dispose/SetInterval возвращают Unit. Enabled — Integer 1=True или 0=False: можно сравнивать обоими способами. Interval — миллисекунды, не Boolean. Результаты примеров: String "3:0", "ready:0", "tick failed:0".
- Движок проверяет монотонное прошедшее время между инструкциями и внутри Basic Wait/Sleep и Wait Until. При включённых таймерах Wait делится на части не длиннее 25 мс. Игровая команда или другой блокирующий нативный вызов сначала должны завершиться. Точность реального времени не гарантируется; новые потоки не создаются.
- Готовые таймеры вызываются по сроку, при равенстве — по порядку создания. До 64 обработчиков за одну проверку; оставшиеся — при следующей. Пока выполняется обработчик, другие таймеры этого скрипта не входят повторно, даже при Wait. Повторный интервал отсчитывается от завершения; пропущенные срабатывания не накапливаются. Пауза останавливает вызовы. После возобновления просроченный таймер срабатывает один раз.
- Ошибка отключает таймер и передаётся в Catch/Finally вызывающего кода. Stop и смена интервала из обработчика учитываются. Аварийная остановка не превращается в обычную ошибку Catch. При завершении, ошибке или остановке корневого запуска все его таймеры освобождаются; при новом запуске/загрузке создайте их заново. Закрытие только IDE сохраняет таймеры работающего скрипта. До 1024 неосвобождённых таймеров на интерпретатор; Dispose освобождает место.
- RunThreePulses и GetHandler ниже полностью показаны и являются функциями примеров. Внутри движка CreateTimer проверяет параметры и владельца, сохраняет остановленный объект; Start записывает срок; Pump вызывает Sub; Fire назначает следующий срок после завершения; Release освобождает объекты при выходе из корневой процедуры. После завершения скрипта отдельная служба таймеров не остаётся.
# Main вызывает полностью показанную RunThreePulses. 20 — интервал в миллисекундах; третий параметр пропущен, поэтому repeating=True. CountPulse увеличивает State.count и останавливает таймер на трёх. Wait Until выполняет проверки и обработчики с таймаутом 3000 мс. После Stop значение Enabled() равно 0; результат "3:0". Using освобождает таймер даже при Return из функции.
Option Explicit On
Module State
Public Dim count As Integer = 0
Public Dim pulse
End Module
Sub CountPulse()
State.count += 1
If State.count >= 3 Then
State.pulse.Stop()
End If
End Sub
Function RunThreePulses() As String
State.pulse = CreateTimer(20, AddressOf CountPulse)
Using State.pulse
State.pulse.Start()
Wait Until State.count >= 3 Timeout 3000
Return CStr(State.count) & ":" & CStr(State.pulse.Enabled())
End Using
End Function
Sub Main()
Return RunThreePulses()
End SubРазбор параметров и выполнения:
Main вызывает полностью показанную RunThreePulses. 20 — интервал в миллисекундах; третий параметр пропущен, поэтому repeating=True. CountPulse увеличивает State.count и останавливает таймер на трёх. Wait Until выполняет проверки и обработчики с таймаутом 3000 мс. После Stop значение Enabled() равно 0; результат "3:0". Using освобождает таймер даже при Return из функции.
# GetHandler возвращает AddressOf SetReady. Именованные аргументы задают 5 мс, callback и repeating=False. SetInterval меняет интервал на 10 до Start. SetReady сохраняет "ready" в Module; однократный таймер уже отключён. Main ждёт не больше 3000 мс и возвращает "ready:0". Все функции и процедуры приведены целиком.
Option Explicit On
Module State
Public Dim message As String = ""
End Module
Sub SetReady()
State.message = "ready"
End Sub
Function GetHandler()
Return AddressOf SetReady
End Function
Sub Main()
Dim callback = GetHandler()
Dim notice = CreateTimer(repeating:=False, handler:=callback, milliseconds:=5)
Using notice
notice.SetInterval(10)
notice.Start()
Wait Until State.message = "ready" Timeout 3000
Return State.message & ":" & CStr(notice.Enabled())
End Using
End SubРазбор параметров и выполнения:
GetHandler возвращает AddressOf SetReady. Именованные аргументы задают 5 мс, callback и repeating=False. SetInterval меняет интервал на 10 до Start. SetReady сохраняет "ready" в Module; однократный таймер уже отключён. Main ждёт не больше 3000 мс и возвращает "ready:0". Все функции и процедуры приведены целиком.
# FailingPulse создаёт ошибку "tick failed". Таймер на 5 мс срабатывает внутри Wait(2000), отключается при ошибке и прерывает ожидание. Catch сохраняет текст и Enabled()=0; Finally освобождает объект. Возвращается "tick failed:0" — сообщение и логическое состояние. Аварийную остановку обрабатывает движок, этот Catch её не поглощает.
Option Explicit On
Sub FailingPulse()
Throw "tick failed"
End Sub
Sub Main()
Dim pulse = CreateTimer(5, AddressOf FailingPulse)
Dim problemText As String = ""
Dim enabledAfterError As Boolean = True
Try
pulse.Start()
Wait(2000)
Catch problem
problemText = problem
enabledAfterError = pulse.Enabled()
Finally
pulse.Dispose()
End Try
Return problemText & ":" & CStr(enabledAfterError)
End SubРазбор параметров и выполнения:
FailingPulse создаёт ошибку "tick failed". Таймер на 5 мс срабатывает внутри Wait(2000), отключается при ошибке и прерывает ожидание. Catch сохраняет текст и Enabled()=0; Finally освобождает объект. Возвращается "tick failed:0" — сообщение и логическое состояние. Аварийную остановку обрабатывает движок, этот Catch её не поглощает.
RunThreePulses и GetHandler ниже полностью показаны и являются функциями примеров. Внутри движка CreateTimer проверяет параметры и владельца, сохраняет остановленный объект; Start записывает срок; Pump вызывает Sub; Fire назначает следующий срок после завершения; Release освобождает объекты при выходе из корневой процедуры. После завершения скрипта отдельная служба таймеров не остаётся.
Integer, миллисекунды от 1 до 2147483647. Строка, дробь, ноль и отрицательное значение дают ошибку. У SetInterval те же правила. Interval() возвращает заданный интервал, а не оставшееся время.
AddressOf однозначно объявленной Sub строго без параметров либо переменная/фабрика обратного вызова этого скрипта. Function, Optional/ParamArray, строка с именем и чужая ссылка не подходят. Общие данные обработчиков храните в Module; локальное замыкание не создаётся.
Третий параметр необязателен: True/1 — повторять, False/0 — один вызов. По умолчанию True. Именованная запись repeating:=. Другие числа и строки недопустимы. Однократный таймер отключается перед входом в обработчик.
CreateTimer возвращает Object (ScriptTimer), не ID предмета и не индекс скрипта. Start/Stop/Dispose/SetInterval возвращают Unit. Enabled — Integer 1=True или 0=False: можно сравнивать обоими способами. Interval — миллисекунды, не Boolean. Результаты примеров: String "3:0", "ready:0", "tick failed:0".
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/Interpreter.Timers.cs; функция CreateTimer.
Объект имеет Start(), Stop(), Dispose(), Enabled(), Interval(), SetInterval(milliseconds). Повторный Start включённого таймера ничего не меняет. После Stop разрешён Start. SetInterval отсчитывает новый интервал включённого таймера от текущего момента; остановленный остаётся остановленным. Dispose повторяем и окончателен: после него Start/SetInterval дают ошибку. Using освобождает захваченный объект при выходе.
Due = now + interval; enabled = true;
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/ObjectTypes/ScriptTimerObject.cs; функция Start.
Движок проверяет монотонное прошедшее время между инструкциями и внутри Basic Wait/Sleep и Wait Until. При включённых таймерах Wait делится на части не длиннее 25 мс. Игровая команда или другой блокирующий нативный вызов сначала должны завершиться. Точность реального времени не гарантируется; новые потоки не создаются.
checkpoint -> Pump -> min(remaining, nextDue, 25 ms) -> Wait
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/Interpreter.Timers.cs; функция WaitWithTimers.
Готовые таймеры вызываются по сроку, при равенстве — по порядку создания. До 64 обработчиков за одну проверку; оставшиеся — при следующей. Пока выполняется обработчик, другие таймеры этого скрипта не входят повторно, даже при Wait. Повторный интервал отсчитывается от завершения; пропущенные срабатывания не накапливаются. Пауза останавливает вызовы. После возобновления просроченный таймер срабатывает один раз.
snapshot -> deadline / sequence -> checkpoint -> Fire; limit = 64
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/ScriptTimerScheduler.cs; функция Pump.
Ошибка отключает таймер и передаётся в Catch/Finally вызывающего кода. Stop и смена интервала из обработчика учитываются. Аварийная остановка не превращается в обычную ошибку Catch. При завершении, ошибке или остановке корневого запуска все его таймеры освобождаются; при новом запуске/загрузке создайте их заново. Закрытие только IDE сохраняет таймеры работающего скрипта. До 1024 неосвобождённых таймеров на интерпретатор; Dispose освобождает место.
callback -> completion -> next Due; error -> disabled -> throw
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/ObjectTypes/ScriptTimerObject.cs; функция Fire.
Объект имеет Start(), Stop(), Dispose(), Enabled(), Interval(), SetInterval(milliseconds). Повторный Start включённого таймера ничего не меняет. После Stop разрешён Start. SetInterval отсчитывает новый интервал включённого таймера от текущего момента; остановленный остаётся остановленным. Dispose повторяем и окончателен: после него Start/SetInterval дают ошибку. Using освобождает захваченный объект при выходе.
Release -> scheduler.Remove -> Changed
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/ObjectTypes/ScriptTimerObject.cs; функция Dispose.
Ошибка отключает таймер и передаётся в Catch/Finally вызывающего кода. Stop и смена интервала из обработчика учитываются. Аварийная остановка не превращается в обычную ошибку Catch. При завершении, ошибке или остановке корневого запуска все его таймеры освобождаются; при новом запуске/загрузке создайте их заново. Закрытие только IDE сохраняет таймеры работающего скрипта. До 1024 неосвобождённых таймеров на интерпретатор; Dispose освобождает место.
timer.Release for each handle -> timers.Clear -> no pending deadline
Исходник проекта: external/InjectionScript/src/InjectionScript/Runtime/ScriptTimerScheduler.cs; функция Release.
Main вызывает полностью показанную RunThreePulses. 20 — интервал в миллисекундах; третий параметр пропущен, поэтому repeating=True. CountPulse увеличивает State.count и останавливает таймер на трёх. Wait Until выполняет проверки и обработчики с таймаутом 3000 мс. После Stop значение Enabled() равно 0; результат "3:0". Using освобождает таймер даже при Return из функции.
ClassicUO - Bad Newbie & Basic IDE Edition