commit 846344b425acab514d781923b4fc6cc7c84dd513 Author: inhere Date: Tue Dec 11 21:48:48 2018 +0800 init project diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76e1962 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +*.log +*.swp +.idea +*.patch +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d839cdc --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 inhere + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c7dacc --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# event + +[![GoDoc](https://godoc.org/github.com/gookit/event?status.svg)](https://godoc.org/github.com/gookit/event) +[![Go Report Card](https://goreportcard.com/badge/github.com/gookit/event)](https://goreportcard.com/report/github.com/gookit/event) + + +## Godoc + +- [godoc for github](https://godoc.org/github.com/gookit/event) + +## LICENSE + +**[MIT](LICENSE)** \ No newline at end of file diff --git a/event.go b/event.go new file mode 100644 index 0000000..4453a7f --- /dev/null +++ b/event.go @@ -0,0 +1,65 @@ +package event + +// EventFace +type EventFace interface { + Params() + Name() string + Stop(bool) +} + +// Event +type Event struct { + name string + stopped bool + target interface{} + params interface{} +} + +// New event instance +func New(name string) *Event { + return &Event{name: name} +} + +// Init +func (e *Event) Init(target, params interface{}) *Event { + return e +} + +// Clone current event object +func (e *Event) Clone() *Event { + ne := *e + ne.name = "" + ne.target = nil + ne.params = nil + ne.stopped = false + return &ne +} + +func (e *Event) Params() interface{} { + return e.params +} + +func (e *Event) SetParams(params interface{}) { + e.params = params +} + +func (e *Event) Name() string { + return e.name +} + +func (e *Event) SetName(name string) { + e.name = name +} + +func (e *Event) SetTarget(target interface{}) { + e.target = target +} + +func (e *Event) Target() interface{} { + return e.target +} + +// Stop +func (e *Event) Stop(stopped bool) { + e.stopped = stopped +} diff --git a/manager.go b/manager.go new file mode 100644 index 0000000..4e2a890 --- /dev/null +++ b/manager.go @@ -0,0 +1,19 @@ +package event + +import "sync" + +// Listener func definition +type Listener func(e EventFace) + +// Manager event manager definition +type Manager struct { + name string + pool sync.Pool + events map[string]EventFace + listeners []Listener +} + +// NewManager +func NewManager(name string) *Manager { + return &Manager{name: name} +} diff --git a/priority.go b/priority.go new file mode 100644 index 0000000..0e4b82e --- /dev/null +++ b/priority.go @@ -0,0 +1 @@ +package event diff --git a/simpleevent/README.md b/simpleevent/README.md new file mode 100644 index 0000000..ea1e8cc --- /dev/null +++ b/simpleevent/README.md @@ -0,0 +1,3 @@ +# simple event + +Simple event manager implements. \ No newline at end of file diff --git a/simpleevent/data.go b/simpleevent/data.go new file mode 100644 index 0000000..37d10e6 --- /dev/null +++ b/simpleevent/data.go @@ -0,0 +1,39 @@ +package simpleevent + +/************************************************************* + * Event Data + *************************************************************/ + +// EventData struct +type EventData struct { + aborted bool + // event name + name string + // user data. + Data []interface{} +} + +// Name get +func (e *EventData) Name() string { + return e.name +} + +// Abort abort event exec +func (e *EventData) Abort() { + e.aborted = true +} + +// Aborted check. +func (e *EventData) Aborted() bool { + return e.aborted +} + +func (e *EventData) init(s string, args []interface{}) { + e.name = s + e.Data = args +} + +func (e *EventData) reset() { + e.name = "" + e.Data = make([]interface{}, 0) +} diff --git a/simpleevent/manager.go b/simpleevent/manager.go new file mode 100644 index 0000000..cfb49e9 --- /dev/null +++ b/simpleevent/manager.go @@ -0,0 +1,137 @@ +package simpleevent + +import ( + "strings" + "sync" +) + +const wildcard = "*" + +// EventHandler func define +type EventHandler func(e *EventData) error + +/************************************************************* + * Event Manager + *************************************************************/ + +// EventManager struct +type EventManager struct { + names map[string]int + events map[string][]EventHandler + pool sync.Pool +} + +// NewEventManager create EventManager instance +func NewEventManager() *EventManager { + em := &EventManager{ + names: make(map[string]int), + events: make(map[string][]EventHandler), + } + + // set pool creator + em.pool.New = func() interface{} { + return &EventData{} + } + + return em +} + +// On register a event handler +func (em *EventManager) On(name string, handler EventHandler) { + name = strings.TrimSpace(name) + if name == "" { + panic("event name cannot be empty") + } + + if ls, ok := em.events[name]; ok { + em.events[name] = append(ls, handler) + } else { // first add. + em.events[name] = []EventHandler{handler} + } +} + +// MustFire fire event by name +func (em *EventManager) MustFire(name string, args ...interface{}) { + err := em.Fire(name, args...) + if err != nil { + panic(err) + } +} + +// Fire event by name +func (em *EventManager) Fire(name string, args ...interface{}) (err error) { + handlers, ok := em.events[name] + if !ok { + return + } + + e := em.pool.Get().(*EventData) + e.init(name, args) + + defer func() { + e.reset() + em.pool.Put(e) + }() + + err = em.callHandlers(e, handlers) + if err != nil || e.Aborted() { + return + } + + // group listen "app.*" + // groupName := + + // wildcard event handler + if em.HasEvent(wildcard) { + err = em.callHandlers(e, em.events[wildcard]) + } + + return +} + +func (em *EventManager) callHandlers(e *EventData, handlers []EventHandler) (err error) { + for _, handler := range handlers { + err = handler(e) + if err != nil || e.Aborted() { + return + } + } + return +} + +// HasEvent has event check +func (em *EventManager) HasEvent(name string) bool { + _, ok := em.names[name] + return ok +} + +// DelEventsByName delete events by name +func (em *EventManager) DelEventsByName(name string) bool { + _, ok := em.names[name] + if ok { + delete(em.names, name) + delete(em.events, name) + } + return ok +} + +// EventsByName get events and handlers by name +func (em *EventManager) EventsByName(name string) (es []EventHandler) { + es, _ = em.events[name] + return +} + +// Events get all events and handlers +func (em *EventManager) Events() map[string][]EventHandler { + return em.events +} + +// Names get all event names +func (em *EventManager) Names() map[string]int { + return em.names +} + +// Clear all events info. +func (em *EventManager) Clear() { + em.events = map[string][]EventHandler{} +}