bal-util
Version:
Common utility functions for Node.js used and maintained by Benjamin Lupton
245 lines (223 loc) • 5.03 kB
text/coffeescript
# Import
{EventEmitter} = require('events')
typeChecker = require('typechecker')
# =====================================
# Event & EventSystem
# Extends the EventEmitterEnhanced with support for:
# - blocking events
# - start and finish events
# Event
class Event
# The name of the event
name: null
# Is the event currently locked?
locked: false
# Has the event finished running?
finished: false
# Apply our name on construction
constructor: ({@name}) ->
# EventSystem
class EventSystem extends EventEmitter
# Event store
# initialised in our event function to prevent javascript reference problems
_eventSystemEvents: null
# Fetch the event object for the event
event: (eventName) ->
# Prepare
# Return the fetched event, create it if it doesn't exist already
# Lock the event
# next(err)
lock: (eventName, next) ->
# Grab the event
event = @event eventName
# Grab a lock on the event
if event.locked is false
# Place the lock
event.locked = true
# Trigger our event
# then fire our callback
try
catch err
next(err)
return @
finally
next()
else
# Wait until the current task has finished
return next(err) if err
# Then try again
# Chain
# Unlock the event
# next(err)
unlock: (eventName, next) ->
# Grab the event
event = @event eventName
# Release the lock
event.locked = false
# Trigger our event
# then fire our callback
try
catch err
next(err)
return @
finally
next()
# Chain
# Start our event
# 1. Performs a lock
# 2. Sets event's finished flag to false
# 3. Fires callback
# next(err)
start: (eventName, next) ->
# Grab a locak
# Error?
return next(err) if err
# Grab the event
event = @event eventName
# Set as started
event.finished = false
# Trigger our event
# then fire our callback
try
catch err
next(err)
return @
finally
next()
# Chain
# Finish, alias for finished
finish: (args...) ->
# Finished our event
# 1. Sets event's finished flag to true
# 2. Unlocks the event
# 3. Fires callback
# next(err)
finished: (eventName, next) ->
# Grab the event
event = @event eventName
# Set as finished
event.finished = true
# Unlock
# Error?
return next(err) if err
# Trigger our event
# then fire our callback
try
catch err
next(err)
return @
finally
next()
# Chain
# Run one time once an event has unlocked
# next(err)
onceUnlocked: (eventName, next) ->
# Grab the event
event = @event eventName
# Check lock status
if event.locked
# Wait until our event has unlocked to fire the callback
else
# Fire our callback now
next()
# Chain
# Run one time once an event has finished
# next(err)
onceFinished: (eventName, next) ->
# Grab the event
event = @event eventName
# Check finish status
if event.finished
# Fire our callback now
next()
else
# Wait until our event has finished to fire the callback
# Chain
# Run every time an event has finished
# next(err)
whenFinished: (eventName, next) ->
# Grab the event
event = @event eventName
# Check finish status
if event.finished
# Fire our callback now
next()
# Everytime our even has finished, fire the callback
# Chain
# When, alias for on
when: (args...) ->
# Block an event from running
# next(err)
block: (eventNames, next) ->
# Ensure array
unless typeChecker.isArray(eventNames)
if typeChecker.isString(eventNames)
eventNames = eventNames.split(/[,\s]+/g)
else
err = new Error('Unknown eventNames type')
return next(err)
total = eventNames.length
done = 0
# Block these events
for eventName in eventNames
# Error?
if err
done = total
return next(err)
# Increment
done++
if done is total
next()
# Chain
# Unblock an event from running
# next(err)
unblock: (eventNames, next) ->
# Ensure array
unless typeChecker.isArray(eventNames)
if typeChecker.isString(eventNames)
eventNames = eventNames.split /[,\s]+/g
else
err = new Error('Unknown eventNames type')
return next(err)
total = eventNames.length
done = 0
# Block these events
for eventName in eventNames
# Error?
if err
done = total
return next(err)
# Increment
done++
if done is total
next()
# Chain
# =====================================
# Export
module.exports = {Event,EventSystem}