Skip to content

Instantly share code, notes, and snippets.

@frostney
Created December 2, 2012 17:01
Show Gist options
  • Save frostney/4189845 to your computer and use it in GitHub Desktop.
Save frostney/4189845 to your computer and use it in GitHub Desktop.
Collection class in Coffeescript including proxies (e.g. adding function to when a key is changed like triggering a redraw of the UI).
class Collection
data =
collection: {}
state: {}
proxies:
handler: {}
keyHandler: {}
contructor: (content) ->
if content
if typeof content is 'string'
@fromString content
else
@set content
fromString: (content) -> data.collection = JSON.parse content
toString: -> JSON.stringify data.collection
add: (key, value, state = 'rw') ->
unless @exists key
@proxy 'add', key, value
data.collection[key] = value
state = 'ro' if state is 'readonly' or state is 'read-only' or state is 'readOnly'
state = 'wo' if state is 'writeonly' or state is 'write-only' or state is 'writeOnly'
data.state[key] = state
exists: (key) ->
@proxy 'exists', key
Object.hasOwnProperty.call data.collection, key
has: @exists
remove: (key) ->
@proxy 'remove', key
delete data.collection[key]
keys: -> Object.keys(data.collection);
on: (name, key, proxyFn) ->
if key and typeof key is 'string'
data.proxies.keyHandler[name] or= {}
data.proxies.keyHandler[name][key] = proxyFn
else
proxyFn = key
data.proxies.handler[name] or= []
data.proxies.handler[name].push proxyFn
off: (name, key) ->
if key
if typeof key is 'number'
data.proxies.handler[name].splice key, 1 if data.proxies.handler[name]?
else
delete data.proxies.keyHandler[name][key] if data.proxies.keyHandler[name]?[key]?
else
delete data.proxies.handler[name]
proxy: (name, key, args...) ->
if data.proxies.handler[name]
for i in data.proxies.handler[name]
i()
if key
args.splice(0, 0, key)
data.proxies.keyHandler[name][key] args... if data.proxies.keyHandler[name]?[key]?
get: (key) ->
if data.state[key] isnt 'wo'
@proxy 'get', key
data.collection[key]
else
undefined
set: (key, value) ->
if value
if @exists key
if data.state[key] isnt 'ro'
data.collection[key] = value
@proxy 'set', key, value
else
@add key, value
else
for k, v of key
@set.call @, k, v
null
each: (callback) ->
for key, value of data.collection
callback key, value
null
map: (callback) ->
result = {}
for key, value of data.collection
result[key] = callback key, value
result
filter: (callback) ->
result = {}
for key, value in data.collection
result[key] = data.collection[key] unless callback data.collection[key]
result
isEmpty: -> @keys().length is 0
# First of all, create a new collection object
myCollection = new Collection()
# Add a general proxy event
myCollection.on 'add', -> console.log 'We are adding stuff now!'
# Add another one
myCollection.on 'set', -> console.log 'Something changed'
# Only fire this event if a key called test has been added
myCollection.on 'add', 'test', (key) -> console.log key
# Add the key
myCollection.add 'test', 5
# Change a key
myCollection.set 'test', 10
# Implicitly add a new key
myCollection.set 'newkey', 7
console.log myCollection.keys()
# Add a whole bunch of stuff
myCollection.set {one: 1, two: 2, three: 3}
# Remove a key
myCollection.remove 'newkey'
# Show all keys
console.log myCollection.keys()
# Add a new read-only key
myCollection.add 'nochange', 'noooo!!!', 'ro'
console.log myCollection.get('nochange')
myCollection.set 'nochange', 'yesss!!!'
console.log myCollection.get('nochange')
# Check if collection is empty
console.log "Collection is empty: #{myCollection.isEmpty()}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment