event_emitter~hugoabonizio
Event Emitter
EventEmitter provides an idiomatic asynchronous event-driven architecture by registering listener functions that are called by named event emits. This shard is heavily inspired by Node.js events API.
When the emit method is called, the listeners attached to it will be called (synchronously or asynchronously) with the possibility to pass arguments to it.
The following example shows a simple EventEmitter usage with a single listener.
require "event_emitter"
class MyEmitter
include EventEmitter::DSL
on :connect, sync: true do |name|
puts "Hello #{name}"
end
def connect(name)
emit :connect, name
end
end
emitter = MyEmitter.new
emitter.connect("Hugo")
Another approach is to inherit from EventEmitter::Base class, as the example above:
class MyEmitter < EventEmitter::Base; end
my = MyEmitter.new
my.on :event do |name|
puts "Hello #{name}"
end
my.emit :event, "hugo"
my.emit :event, "abonizio"
Usage
DSL
Synchronous and asynchronous
A listener can execute a block synchronously or asynchronously depending on the argument sync it is passed.
# Asynchronous (executed in another fiber)
on :message, do |message|
puts "ASYNC: Message: #{message}"
end
# Synchronous
on :connect, sync: true do |name|
puts "SYNC: Hello #{name}"
end
Passing arguments to the listeners
class MyEmitter
include EventEmitter::DSL
on :finish do |id, name|
puts "Hello #{name} (#{id})"
end
def perform(name)
id = User.create(name)
emit :finish, id, name
end
end
Instance
The class EventEmitter::Base provides the methods on, once and emit to insert a new listener, insert a one-time listener and trigger an event, respectively. It also provides an all method for responding to all events, and a remove_listener method to delete a listener.
You can inherit from EventEmitter::Base class to add custom functionality (class MyEmitter < EventEmitter::Base; end) or simply create an instance of EventEmitter::Base as the following example.
emitter = EventEmitter::Base.new
emitter.on :message do |body|
puts "> #{body}"
end
delay 200.milliseconds do
emitter.emit :message, "Hello, world!"
end
Handling events only once:
emitter = EventEmitter::Base.new
flag = 1
emitter.once :trigger do
flag = 2
end
emitter.emit :trigger
emitter.emit :trigger # Will execute only the first trigger
Listening to all events:
emitter = EventEmitter::Base.new
flag = 0
emitter.all { flag += 1 }
emitter.emit(:foo)
emitter.emit(:bar)
emitter.emit(:foobar)
puts flag
# => 3
Removing an event listener:
emitter = EventEmitter::Base.new
flag = 0
emitter.on(:foo) { flag += 1 }
emitter.emit(:foo)
emitter.remove_listener(:foo)
emitter.emit(:foo)
puts flag
# => 1
Installation
Add this to your application's shard.yml:
dependencies:
event_emitter:
github: hugoabonizio/event_emitter.cr
Contributing
- Fork it ( https://github.com/hugoabonizio/event_emitter.cr/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- hugoabonizio Hugo Abonizio - creator, maintainer
- watzon Chris Watson - contributor