Separate stored objects by the render view.

When a render view is closed, it's not guarrenteed that all objects'
weak callback would be called. So we must clean up all objects manually
after the render view gets closed.
This commit is contained in:
Cheng Zhao 2013-04-26 21:14:29 +08:00
parent e91d4c7c99
commit dded164052
2 changed files with 35 additions and 33 deletions

View file

@ -1,22 +1,22 @@
module.exports =
class ObjectsRegistry
@nextId = 0
IDWeakMap = require 'id_weak_map'
constructor: ->
@objects = []
globalStore = {}
globalMap = new IDWeakMap
getNextId: ->
++ObjectsRegistry.nextId
getStoreForRenderView = (process_id, routing_id) ->
key = "#{process_id}_#{routing_id}"
globalStore[key] = {} unless globalStore[key]?
globalStore[key]
add: (obj) ->
id = @getNextId()
@objects[id] = obj
id
exports.add = (process_id, routing_id, obj) ->
id = globalMap.add obj
store = getStoreForRenderView process_id, routing_id
store[id] = obj
id
remove: (id) ->
obj = @objects[id]
delete @objects[id]
obj
exports.get = (process_id, routing_id, id) ->
globalMap.get id
get: (id) ->
@objects[id]
exports.remove = (process_id, routing_id, id) ->
store = getStoreForRenderView process_id, routing_id
delete store[id]

View file

@ -1,21 +1,20 @@
ipc = require 'ipc'
path = require 'path'
ObjectsRegistry = require './objects_registry.js'
objectsRegistry = new ObjectsRegistry
objectsRegistry = require './objects_registry.js'
class PlainObject
constructor: (value) ->
constructor: (process_id, routing_id, value) ->
@type = typeof value
@type = 'value' if value is null
@type = 'array' if Array.isArray value
if @type is 'array'
@members = []
@members.push new PlainObject(el) for el in value
@members.push new PlainObject(process_id, routing_id, el) for el in value
else if @type is 'object' or @type is 'function'
@name = value.constructor.name
@id = objectsRegistry.add value
@id = objectsRegistry.add process_id, routing_id, value
value.id = @id
@members = []
@members.push { name: prop, type: typeof field } for prop, field of value
@ -24,44 +23,47 @@ class PlainObject
@value = value
ipc.on 'ATOM_INTERNAL_REQUIRE', (event, process_id, routing_id, module) ->
event.result = new PlainObject(require(module))
event.result = new PlainObject(process_id, routing_id, require(module))
ipc.on 'ATOM_INTERNAL_CONSTRUCTOR', (event, process_id, routing_id, id, args) ->
try
constructor = objectsRegistry.get id
constructor = objectsRegistry.get process_id, routing_id, id
# Call new with array of arguments.
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
obj = new (Function::bind.apply(constructor, [null].concat(args)))
event.result = new PlainObject(obj)
event.result = new PlainObject(process_id, routing_id, obj)
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_FUNCTION_CALL', (event, process_id, routing_id, id, args) ->
try
ret = objectsRegistry.get(id).apply global, args
event.result = new PlainObject(ret)
func = objectsRegistry.get process_id, routing_id, id
ret = func.apply global, args
event.result = new PlainObject(process_id, routing_id, ret)
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_MEMBER_CALL', (event, process_id, routing_id, id, method, args) ->
try
obj = objectsRegistry.get id
obj = objectsRegistry.get process_id, routing_id, id
ret = obj[method].apply(obj, args)
event.result = new PlainObject(ret)
event.result = new PlainObject(process_id, routing_id, ret)
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_MEMBER_SET', (event, process_id, routing_id, id, name, value) ->
try
objectsRegistry.get(id)[name] = value
obj = objectsRegistry.get process_id, routing_id, id
obj[name] = value
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_MEMBER_GET', (event, process_id, routing_id, id, name) ->
try
event.result = new PlainObject(objectsRegistry.get(id)[name])
obj = objectsRegistry.get process_id, routing_id, id
event.result = new PlainObject(process_id, routing_id, obj[name])
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_DESTROY', (process_id, routing_id, id) ->
objectsRegistry.remove id
objectsRegistry.remove process_id, routing_id, id