<commit_before>package events

import (
	"fmt"
	"time"

	"github.com/Cristofori/kmud/database"
	"github.com/Cristofori/kmud/types"
	"github.com/Cristofori/kmud/utils"
)

type eventListener struct {
	Channel   chan Event
	Character types.Character
}

var _listeners map[types.Character]chan Event

var eventMessages chan interface{}

type register eventListener

type unregister struct {
	Character types.Character
}

type broadcast struct {
	Event Event
}

func Register(receiver types.Character) chan Event {
	listener := eventListener{Character: receiver, Channel: make(chan Event, 20)}
	eventMessages <- register(listener)
	return listener.Channel
}

func Unregister(char types.Character) {
	eventMessages <- unregister{char}
}

func Broadcast(event Event) {
	eventMessages <- broadcast{event}
}

func StopEvents() {
	close(eventMessages)
}

func StartEvents() {
	if _listeners != nil {
		return
	}

	_listeners = map[types.Character]chan Event{}

	eventMessages = make(chan interface{}, 1)

	go func() {
		for message := range eventMessages {
			switch m := message.(type) {
			case register:
				_listeners[m.Character] = m.Channel
			case unregister:
				delete(_listeners, m.Character)
			case broadcast:
				for char, channel := range _listeners {
					if m.Event.IsFor(char) {
						if len(channel) == cap(channel) {
							// TODO - Kill the session rather than the whole server
							panic(fmt.Sprintf("Buffer full! %s %v", char.GetName(), m.Event))
						}

						channel <- m.Event
					}
				}
			default:
				panic("Unhandled event message")
			}
		}

		_listeners = nil
	}()

	go func() {
		throttler := utils.NewThrottler(1 * time.Second)

		for {
			throttler.Sync()
			Broadcast(TickEvent{})
		}
	}()
}

type EventReceiver interface {
	types.Identifiable
	types.Locateable
}<commit_msg>Use goroutines for individual event passing<commit_after>package events

import (
	"fmt"
	"time"

	"github.com/Cristofori/kmud/database"
	"github.com/Cristofori/kmud/types"
	"github.com/Cristofori/kmud/utils"
)

type eventListener struct {
	Channel   chan Event
	Character types.Character
}

var _listeners map[types.Character]chan Event

var eventMessages chan interface{}

type register eventListener

type unregister struct {
	Character types.Character
}

type broadcast struct {
	Event Event
}

func Register(receiver types.Character) chan Event {
	listener := eventListener{Character: receiver, Channel: make(chan Event)}
	eventMessages <- register(listener)
	return listener.Channel
}

func Unregister(char types.Character) {
	eventMessages <- unregister{char}
}

func Broadcast(event Event) {
	eventMessages <- broadcast{event}
}

func StopEvents() {
	close(eventMessages)
}

func StartEvents() {
	if _listeners != nil {
		return
	}

	_listeners = map[types.Character]chan Event{}

	eventMessages = make(chan interface{}, 1)

	go func() {
		for message := range eventMessages {
			switch m := message.(type) {
			case register:
				_listeners[m.Character] = m.Channel
			case unregister:
				delete(_listeners, m.Character)
			case broadcast:
				for char, channel := range _listeners {
					if m.Event.IsFor(char) {
						go func(c chan Event) {
							c <- m.Event
						}(channel)
					}
				}
			default:
				panic("Unhandled event message")
			}
		}

		_listeners = nil
	}()

	go func() {
		throttler := utils.NewThrottler(1 * time.Second)

		for {
			throttler.Sync()
			Broadcast(TickEvent{})
		}
	}()
}

type EventReceiver interface {
	types.Identifiable
	types.Locateable
}
{'fraction_non_alphanumeric': 0.11101573676680973, 'fraction_numerical': 0.0017167381974248926, 'mean_word_length': 3.6989247311827955, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3660286', 'n_tokens_mistral': 1295, 'n_tokens_neox': 1128, 'n_words': 279}