API Basic Events en - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

Event / AddHandler / RemoveHandler / RaiseEvent

ClassicUO • Basic

Event declares a script notification. AddHandler connects a Sub, RemoveHandler disconnects it, and RaiseEvent calls the current handlers synchronously in subscription order.

Exact syntax

Event Changed(ByVal value As Integer)
Public Event Adjust(ByRef value As Integer)
Private Event Completed()
AddHandler EventName, AddressOf Handler
AddHandler Module.EventName, callback
RemoveHandler EventName, AddressOf Handler
RaiseEvent EventName(arguments)

Parameters

  • EventName / Public / Private — Declare a simple event name at file level (the script’s implicit module) or inside Module, outside procedures. Public is the default. Private requires Module. Outside a module use Module.EventName to subscribe. Only the declaring module may RaiseEvent, including for a Public event. Event names must not conflict with procedures or variables.
  • Handler / callback — Handler is a uniquely declared Sub, passed through AddressOf or a callback variable/factory from this loaded script. Functions, strings containing names, foreign handles and overload groups are rejected. The handler must have exactly the same number, types and ByVal/ByRef modes as the event. Write ByVal explicitly in handlers; ordinary legacy procedure parameters default to ByRef.
  • arguments / ByVal / ByRef — RaiseEvent requires all positional arguments. Optional, ParamArray, defaults, named event arguments and Safe Call are unsupported. Event parameters default to ByVal. ByVal copies a scalar or object reference, not the object’s contents. ByRef changes reach later handlers and are copied to the caller’s writable variable or indexed element; argument/index expressions are evaluated once in written order.

Returns

Event declarations and AddHandler/RemoveHandler/RaiseEvent produce no value (Unit): they return neither Boolean nor an ID or subscriber count. Use a ByRef parameter or shared Module state to receive data. Main returns String "ready", Integer 8 and String "ABAC:handler failed" in the three examples.

Behavior

  • Each interpreter keeps its own subscriptions. Other scripts and a reloaded script start without them. They remain for subsequent entry calls in the same loaded interpreter until removed or that interpreter is released. Closing the IDE keeps a running script and its subscriptions alive; it does not create an independent background event service.
  • AddHandler appends; duplicate subscriptions call the same Sub repeatedly. RemoveHandler removes the last occurrence of that Sub; an absent matching subscription is a no-op. The runtime checks declaration/access and the handler signature, evaluates raise arguments, then uses an immutable ordered snapshot. Changes during dispatch affect the next raise; the current snapshot is not modified.
  • A handler error stops later handlers in that raise and reaches the caller’s Catch/Finally. Earlier ByRef changes still copy back. Pause checkpoints and emergency cancellation apply inside handlers; Catch does not swallow emergency stop. No new thread is created. A blocking native call retains its own cancellation limits.
  • Limits: 4096 subscriptions per event, 16 nested RaiseEvent calls, 32 nested script procedure frames. Cycles/deep recursion produce a catchable script error instead of exhausting the client stack. Use a loop for deep processing. Shared scalar handler state belongs in Public/Private Module fields; legacy file-level scalars retain their inherited-copy behavior.
  • Script-declared events still require explicit RaiseEvent. Automatic journal, resource and connection subscriptions use the client-owned UO. events documented in Basic.GameEvents. Handles, WithEvents, Custom Event, event delegate types and class events remain unsupported.

Examples

1. Subscribe and unsubscribe

# Feed.Message carries text As String ByVal. Feed.Publish is the fully shown source procedure that raises it. Record appends text to shared State.log. A callback variable subscribes Record; publishing "ready" stores it. Removing AddressOf Record matches the same Sub even though the reference occurs at another line. The second publication has no subscribers and adds nothing. Main returns "ready".
Option Explicit On
Module Feed
    Public Event Message(ByVal text As String)
    Public Sub Publish(ByVal text As String)
        RaiseEvent Message(text)
    End Sub
End Module

Module State
    Public Dim log As String = ""
End Module

Sub Record(ByVal text As String)
    State.log = State.log & text
End Sub

Sub Main()
    Dim handler = AddressOf Record
    AddHandler Feed.Message, handler
    Feed.Publish("ready")
    RemoveHandler Feed.Message, AddressOf Record
    Feed.Publish("ignored")
    Return State.log
End Sub

Parameter and execution notes:

Feed.Message carries text As String ByVal. Feed.Publish is the fully shown source procedure that raises it. Record appends text to shared State.log. A callback variable subscribes Record; publishing "ready" stores it. Removing AddressOf Record matches the same Sub even though the reference occurs at another line. The second publication has no subscribers and adds nothing. Main returns "ready".

2. Pass a mutable value through handlers

# Adjust and both handlers declare total As Integer ByRef. total starts at 3; Increment changes it to 4, then DoubleValue sees 4 and changes it to 8. RaiseEvent copies 8 back to Main. Removing handlers cleans up both subscriptions. Integer 8 is a quantity, not True/False; RaiseEvent itself returns no value.
Option Explicit On
Event Adjust(ByRef total As Integer)

Sub Increment(ByRef total As Integer)
    total += 1
End Sub

Sub DoubleValue(ByRef total As Integer)
    total *= 2
End Sub

Sub Main()
    Dim total As Integer = 3
    AddHandler Adjust, AddressOf Increment
    AddHandler Adjust, AddressOf DoubleValue
    RaiseEvent Adjust(total)
    RemoveHandler Adjust, AddressOf Increment
    RemoveHandler Adjust, AddressOf DoubleValue
    Return total
End Sub

Parameter and execution notes:

Adjust and both handlers declare total As Integer ByRef. total starts at 3; Increment changes it to 4, then DoubleValue sees 4 and changes it to 8. RaiseEvent copies 8 back to Main. Removing handlers cleans up both subscriptions. Integer 8 is a quantity, not True/False; RaiseEvent itself returns no value.

3. Handle an error and continue safely

# Ready has no parameters. First appends A, Failing appends B and throws, so Last is skipped in that raise. Catch stores the message; Finally removes Failing. The next raise calls First and Last, appending AC. Main returns "ABAC:handler failed". All handlers and the shared State module are included in the example.
Option Explicit On
Event Ready()
Module State
    Public Dim log As String = ""
End Module

Sub First()
    State.log = State.log & "A"
End Sub

Sub Failing()
    State.log = State.log & "B"
    Throw "handler failed"
End Sub

Sub Last()
    State.log = State.log & "C"
End Sub

Sub Main()
    Dim message As String = ""
    AddHandler Ready, AddressOf First
    AddHandler Ready, AddressOf Failing
    AddHandler Ready, AddressOf Last
    Try
        RaiseEvent Ready()
    Catch problem
        message = problem
    Finally
        RemoveHandler Ready, AddressOf Failing
    End Try
    RaiseEvent Ready()
    Return State.log & ":" & message
End Sub

Parameter and execution notes:

Ready has no parameters. First appends A, Failing appends B and throws, so Last is skipped in that raise. Catch stores the message; Finally removes Failing. The next raise calls First and Last, appending AC. Main returns "ABAC:handler failed". All handlers and the shared State module are included in the example.


en · ru · uk · fr · de · it · es · zh-tw · ja · ko

Basic