Better support of array type in RPC.
authorCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 08:03:29 +0000 (16:03 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 08:03:29 +0000 (16:03 +0800)
browser/atom/rpc_server.coffee
renderer/api/lib/remote.coffee

index f931707..c2d2e14 100644 (file)
@@ -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
index 0c61853..fe8b60a 100644 (file)
@@ -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