From 678a4953fa1bbfb545a2aa770fc3937d40391690 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 25 Apr 2013 16:03:29 +0800 Subject: [PATCH] Better support of array type in RPC. --- browser/atom/rpc_server.coffee | 9 ++-- renderer/api/lib/remote.coffee | 78 +++++++++++++++++----------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/browser/atom/rpc_server.coffee b/browser/atom/rpc_server.coffee index f931707933f2..c2d2e14a9a4f 100644 --- a/browser/atom/rpc_server.coffee +++ b/browser/atom/rpc_server.coffee @@ -8,14 +8,17 @@ class PlainObject constructor: (value) -> @type = typeof value @type = 'value' if value is null + @type = 'array' if Array.isArray value - if @type is 'object' or @type is 'function' + if @type is 'array' + @members = [] + @members.push new PlainObject(el) for el in value + else if @type is 'object' or @type is 'function' @name = value.constructor.name @id = objectsRegistry.add value @members = [] - for prop, field of value - @members.push { name: prop, type: typeof field } + @members.push { name: prop, type: typeof field } for prop, field of value else @type = 'value' @value = value diff --git a/renderer/api/lib/remote.coffee b/renderer/api/lib/remote.coffee index 0c6185380f63..fe8b60aa14b2 100644 --- a/renderer/api/lib/remote.coffee +++ b/renderer/api/lib/remote.coffee @@ -1,49 +1,49 @@ ipc = require 'ipc' generateFromPainObject = (plain) -> - if plain.type is 'value' - return plain.value - else if plain.type is 'error' - throw new Error('Remote Error: ' + plain.value) + switch plain.type + when 'error' then throw new Error('Remote Error: ' + plain.value) + when 'value' then plain.value + when 'array' then (generateFromPainObject(el) for el in plain.members) + else + ret = {} + if plain.type is 'function' + # A shadow class to represent the remote function object. + ret = + class RemoteObject + constructor: -> + if @constructor == RemoteObject + # Constructor call. + obj = ipc.sendChannelSync 'ATOM_INTERNAL_CONSTRUCTOR', plain.id, Array::slice.call(arguments) - ret = {} - if plain.type is 'function' - # A shadow class to represent the remote function object. - ret = - class RemoteObject - constructor: -> - if @constructor == RemoteObject - # Constructor call. - obj = ipc.sendChannelSync 'ATOM_INTERNAL_CONSTRUCTOR', plain.id, Array::slice.call(arguments) + # Returning object in constructor will replace constructed object + # with the returned object. + # http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this + return generateFromPainObject obj + else + # Function call. + ret = ipc.sendChannelSync 'ATOM_INTERNAL_FUNCTION_CALL', plain.id, Array::slice.call(arguments) + return generateFromPainObject ret - # Returning object in constructor will replace constructed object - # with the returned object. - # http://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this - return generateFromPainObject obj - else - # Function call. - ret = ipc.sendChannelSync 'ATOM_INTERNAL_FUNCTION_CALL', plain.id, Array::slice.call(arguments) - return generateFromPainObject ret + # Polulate delegate members. + for member in plain.members + do (member) -> + if member.type is 'function' + ret[member.name] = -> + # Call member function. + ret = ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_CALL', plain.id, member.name, Array::slice.call(arguments) + generateFromPainObject ret + else + ret.__defineSetter__ member.name, (value) -> + # Set member data. + ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_SET', plain.id, member.name, value - # Polulate delegate members. - for member in plain.members - do (member) -> - if member.type is 'function' - ret[member.name] = -> - # Call member function. - ret = ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_CALL', plain.id, member.name, Array::slice.call(arguments) - generateFromPainObject ret - else - ret.__defineSetter__ member.name, (value) -> - # Set member data. - ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_SET', plain.id, member.name, value + ret.__defineGetter__ member.name, -> + # Get member data. + ret = ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_GET', plain.id, member.name + generateFromPainObject ret - ret.__defineGetter__ member.name, -> - # Get member data. - ret = ipc.sendChannelSync 'ATOM_INTERNAL_MEMBER_GET', plain.id, member.name - generateFromPainObject ret - - ret + ret exports.require = (module) -> plain = ipc.sendChannelSync 'ATOM_INTERNAL_REQUIRE', module