Add remote.getObject API to get object in browser by it's ID.

This commit is contained in:
Cheng Zhao 2013-04-26 22:25:30 +08:00
parent d4d1230107
commit cc921fed1e
4 changed files with 38 additions and 16 deletions

View file

@ -30,12 +30,6 @@ EventEmitter::EventEmitter(v8::Handle<v8::Object> wrapper) {
} }
EventEmitter::~EventEmitter() { EventEmitter::~EventEmitter() {
// process.emit('ATOM_BROWSER_INTERNAL_DELETE', this).
v8::Handle<v8::Value> args[] = {
v8::String::New("ATOM_BROWSER_INTERNAL_DELETE"),
handle_,
};
node::MakeCallback(node::process, "emit", 2, args);
} }
bool EventEmitter::Emit(const std::string& name, base::ListValue* args) { bool EventEmitter::Emit(const std::string& name, base::ListValue* args) {

View file

@ -8,13 +8,27 @@ getStoreForRenderView = (process_id, routing_id) ->
globalStore[key] = {} unless globalStore[key]? globalStore[key] = {} unless globalStore[key]?
globalStore[key] globalStore[key]
exports.add = (process_id, routing_id, obj) -> process.on 'ATOM_BROWSER_INTERNAL_NEW', (obj) ->
# For objects created in browser scripts, keep a weak reference here.
id = globalMap.add obj id = globalMap.add obj
obj.id = id
exports.add = (process_id, routing_id, obj) ->
# Some native types may already been added to globalMap, in that case we
# don't add it twice.
id = obj.id ? globalMap.add obj
store = getStoreForRenderView process_id, routing_id store = getStoreForRenderView process_id, routing_id
# It's possible that a render view may want to get the same remote object
# twice, since we only allow one reference of one object per render view,
# we throw when the object is already referenced.
throw new Error("Object #{id} is already referenced") if store[id]?
store[id] = obj store[id] = obj
id id
exports.get = (process_id, routing_id, id) -> exports.get = (id) ->
globalMap.get id globalMap.get id
exports.remove = (process_id, routing_id, id) -> exports.remove = (process_id, routing_id, id) ->

View file

@ -14,7 +14,6 @@ class PlainObject
else if @type is 'object' or @type is 'function' else if @type is 'object' or @type is 'function'
@name = value.constructor.name @name = value.constructor.name
@id = objectsRegistry.add process_id, routing_id, value @id = objectsRegistry.add process_id, routing_id, value
value.id = @id
@members = [] @members = []
@members.push { name: prop, type: typeof field } for prop, field of value @members.push { name: prop, type: typeof field } for prop, field of value
@ -23,11 +22,14 @@ class PlainObject
@value = value @value = value
ipc.on 'ATOM_INTERNAL_REQUIRE', (event, process_id, routing_id, module) -> ipc.on 'ATOM_INTERNAL_REQUIRE', (event, process_id, routing_id, module) ->
event.result = new PlainObject(process_id, routing_id, require(module)) try
event.result = new PlainObject(process_id, routing_id, require(module))
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_CONSTRUCTOR', (event, process_id, routing_id, id, args) -> ipc.on 'ATOM_INTERNAL_CONSTRUCTOR', (event, process_id, routing_id, id, args) ->
try try
constructor = objectsRegistry.get process_id, routing_id, id constructor = objectsRegistry.get id
# Call new with array of arguments. # Call new with array of arguments.
# http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible # http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
obj = new (Function::bind.apply(constructor, [null].concat(args))) obj = new (Function::bind.apply(constructor, [null].concat(args)))
@ -37,7 +39,7 @@ ipc.on 'ATOM_INTERNAL_CONSTRUCTOR', (event, process_id, routing_id, id, args) ->
ipc.on 'ATOM_INTERNAL_FUNCTION_CALL', (event, process_id, routing_id, id, args) -> ipc.on 'ATOM_INTERNAL_FUNCTION_CALL', (event, process_id, routing_id, id, args) ->
try try
func = objectsRegistry.get process_id, routing_id, id func = objectsRegistry.get id
ret = func.apply global, args ret = func.apply global, args
event.result = new PlainObject(process_id, routing_id, ret) event.result = new PlainObject(process_id, routing_id, ret)
catch e catch e
@ -45,7 +47,7 @@ ipc.on 'ATOM_INTERNAL_FUNCTION_CALL', (event, process_id, routing_id, id, args)
ipc.on 'ATOM_INTERNAL_MEMBER_CALL', (event, process_id, routing_id, id, method, args) -> ipc.on 'ATOM_INTERNAL_MEMBER_CALL', (event, process_id, routing_id, id, method, args) ->
try try
obj = objectsRegistry.get process_id, routing_id, id obj = objectsRegistry.get id
ret = obj[method].apply(obj, args) ret = obj[method].apply(obj, args)
event.result = new PlainObject(process_id, routing_id, ret) event.result = new PlainObject(process_id, routing_id, ret)
catch e catch e
@ -53,17 +55,24 @@ ipc.on 'ATOM_INTERNAL_MEMBER_CALL', (event, process_id, routing_id, id, method,
ipc.on 'ATOM_INTERNAL_MEMBER_SET', (event, process_id, routing_id, id, name, value) -> ipc.on 'ATOM_INTERNAL_MEMBER_SET', (event, process_id, routing_id, id, name, value) ->
try try
obj = objectsRegistry.get process_id, routing_id, id obj = objectsRegistry.get id
obj[name] = value obj[name] = value
catch e catch e
event.result = type: 'error', value: e.message event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_MEMBER_GET', (event, process_id, routing_id, id, name) -> ipc.on 'ATOM_INTERNAL_MEMBER_GET', (event, process_id, routing_id, id, name) ->
try try
obj = objectsRegistry.get process_id, routing_id, id obj = objectsRegistry.get id
event.result = new PlainObject(process_id, routing_id, obj[name]) event.result = new PlainObject(process_id, routing_id, obj[name])
catch e catch e
event.result = type: 'error', value: e.message event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_GET_OBJECT', (event, process_id, routing_id, id) ->
try
obj = objectsRegistry.get id
event.result = new PlainObject(process_id, routing_id, obj)
catch e
event.result = type: 'error', value: e.message
ipc.on 'ATOM_INTERNAL_DESTROY', (process_id, routing_id, id) -> ipc.on 'ATOM_INTERNAL_DESTROY', (process_id, routing_id, id) ->
objectsRegistry.remove process_id, routing_id, id objectsRegistry.remove process_id, routing_id, id

View file

@ -3,7 +3,7 @@ v8_util = process.atom_binding 'v8_util'
generateFromPainObject = (plain) -> generateFromPainObject = (plain) ->
switch plain.type switch plain.type
when 'error' then throw new Error('Remote Error: ' + plain.value) when 'error' then throw new Error(plain.value)
when 'value' then plain.value when 'value' then plain.value
when 'array' then (generateFromPainObject(el) for el in plain.members) when 'array' then (generateFromPainObject(el) for el in plain.members)
else else
@ -56,3 +56,8 @@ generateFromPainObject = (plain) ->
exports.require = (module) -> exports.require = (module) ->
plain = ipc.sendChannelSync 'ATOM_INTERNAL_REQUIRE', module plain = ipc.sendChannelSync 'ATOM_INTERNAL_REQUIRE', module
generateFromPainObject plain generateFromPainObject plain
# Get object with specified id.
exports.getObject = (id) ->
plain = ipc.sendChannelSync 'ATOM_INTERNAL_GET_OBJECT', id
generateFromPainObject plain