v8Util = process.atomBinding 'v8_util' module.exports = class CallbacksRegistry constructor: -> @nextId = 0 @callbacks = {} add: (callback) -> ### The callback is already added. ### id = v8Util.getHiddenValue callback, 'callbackId' return id if id? id = ++@nextId ### Capture the location of the function and put it in the ID string, so that release errors can be tracked down easily. ### regexp = /at (.*)/gi stackString = (new Error).stack while (match = regexp.exec(stackString)) isnt null [x, location] = match continue if location.indexOf('(native)') isnt -1 continue if location.indexOf('atom.asar') isnt -1 [x, filenameAndLine] = /([^/^\)]*)\)?$/gi.exec(location) break @callbacks[id] = callback v8Util.setHiddenValue callback, 'callbackId', id v8Util.setHiddenValue callback, 'location', filenameAndLine id get: (id) -> @callbacks[id] ? -> call: (id, args...) -> @get(id).call global, args... apply: (id, args...) -> @get(id).apply global, args... remove: (id) -> delete @callbacks[id]