[Class] Event Handler

Post your working scripts, libraries and tools for AHK v1.1 and older
0x00
Posts: 89
Joined: 22 Jan 2019, 13:12

[Class] Event Handler

12 Mar 2020, 10:44

It's a pretty simple script that allows you to easily create EventHandlers & Consumer functions, just a different way to write scripts really, I enjoy event driven scripting in modding games & such,so i figure it'd be interesting.

REV.2
  • Very flexible but a new event handler timer is created for every consumer function.

Code: Select all

;Event Handler Prototype
EH.Subscribe("WinChangeEventHandlerExample", "CallbackExample", 5000)	;every 5sec
EH.Subscribe("WinChangeEventHandlerExample", "AnotherCallbackExample", 100)	;every 0.1sec

class EH{	;EventHandler class to register event callbacks & enabled/disable registered event handlers
	Subscribe(eventHandlerName, callbackFunc, eventHandlerPollFreq:=100){
		#Persistent
		Global
		EH_%eventHandlerName%%callbackFunc% :=  callbackFunc
		eventHandlerName%callbackFunc% := Func(eventHandlerName).Bind(callbackFunc)
		SetTimer, % eventHandlerName%callbackFunc%, % eventHandlerPollFreq
	}
	
	Unsubscribe(eventHandlerName, callbackFunc){	;alias for Disable()
		Global
		this.Disable(eventHandlerName, callbackFunc)
	}
	
	Disable(eventHandlerName, callbackFunc){
		eventHandlerName%callbackFunc% := Func(eventHandlerName).Bind(callbackFunc)
		SetTimer, % eventHandlerName%callbackFunc%, off
	}
	
	Enable(eventHandlerName, callbackFunc){
		eventHandlerName%callbackFunc% := Func(eventHandlerName).Bind(callbackFunc)
		SetTimer, % eventHandlerName%callbackFunc%, on
	}
	
}

CallbackExample(eventArray){
	For each, eventParam in eventArray
		MsgBox(A_ThisFunc "`n`n" each "`n" eventParam)
}

AnotherCallbackExample(eventArray){
	For each, eventParam in eventArray
		params .= each " - " eventParam "`n"
	MsgBox(A_ThisFunc "`n`n" params)
}

WinChangeEventHandlerExample(callback){
	Global
	callbacks := EH_%A_ThisFunc%%callback%
	eventArray := []
	;MsgBox % callbacks
	;check if active window changed, exec callbacks when it does
	static lastHwnd := lastHwnd ? lastHwnd : WinExist("A")
	If ( WinExist("A") != lastHwnd ){
		lastHwnd := WinExist("A")
		WinGetActiveStats, activeTitle, activeW, activeH, activeX, activeY
		eventArray := {id:lastHwnd, title:activeTitle, x:activeX, y:activeY, w:activeW, h:activeH}
		IsFunc(callback) ? %callback%(eventArray) : MsgBox("Error: `n`n`t" A_ThisFunc "`n`nEventHandler attempted to call non existent callback function: " callback, A_ScriptName,"0x40010")
		SoundBeep
	}
}

MsgBox(Text:="", Title:="", Options:="0x40040", TimeOut:=""){	;default is info
	MsgBox, % Options, % Title, % Text, % TimeOut
	IfMsgBox, Yes
		Return Text
	IfMsgBox, Ok
		Return Text
}


REV.1
  • Less flexible but all consumer functions bound to the same event handler are tied to a the same single timer,so more efficient where that matters & consumer functions are called in the same order with which they were subscribed to the event handler, a useful functional artifact.

Code: Select all


;Event Handler Prototype
EH.Subscribe("WinChangeEventHandlerExample", "CallbackExample", 500)
EH.Subscribe("WinChangeEventHandlerExample", "AnotherCallbackExample", 100)		;updating eventHandler poll freq here updates it for EH above as well.

