Слияние кода завершено, страница обновится автоматически
package hxgo
import (
"reflect"
"errors"
)
// declare some event caller error
var (
// caller is not a function
EventCallerNotFunc = errors.New("invalid function for event caller")
// caller is not found
EventCallerNotExist = errors.New("no event caller")
// caller input params are not matched
EventCallerInError = errors.New("input data error in event caller")
)
// Event struct
// manage events binding and triggering
type Event struct {
callbacks map[string]EventCall
}
// EventCall struct
// saving event caller and input/output args
type EventCall struct {
caller reflect.Value
numIn int
numOut int
}
// On event
// add a function in event
func (this *Event) On(event string, call interface {}) error {
v := reflect.ValueOf(call)
if v.Type().Kind().String() != "func" {
return EventCallerNotFunc
}
c := EventCall{}
c.caller = v
c.numIn = v.Type().NumIn()
c.numOut = v.Type().NumOut()
this.callbacks[event] = c
return nil
}
// Live event
// add a function in event if no event is added
func (this *Event) Live(event string, call interface {}) error {
if this.Has(event) {
return nil
}
return this.On(event, call)
}
// Off event
// clear the func binding in event
func (this *Event) Off(event string) {
this.callbacks[event] = EventCall{}
}
// Check is event binding
// If a function is on event, return true
func (this *Event) Has(event string) bool {
return this.callbacks[event].caller.IsValid()
}
// Emit event
// Trigger event and return function execution result
// result is []interface as many as returning params
func (this *Event) Emit(event string, args...interface {}) (chan []interface {}, error) {
caller := this.callbacks[event]
if !caller.caller.IsValid() {
return nil, EventCallerNotExist
}
if len(args) != caller.numIn {
return nil, EventCallerInError
}
ch := make(chan []interface {})
go func() {
argsValue := make([]reflect.Value, caller.numIn)
for i := 0; i < caller.numIn; {
argsValue[i] = reflect.ValueOf(args[i])
i++
}
out := caller.caller.Call(argsValue)
rs := make([]interface {}, len(out))
if len(out) < 1 {
ch <- rs
}
for i, v := range out {
rs[i] = v.Interface()
}
ch <-rs
}()
return ch, nil
}
// create a new event trigger for binding and emitting
func NewEvent() *Event {
e := &Event{}
e.callbacks = make(map[string]EventCall)
return e
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )