In programming, event managers are a common tool for triggering actions through notifications. In Go language, we can implement event processing by creating event managers and listeners. This article will introduce the implementation of a simple Go event manager and improve its performance through asynchronous improvements.
Listener
First, we need to create a listener. In this implementation, the listener is just a function that receives event parameters.
type Listener[T any] func(T)
Event Manager
Event Manager is a structure used to manage events and listeners. It has two methods:Add
andRun
。Add
Method is used to attach a new listener to an event, andRun
Methods are used to execute event managers.
type Manager[T any] interface { Add(n string, l Listener[T]) Run() }
Abstract Event Manager
For ease of use, we can create an abstract event manager that implements part of the general logic of the event manager interface. Although Go is not object-oriented, we can achieve similar effects through simulation.
type BaseManager[T any] struct { lst map[string][]Listener[T] } func (m *BaseManager[T]) Invoke(n string, args T) { for _, ls := range [n] { ls(args) } } func (m *BaseManager[T]) Add(n string, l Listener[T]) { [n] = append([n], l) }
BaseManager
ProvidedAdd
Methods are used to add listeners andInvoke
Method is used to trigger the listener for the specified event.
Specific event manager
The following is an example implementation of a specific event manager: Command Event Manager. The manager receives commands entered by the user from the console and triggers the corresponding event according to the command type.
type Command struct { Kind string Args []string } type CommandEventManager struct { BaseManager[*Command] } func (m *CommandEventManager) Run() { var ( inp string args Command ) (&inp) cmd := (inp, ":") if l := len(cmd); l == 0 { ("no-command", nil) } else if l > 1 { = (cmd[1], " ") } = cmd[0] ("any-command", &args) (, &args) } func NewCommandEventManager() Manager[*Command] { return &CommandEventManager{ BaseManager: BaseManager[*Command]{lst: make(map[string][]Listener[*Command])}, } }
Run
Methods obtain commands entered by the user from the console and parse command parameters. If there are no commands or command parameters, the "no-command" event is triggered; otherwise, the "any-command" event and specific command events are triggered.
Add a listener
Let's add some listeners to the command event manager.
func main() { cem := NewCommandEventManager() ("no-command", func(_ *Command) { ("no command was recieved") }) ("any-command", func(c *Command) { ("the %s command was executed", ) }) ("sum", func(c *Command) { a, _ := ([0]) b, _ := ([1]) ("the sum result is: %d", a+b) }) () }
In the example above, the program is executed only once, but you can put it in an infinite loop to continuously listen for commands.
Asynchronous improvements
The execution of the event manager can be changed to asynchronously to improve performance. Each time an event is executed, it can be used as agoroutine
Perform processing. Even the execution of each listener can be placed in onegoroutine
to improve concurrency performance.
Through the above improvements, we can better utilize the concurrency characteristics of Go language and improve event processing efficiency.
This is the end of this article about simply implementing event manager based on Go. For more related go event manager content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!