class EH{	;EventHandler class to register event callbacks & enabled/disable registered event handlers
	Subscribe(eventHandlerName, callbackFunc, eventHandlerPollFreq:=100){
		#Persistent
		Global
		EH_%eventHandlerName% .=  callbackFunc ","
		SetTimer, % eventHandlerName, % eventHandlerPollFreq
	}
	
	Unsubscribe(eventHandlerName, callbackFunc, eventHandlerPollFreq:=100){
		Global
		EH_%eventHandlerName% .= StrReplace(EH_%eventHandlerName%, callbackFunc ",", "")
	}
	
	Disable(eventHandlerName){
		SetTimer, % eventHandlerName, off
	}
	
	Enable(eventHandlerName){
		SetTimer, % eventHandlerName, on
	}
	
}


CallbackExample(eventArray){
	For each, eventParam in eventArray
		MsgBox(A_ThisFunc "`n`n" each "`n" eventParam)
}

AnotherCallbackExample(eventArray){
	For each, eventParam in eventArray
		params .= each " - " eventParam "`n"
	MsgBox(A_ThisFunc "`n`n" params)	
}

WinChangeEventHandlerExample(){
	Global
	callbacks := StrSplit(EH_%A_ThisFunc%, ",")
	eventArray := []
	;MsgBox % callbacks
	;check if active window changed, exec callbacks when it does
	static lastHwnd := lastHwnd ? lastHwnd : WinExist("A")
	If ( WinExist("A") != lastHwnd ){
		lastHwnd := WinExist("A")
		WinGetActiveStats, activeTitle, activeW, activeH, activeX, activeY
		eventArray := {id:lastHwnd, title:activeTitle, x:activeX, y:activeY, w:activeW, h:activeH}
		For each, callback in callbacks
			If Trim(callback)
				IsFunc(callback) ? %callback%(eventArray) : MsgBox("Error: `n`n`t" A_ThisFunc "`n`nEventHandler attempted to call non existent callback function: " callback, A_ScriptName,"0x40010")
		SoundBeep
	}
}

MsgBox(Text:="", Title:="", Options:="0x40040", TimeOut:=""){	;default is info
	MsgBox, % Options, % Title, % Text, % TimeOut
	IfMsgBox, Yes
		Return Text
	IfMsgBox, Ok
		Return Text
}

User avatar
Chunjee
Posts: 1421
Joined: 18 Apr 2014, 19:05
Contact:

Re: [Class] Event Handler

13 Mar 2020, 11:19

I absolutely need this. Perfect timing, thank you for writing it as a class.

Much appreciated.
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: [Class] Event Handler

13 Mar 2020, 23:42

what other events do you use besides the active window change?

0x00
Posts: 89
Joined: 22 Jan 2019, 13:12

Re: [Class] Event Handler

15 Mar 2020, 15:34

guest3456 wrote:
13 Mar 2020, 23:42
what other events do you use besides the active window change?
Here's an example of an additional particular use case that might be generally useful, but generally an event driven approach is useful for any application where unpredictable(frequency of change, variations in active event attributes,...) variances in data are used to define logic instead of unique instances of code... It's also far easier to maintain event driven scripts, where large scripts that need to be very responsive are concerned.
Spoiler
Some other Event Handlers,functionally described as posting them would serve no purpose given the dependence on third party apps,mostly...
Spoiler

I didn't include more example events, as i mainly use events with either a lot of third party apps to get data or events are used to retrieve information to act on particular apps most may not use, I write normal scripts/functions for ordinary use cases where defining an event isn't worth the effort, it's not about simple code reuse but more about code reuse in large scripts & most importantly very high level abstractions of most frequently used data sets such as active window/change, networked devices,etc....
guest3456
Posts: 3463
Joined: 09 Oct 2013, 10:31

Re: [Class] Event Handler

15 Mar 2020, 15:39

excellent, good examples thanks


Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 165 guests