diff --git a/v2/internal/messagedispatcher/message/event.go b/v2/internal/messagedispatcher/message/event.go index 47aa0f7d1..dcb133e48 100644 --- a/v2/internal/messagedispatcher/message/event.go +++ b/v2/internal/messagedispatcher/message/event.go @@ -13,6 +13,7 @@ type EventMessage struct { type OnEventMessage struct { Name string Callback func(optionalData ...interface{}) + Counter int } // eventMessageParser does what it says on the tin! @@ -28,8 +29,6 @@ func eventMessageParser(message string) (*parsedMessage, error) { // Switch the event type (with or without data) switch message[0] { - case 'e': - eventMessage.Name = message[2:] case 'E': m := message[2:] err := json.Unmarshal([]byte(m), eventMessage) diff --git a/v2/internal/runtime/goruntime/events.go b/v2/internal/runtime/goruntime/events.go index bba45bd73..850166d1c 100644 --- a/v2/internal/runtime/goruntime/events.go +++ b/v2/internal/runtime/goruntime/events.go @@ -8,6 +8,7 @@ import ( // Events defines all events related operations type Events interface { On(eventName string, callback func(optionalData ...interface{})) + Once(eventName string, callback func(optionalData ...interface{})) Emit(eventName string, optionalData ...interface{}) } @@ -28,6 +29,17 @@ func (r *event) On(eventName string, callback func(optionalData ...interface{})) eventMessage := &message.OnEventMessage{ Name: eventName, Callback: callback, + Counter: -1, + } + r.bus.Publish("event:on", eventMessage) +} + +// On pass through +func (r *event) Once(eventName string, callback func(optionalData ...interface{})) { + eventMessage := &message.OnEventMessage{ + Name: eventName, + Callback: callback, + Counter: 1, } r.bus.Publish("event:on", eventMessage) } diff --git a/v2/internal/runtime/js/core/events.js b/v2/internal/runtime/js/core/events.js index a0dd2b1c2..5a60fc3f3 100644 --- a/v2/internal/runtime/js/core/events.js +++ b/v2/internal/runtime/js/core/events.js @@ -137,17 +137,11 @@ export function Notify(notifyMessage) { */ export function Emit(eventName) { - // Calculate the data - if (arguments.length > 1) { - // Notify backend - const payload = { - name: eventName, - data: [].slice.apply(arguments).slice(1), - }; - SendMessage('Ej' + JSON.stringify(payload)); - } else { - SendMessage('ej' + eventName); - } + const payload = { + name: eventName, + data: [].slice.apply(arguments).slice(1), + }; + SendMessage('Ej' + JSON.stringify(payload)); } diff --git a/v2/internal/subsystem/event.go b/v2/internal/subsystem/event.go index 886029094..aa219f8d4 100644 --- a/v2/internal/subsystem/event.go +++ b/v2/internal/subsystem/event.go @@ -15,7 +15,7 @@ import ( // means it does not expire (default). type eventListener struct { callback func(...interface{}) // Function to call with emitted event data - counter int64 // The number of times this callback may be called. -1 = infinite + counter int // The number of times this callback may be called. -1 = infinite delete bool // Flag to indicate that this listener should be deleted } @@ -60,12 +60,12 @@ func NewEvent(bus *servicebus.ServiceBus, logger *logger.Logger) (*Event, error) } // RegisterListener provides a means of subscribing to events of type "eventName" -func (e *Event) RegisterListener(eventName string, callback func(...interface{})) { +func (e *Event) RegisterListener(eventName string, callback func(...interface{}), counter int) { // Create new eventListener thisListener := &eventListener{ callback: callback, - counter: 0, + counter: counter, delete: false, } @@ -120,7 +120,7 @@ func (e *Event) Start() error { var message *message.OnEventMessage = eventMessage.Data().(*message.OnEventMessage) eventName := message.Name callback := message.Callback - e.RegisterListener(eventName, callback) + e.RegisterListener(eventName, callback, message.Counter) e.logger.Trace("Registered listener for event '%s' with callback %p", eventName, callback) default: e.logger.Error("unknown event message: %+v", eventMessage) @@ -179,13 +179,16 @@ func (e *Event) notifyListeners(eventName string, message *message.EventMessage) } } - // Save new listeners - e.listeners[eventName] = newListeners + // Save new listeners or remove entry + if len(newListeners) > 0 { + e.listeners[eventName] = newListeners + } else { + delete(e.listeners, eventName) + } } // Unlock e.notifyLock.Unlock() - } func (e *Event) shutdown() { diff --git a/v2/test/runtime/runtime.go b/v2/test/runtime/runtime.go index 5d1bc73b0..f3c10fe55 100644 --- a/v2/test/runtime/runtime.go +++ b/v2/test/runtime/runtime.go @@ -23,6 +23,9 @@ func (r *RuntimeTest) WailsInit(runtime *wails.Runtime) error { r.runtime.Events.On("testevent", func(optionalParams ...interface{}) { println("Wooohoooo! I got called!") }) + r.runtime.Events.Once("testeventonce", func(optionalParams ...interface{}) { + println("I only get called once!") + }) return nil }