Improve event emitter/subscription abilities
This commit is contained in:
@@ -1,14 +1,9 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/colorstring"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type EventListeners map[string][]EventListenerFunction
|
||||
|
||||
type EventListenerFunction *func(string)
|
||||
|
||||
// Defines all of the possible output events for a server.
|
||||
// noinspection GoNameStartsWithPackageName
|
||||
const (
|
||||
@@ -19,47 +14,63 @@ const (
|
||||
StatsEvent = "stats"
|
||||
)
|
||||
|
||||
// Adds an event listener for the server instance.
|
||||
func (s *Server) AddListener(event string, f EventListenerFunction) {
|
||||
if s.listeners == nil {
|
||||
s.listeners = make(map[string][]EventListenerFunction)
|
||||
type Event struct {
|
||||
Data string
|
||||
Topic string
|
||||
}
|
||||
|
||||
type EventBus struct {
|
||||
subscribers map[string][]chan Event
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// Returns the server's emitter instance.
|
||||
func (s *Server) Events() *EventBus {
|
||||
if s.emitter == nil {
|
||||
s.emitter = &EventBus{
|
||||
subscribers: map[string][]chan Event{},
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := s.listeners[event]; ok {
|
||||
s.listeners[event] = append(s.listeners[event], f)
|
||||
} else {
|
||||
s.listeners[event] = []EventListenerFunction{f}
|
||||
return s.emitter
|
||||
}
|
||||
|
||||
// Publish data to a given topic.
|
||||
func (e *EventBus) Publish(topic string, data string) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if ch, ok := e.subscribers[topic]; ok {
|
||||
go func(data Event, cs []chan Event) {
|
||||
for _, channel := range cs {
|
||||
channel <- data
|
||||
}
|
||||
}(Event{Data: data, Topic: topic}, ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Removes the event listener for the server instance.
|
||||
func (s *Server) RemoveListener(event string, f EventListenerFunction) {
|
||||
if _, ok := s.listeners[event]; ok {
|
||||
for i := range s.listeners[event] {
|
||||
if s.listeners[event][i] == f {
|
||||
s.listeners[event] = append(s.listeners[event][:i], s.listeners[event][i+1:]...)
|
||||
break
|
||||
// Subscribe to an emitter topic using a channel.
|
||||
func (e *EventBus) Subscribe(topic string, ch chan Event) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if p, ok := e.subscribers[topic]; ok {
|
||||
e.subscribers[topic] = append(p, ch)
|
||||
} else {
|
||||
e.subscribers[topic] = append([]chan Event{}, ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Unsubscribe a channel from a topic.
|
||||
func (e *EventBus) Unsubscribe(topic string, ch chan Event) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if _, ok := e.subscribers[topic]; ok {
|
||||
for i := range e.subscribers[topic] {
|
||||
if ch == e.subscribers[topic][i] {
|
||||
e.subscribers[topic] = append(e.subscribers[topic][:i], e.subscribers[topic][i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emits an event to all of the active listeners for a server.
|
||||
func (s *Server) Emit(event string, data string) {
|
||||
if _, ok := s.listeners[event]; ok {
|
||||
for _, handler := range s.listeners[event] {
|
||||
go func(f EventListenerFunction, d string) {
|
||||
(*f)(d)
|
||||
}(handler, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sends output to the server console formatted to appear correctly as being sent
|
||||
// from Wings.
|
||||
func (s *Server) SendConsoleOutputFromDaemon(data string) {
|
||||
s.Emit(
|
||||
ConsoleOutputEvent,
|
||||
colorstring.Color(fmt.Sprintf("[yellow][bold][Pterodactyl Daemon]:[default] %s", data)),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user