Browse Source

Add contextual event buses

luis 7 years ago
parent
commit
0b4fed102e
5 changed files with 107 additions and 12 deletions
  1. 7 0
      README.md
  2. 11 0
      TODO.md
  3. 19 4
      bus.go
  4. 35 8
      event_test.go
  5. 35 0
      system.go

+ 7 - 0
README.md

@@ -3,3 +3,10 @@ Event
 
 Really simple event Bus
 
+```go
+	bus1 := eventSystem.Bus()
+
+	bus1.Emit("test")
+
+```
+

+ 11 - 0
TODO.md

@@ -0,0 +1,11 @@
+
+Contextual event buses
+
+```go
+ctx := eventSystem.Context()
+
+ctx.On("something",...) // adds a listener for system wide something
+ctx.Emit("something") // Emit system wide
+
+eventSystem.Remove(ctx) // remove all listeners declared by ctx
+```

+ 19 - 4
bus.go

@@ -2,7 +2,7 @@ package event
 
 // Should be called manager?
 
-// Bus can be implemente in other sturcts
+// Bus can be implemente in other structs
 type Bus interface {
 	Emitter
 	Receiver
@@ -10,14 +10,16 @@ type Bus interface {
 
 // EventBus implementation
 type eventBus struct {
+	system   *System
 	handlers map[string]*[]HandlerFunc
 }
 
 // NewBus Creates and Initializes an eventBus
-func NewBus() Bus {
+/*func NewBus() Bus {
 	return &eventBus{handlers: map[string]*[]HandlerFunc{}}
-}
-func (e *eventBus) Emit(evt Event) {
+}*/
+
+func (e *eventBus) handleEvent(evt Event) {
 	handlerList, ok := e.handlers[evt.Name()]
 	if !ok {
 		return
@@ -25,9 +27,22 @@ func (e *eventBus) Emit(evt Event) {
 	for _, handler := range *handlerList {
 		handler(evt)
 	}
+	// Special case
+	catchList, ok := e.handlers["*"]
+	if !ok {
+		return
+	}
+	for _, handler := range *catchList {
+		handler(evt)
+	}
+}
 
+// This should send to system
+func (e *eventBus) Emit(evt Event) {
+	e.system.handleEvent(evt) // Forward to system
 }
 
+// Register locally
 func (e *eventBus) On(name string, handler HandlerFunc) {
 	handlerList, ok := e.handlers[name]
 	if !ok {

+ 35 - 8
event_test.go

@@ -7,16 +7,14 @@ import (
 )
 
 func TestEvent(t *testing.T) {
-
-	bus := event.NewBus()
+	es := event.NewSystem()
+	bus := es.NewBus()
 	a := 0
 	bus.On("test", func(evt event.Event) {
 		t.Log("Event successfull")
 		a++
 	})
-
 	bus.Emit(event.New("test", nil))
-
 	if a != 1 {
 		t.Fatal("Event Failed")
 	}
@@ -25,8 +23,8 @@ func TestEvent(t *testing.T) {
 
 // Testing a named emitter that prefixes events
 func TestNamedEmitter(t *testing.T) {
-
-	bus := event.NewBus()
+	es := event.NewSystem()
+	bus := es.NewBus()
 
 	em := event.NewNamedEmitter("user", bus)
 
@@ -46,13 +44,41 @@ func TestNamedEmitter(t *testing.T) {
 		t.Fail()
 	}
 }
+func TestMultiBus(t *testing.T) {
+	es := event.NewSystem()
+	bus1 := es.NewBus()
+	bus2 := es.NewBus()
+
+	cevt := 0
+	bus1.On("test", func(evt event.Event) {
+		t.Log("Bus1 evt")
+		cevt++
+	})
+	bus2.On("test", func(evt event.Event) {
+		t.Log("Bus2 evt")
+		cevt++
+	})
+	bus1.Emit(event.New("test", nil))
+	if cevt != 2 {
+		t.Fatal("mismatch number of events consumed")
+	}
+	es.RemoveBus(bus2)
+
+	bus1.Emit(event.New("test", nil))
+
+	if cevt != 3 {
+		t.Fatal("mismatch number of events consumed, should be 3")
+	}
+
+}
 
 type MyStruct struct {
 	event.Emitter
 }
 
 func TestCustomStruct(t *testing.T) {
-	bus := event.NewBus()
+	es := event.NewSystem()
+	bus := es.NewBus()
 	a := 0
 
 	bus.On("MyStruct:test", func(evt event.Event) {
@@ -67,7 +93,8 @@ func TestCustomStruct(t *testing.T) {
 }
 
 func TestParamData(t *testing.T) {
-	bus := event.NewBus()
+	es := event.NewSystem()
+	bus := es.NewBus()
 	bus.On("test", func(evt event.Event) {
 		str := evt.Data().(string)
 		if str != "123" {

+ 35 - 0
system.go

@@ -0,0 +1,35 @@
+package event
+
+type System struct {
+	busList []*eventBus
+}
+
+func NewSystem() *System {
+	return &System{[]*eventBus{}}
+}
+
+func (s *System) NewBus() Bus {
+	evtBus := &eventBus{s, map[string]*[]HandlerFunc{}}
+	s.busList = append(s.busList, evtBus)
+
+	return evtBus
+}
+func (s *System) RemoveBus(bus Bus) {
+	where := -1
+	for i, b := range s.busList {
+		if b == bus { // Pointer comparison somehow?
+			where = i
+			break
+		}
+	}
+
+	s.busList = append(s.busList[:where], s.busList[where+1:]...)
+
+}
+
+func (s *System) handleEvent(evt Event) {
+	// Pass this event trough all buses
+	for _, bus := range s.busList {
+		bus.handleEvent(evt)
+	}
+}