| OLD | NEW |
| 1 JavaScript Mojo Example Applications | 1 # Running Mojo Applications |
| 2 ===================== | |
| 3 | |
| 4 hello.js, world.js - A minimal application that connects to another. | |
| 5 | |
| 6 wget.js - Uses the network service to load a URL. | |
| 7 | |
| 8 cube.js - A JS version of examples/sample_app. | |
| 9 | |
| 10 --- Running Mojo Applications --- | |
| 11 | 2 |
| 12 A Mojo application written in JavaScript is launched with mojo_shell like this: | 3 A Mojo application written in JavaScript is launched with mojo_shell like this: |
| 13 | 4 |
| 14 mojo_shell <js-application-url> | 5 ``` |
| 6 mojo_shell <js-application-url> |
| 7 ``` |
| 15 | 8 |
| 16 Where js-application-url is a URL understood by the shell. For example | 9 Where js-application-url is a URL understood by the shell. For example |
| 17 a file or an http URL that names a JS source file. The JS file itself | 10 a file or an http URL that names a JS source file. The JS file itself |
| 18 must begin with a Mojo "shebang" that specifies the Mojo URL of the JS | 11 must begin with a Mojo "shebang" that specifies the Mojo URL of the JS |
| 19 content handler. In other words, the first line of the JS source file | 12 content handler. In other words, the first line of the JS source file |
| 20 must be: | 13 must be: |
| 21 | 14 |
| 22 #!mojo:js_content_handler | 15 ```javascript |
| 16 #!mojo:js_content_handler |
| 17 ``` |
| 23 | 18 |
| 24 Following the shebang should be a single AMD module called "main" whose value | 19 Following the shebang should be a single AMD module called "main" whose value |
| 25 is an Application subclass. The JS content handler will create an instance of | 20 is an Application subclass. The JS content handler will create an instance of |
| 26 the Application and make it the client of the Mojo shell. The JS content handler | 21 the Application and make it the client of the Mojo shell. The JS content handler |
| 27 is itself a Mojo application and it's responsible for creating an instance of V8 | 22 is itself a Mojo application and it's responsible for creating an instance of V8 |
| 28 and loading the "main" JS module and all of the modules the main module | 23 and loading the "main" JS module and all of the modules the main module |
| 29 depends on. | 24 depends on. |
| 30 | 25 |
| 26 ## JavaScript Classes |
| 27 |
| 28 The JS content handler depends on the ECMAScript6 ("Harmony") classes feature. |
| 29 |
| 30 As of January 2015 Chrome enables Harmony classes by default. |
| 31 |
| 32 |
| 33 # The JS Application Class |
| 34 |
| 35 Mojo JS applications are defined with the Application class. The |
| 36 Application class handles incoming requests for services and provides |
| 37 services of its own. |
| 38 |
| 31 This is the overall structure of a JS Mojo application: | 39 This is the overall structure of a JS Mojo application: |
| 32 | 40 |
| 33 ```javascript | 41 ```javascript |
| 34 #!mojo:js_content_handler | 42 #!mojo:js_content_handler |
| 35 | 43 |
| 36 define("main", ["mojo/services/public/js/application", | 44 define("main", ["mojo/services/public/js/application", |
| 37 <list of other modules that this application depends on> | 45 <list of other modules that this application depends on> |
| 38 ], | 46 ], |
| 39 function(appModule, <one parameter per dependent module>) { | 47 function(application, <one parameter per dependent module>) { |
| 40 class MyApplication extends appModule.Application { | 48 class MyApplication extends application.Application { |
| 41 constructor(appShell, url) { | 49 constructor(appShell, url) { |
| 42 super(appShell, url); // Initializes this.shell, this.url. | 50 super(appShell, url); // Initializes this.shell, this.url. |
| 43 // MyApplication initializations here. | 51 // MyApplication initializations here. |
| 44 } | 52 } |
| 45 | 53 |
| 46 initialize(args) { | 54 initialize(args) { |
| 47 } | 55 } |
| 48 | 56 |
| 49 acceptConnection(url, serviceProvider) { | 57 acceptConnection(url, serviceProvider) { |
| 58 } |
| 50 } | 59 } |
| 51 } | 60 } |
| 52 | 61 |
| 53 return MyApplication; | 62 return MyApplication; |
| 54 }); | 63 }); |
| 55 ``` | 64 ``` |
| 56 | 65 |
| 57 The hello.js example is little more than this basic skeleton. | 66 The hello.js example is little more than this basic skeleton. |
| 58 | 67 |
| 59 The JS content handler loads the "main" module and makes an instance of its | 68 The JS content handler loads the "main" module and constructs an |
| 60 value, which must be an Application subclass. The application's constructor is | 69 instance of its value, which must be an Application subclass. The |
| 61 passed two arguments: | 70 application's constructor is passed two arguments: |
| 62 | 71 |
| 63 appShell - a pointer to the Mojo shell. Typically this will be wrapped by a | 72 * `appShell` - a pointer to the Mojo shell. Typically this will be wrapped by a |
| 64 Shell object, see below. | 73 JS Shell object, see below. |
| 65 | 74 |
| 66 url - the URL this application was loaded from as a String. | 75 * `url` - the URL this application was loaded from as a String. |
| 67 | 76 |
| 68 The (inherited) Application class constructor initializes the shell and url | 77 The inherited Application class constructor initializes the shell and url |
| 69 properties. It's unlikely that you'll want to use the appShell argument | 78 properties. It's unlikely that you'll want to use the appShell argument |
| 70 directly. | 79 directly. |
| 71 | 80 |
| 72 The initialize() and acceptConnection() methods are defined by application.mojom | 81 The initialize() and acceptConnection() methods are defined by application.mojom |
| 73 and they're needed because the JS content handler makes the JS application the | 82 and they're needed because the JS content handler makes the JS application the |
| 74 Mojo shell's client. | 83 Mojo shell's client. |
| 75 | 84 |
| 85 The intiailize() method is called once, after the constructor has run |
| 86 and before any calls to acceptConnection(). The value of its parameter |
| 87 is argument list specified for this application with |
| 88 mojo_shell. Arguments can be specified using the mojo_shell |
| 89 `--args-for` command line argument or by just adding them after the |
| 90 application's URL and enclosing the entire expression in quotes. |
| 76 | 91 |
| 77 --- JavaScript Classes --- | 92 ``` |
| 93 mojo_shell '<js-application-url> arg1 arg2' |
| 94 ``` |
| 95 See the wget.js for an example of command-line argument use. |
| 78 | 96 |
| 79 The JS content handler depends on the ECMAScript6 ("Harmony") classes feature. | 97 The acceptConnection() method is called each time another application connects |
| 98 to this one. The first call corresponds the mojo_shell's initial connection. |
| 99 The serviceProvider parameter is a JS ServiceProvider, see the "Requesting |
| 100 and Providing Services" section below. |
| 80 | 101 |
| 102 ## JS Bindings |
| 81 | 103 |
| 104 To use or implement a service you'll need the JS "bindings" for the |
| 105 Mojo interface. The bindings are generated by the build system and end |
| 106 up in files whose name is the same as the '.mojom' file with a '.js' |
| 107 suffix. It's often helpful to look at the generated '.mojom.js' files. |
| 82 | 108 |
| 83 --- Mojo Application Structure --- | |
| 84 | |
| 85 Mojo applications can connect to services provided by other applications and | |
| 86 they can provide services of their own. A service is an implementation of a Mojo | |
| 87 interface that was defined as part of a Mojo module in a ".mojom" file. | |
| 88 | |
| 89 To implement a service you'll need the JS "bindings" for the Mojo interface. The | |
| 90 bindings are generated by the build system and end up in files whose name is the | |
| 91 same as the '.mojom' file with a '.js' suffix. It's often helpful to look at the | |
| 92 generated 'mojom.js' files. | |
| 93 | |
| 94 The JS Shell class simplifies connecting to applications and services. It's a | |
| 95 wrapper for the Application's appShell argument. The Application constructor | |
| 96 creates a Shell and assigns it to |this.shell|. | |
| 97 | |
| 98 The Shell's connectToService() method returns a "proxy" to a service provided by | |
| 99 another application. | |
| 100 | 109 |
| 101 The JS bindings for a Mojo interface's API are delivered as a JS module whose | 110 The JS bindings for a Mojo interface's API are delivered as a JS module whose |
| 102 name is based on the '.mojom' file's path. For example, to use the Mojo network | 111 name is based on the '.mojom' file's path. For example, to use the Mojo network |
| 103 service you need the JS module based on network_service.mojom: | 112 service you need the JS module based on network_service.mojom: |
| 104 | 113 |
| 105 ```javascript | 114 ```javascript |
| 106 define("main", [ | 115 define("main", [ |
| 107 "mojo/services/network/public/interfaces/network_service.mojom", | 116 "mojo/services/network/public/interfaces/network_service.mojom", |
| 108 "mojo/services/public/js/application", | 117 "mojo/services/public/js/application", |
| 109 ] | 118 ] |
| 110 function(netModule, appModule) { | 119 function(net, application) { |
| 111 class MyApplication extends appModule.Application { | 120 class MyApplication extends application.Application { |
| 112 initialize(args) { | 121 initialize(args) { |
| 113 var netService = this.shell.connectToService( | 122 var netService = this.shell.connectToService( |
| 114 "mojo:network_service", netModule.NetworkService); | 123 "mojo:network_service", net.NetworkService); |
| 115 // Use netService's NetworkService methods. | 124 // Use netService's NetworkService methods. |
| 125 } |
| 126 ... |
| 116 } | 127 } |
| 117 ... | 128 ... |
| 118 } | 129 } |
| 119 | |
| 120 return MyApplication; | 130 return MyApplication; |
| 121 }); | 131 }); |
| 122 ``` | 132 ``` |
| 123 | 133 |
| 124 The first connectToService() parameter is the Mojo URL for the network service | 134 The first connectToService() parameter is the Mojo URL for the network service |
| 125 application and the second is the JS "interface" object for NetworkService. The | 135 application and the second is the JS "interface" object for NetworkService. The |
| 126 JS interface object's properties identify the (generated) JS bindings classes | 136 JS interface object's properties identify the generated JS bindings classes |
| 127 used to provide or connect to a service. For example (from | 137 used to provide or connect to a service. For example (from |
| 128 network_service.mojom.js): | 138 network_service.mojom.js): |
| 129 | 139 |
| 130 ```javascript | 140 ```javascript |
| 131 var NetworkService = { | 141 var NetworkService = { |
| 132 name: 'mojo::NetworkService', // Fully qualified Mojo interface name. | 142 name: 'mojo::NetworkService', // Fully qualified Mojo interface name. |
| 133 proxyClass: NetworkServiceProxy, | 143 proxyClass: NetworkServiceProxy, |
| 134 stubClass: NetworkServiceStub, | 144 stubClass: NetworkServiceStub, |
| 135 // ... | 145 // ... |
| 136 }; | 146 }; |
| 137 ``` | 147 ``` |
| 138 | 148 |
| 139 The 'proxyClass' is used to access another application's NetworkService and the | 149 The 'proxyClass' is used to access another application's NetworkService and the |
| 140 'stubClass' is used to create an implementation of NetworkService. | 150 'stubClass' is used to create an implementation of NetworkService. |
| 141 | 151 |
| 152 ## The JS Shell Class |
| 153 |
| 154 The JS Shell class simplifies connecting to applications and services. It's a |
| 155 wrapper for the Application's appShell argument. The Application constructor |
| 156 creates a Shell and assigns it to `this.shell`. |
| 157 |
| 158 The Shell's connectToService() method returns a "proxy" to a service provided by |
| 159 another application. |
| 160 |
| 142 In the netService case above the Shell connects to the Mojo application at | 161 In the netService case above the Shell connects to the Mojo application at |
| 143 "mojo:network_service", then connects to its service called | 162 "mojo:network_service", then connects to its service called |
| 144 'NetworkService.name' with an instance of 'NetworkService.proxyClass'. The proxy | 163 NetworkService.name with an instance of NetworkService.proxyClass. The proxy |
| 145 instance is returned. The netService proxy can be used immediately. | 164 instance is returned. The netService proxy can be used immediately. |
| 146 | 165 |
| 147 | 166 |
| 148 --- Mojo Responses are Promises --- | 167 ## Mojo Responses are Promises |
| 149 | 168 |
| 150 Mojo functions can return zero or more values called a "response". For example | 169 Mojo functions can return zero or more values called a "response". For example |
| 151 the EchoString function below returns a string or null. | 170 the EchoString function below returns a string or null. |
| 152 | 171 |
| 153 ```javascript | 172 ```javascript |
| 154 interface EchoService { | 173 interface EchoService { |
| 155 EchoString(string? value) => (string? value); | 174 EchoString(string? value) => (string? value); |
| 156 }; | 175 }; |
| 157 ``` | 176 ``` |
| 158 | 177 |
| 159 The response is delivered to the function caller asynchronously. In C++ the | 178 The response is delivered to the function caller asynchronously. In C++ the |
| 160 caller provides a Callback object whose Run() method has one argument for | 179 caller provides a Callback object whose Run() method has one argument for |
| 161 each response parameter. In JS, Mojo functions that specify a response return | 180 each response parameter. In JS, Mojo functions that specify a response return |
| 162 a Promise object. The Promise resolves to an object with one property per | 181 a Promise object. The Promise resolves to an object with one property per |
| 163 response parameter. In the EchoString case that would be something like | 182 response parameter. In the EchoString case that would be something like |
| 164 {value: "foo"}. | 183 `{value: "foo"}`. |
| 165 | 184 |
| 166 Similarly, the implementation of a Mojo interface functions that specify a | 185 Similarly, the implementation of a Mojo interface functions that specify a |
| 167 response, must return a Promise. The implementation of EchoString() could | 186 response, must return a Promise. The implementation of EchoString() could |
| 168 be written like this: | 187 be written like this: |
| 169 | 188 |
| 170 ```javascript | 189 ```javascript |
| 171 MyEchoStringImpl.prototype.EchoString = function(s) { | 190 MyEchoStringImpl.prototype.EchoString = function(s) { |
| 172 return Promise.resolve({value: s}); | 191 return Promise.resolve({value: s}); |
| 173 }; | 192 }; |
| 174 ``` | 193 ``` |
| 175 | 194 |
| 176 - Applications can request and provide services | 195 ## Requesting and Providing Services |
| 196 |
| 197 Mojo applications can connect to services provided by other applications and |
| 198 they can provide services of their own. A service is an implementation of a Mojo |
| 199 interface that was defined as part of a Mojo module in a ".mojom" file. |
| 177 | 200 |
| 178 When an application starts, its initialize() method runs and then its | 201 When an application starts, its initialize() method runs and then its |
| 179 acceptConnection() method runs. The acceptConnection() method | 202 acceptConnection() method runs. The acceptConnection() method |
| 180 indicates that another application has connected to this one and it | 203 indicates that another application has connected to this one and it |
| 181 always runs at least once. | 204 always runs at least once. |
| 182 | 205 |
| 183 ```javascript | 206 ```javascript |
| 184 acceptConnection(initiatorURL, serviceProvider) { | 207 acceptConnection(initiatorURL, serviceProvider) { |
| 185 // provide services to the initiator here | 208 // provide services to the initiator here |
| 186 // request services from the initiator here | 209 // request services from the initiator here |
| (...skipping 30 matching lines...) Expand all Loading... |
| 217 | 240 |
| 218 The usage examples that follow are based on the following trivial Mojo | 241 The usage examples that follow are based on the following trivial Mojo |
| 219 interface: | 242 interface: |
| 220 | 243 |
| 221 ```javascript | 244 ```javascript |
| 222 interface EchoService { | 245 interface EchoService { |
| 223 EchoString(string? value) => (string? value); | 246 EchoString(string? value) => (string? value); |
| 224 }; | 247 }; |
| 225 ``` | 248 ``` |
| 226 | 249 |
| 227 -- Requesting a service using the Application's Shell | 250 ### Requesting a Service Using the Application's Shell |
| 228 | 251 |
| 229 Given the URL of a Mojo application that implements the EchoService we | 252 Given the URL of a Mojo application that implements the EchoService we |
| 230 can use the application's shell to get an EchoService proxy. Here's a | 253 can use the application's shell to get an EchoService proxy. Here's a |
| 231 complete application: | 254 complete application: |
| 232 | 255 |
| 233 ```javascript | 256 ```javascript |
| 234 #!mojo:js_content_handler | 257 #!mojo:js_content_handler |
| 235 | 258 |
| 236 define("main", [ | 259 define("main", [ |
| 237 "console", | 260 "console", |
| 238 "mojo/services/public/js/application", | 261 "mojo/services/public/js/application", |
| 239 "services/js/test/echo_service.mojom" | 262 "services/js/test/echo_service.mojom" |
| 240 ], function(console, appModule, echoModule) { | 263 ], function(console, appModule, echoModule) { |
| 241 | 264 |
| 242 class EchoShellRequest extends appModule.Application { | 265 class EchoShellRequest extends appModule.Application { |
| 243 initialize(args) { | 266 initialize(args) { |
| 244 var url = "file:/foo/bar/echo.js"; | 267 var url = "file:/foo/bar/echo.js"; |
| 245 var echoService = this.shell.connectToService(url, echoModule.EchoService)
; | 268 var echoService = this.shell.connectToService(url, echoModule.EchoService)
; |
| 246 echoService.echoString("foo").then(function(result) { | 269 echoService.echoString("foo").then(function(result) { |
| 247 console.log("echoString(foo) => " + result.value); | 270 console.log("echoString(foo) => " + result.value); |
| 248 }); | 271 }); |
| 249 } | 272 } |
| 250 } | 273 } |
| 251 return EchoShellRequest; | 274 return EchoShellRequest; |
| 252 }); | 275 }); |
| 253 ``` | 276 ``` |
| 254 | 277 |
| 255 | 278 |
| 256 -- Providing a service | 279 ### Providing a Service |
| 257 | 280 |
| 258 A complete application that unconditionally provides the EchoService | 281 A complete application that unconditionally provides the EchoService |
| 259 looks like this: | 282 looks like this: |
| 260 | 283 |
| 261 ```javascript | 284 ```javascript |
| 262 #!mojo:js_content_handler | 285 #!mojo:js_content_handler |
| 263 | 286 |
| 264 define("main", [ | 287 define("main", [ |
| 265 "mojo/services/public/js/application", | 288 "mojo/services/public/js/application", |
| 266 "services/js/test/echo_service.mojom" | 289 "services/js/test/echo_service.mojom" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 285 interface. If the EchoService defined a client interface, the factory | 308 interface. If the EchoService defined a client interface, the factory |
| 286 function's client parameter would be a proxy for the initiator's | 309 function's client parameter would be a proxy for the initiator's |
| 287 client service. EchoService doesn't have a client so we could have | 310 client service. EchoService doesn't have a client so we could have |
| 288 omitted this parameter. | 311 omitted this parameter. |
| 289 | 312 |
| 290 Each time another application connects to this one, the EchoServiceImpl | 313 Each time another application connects to this one, the EchoServiceImpl |
| 291 function will be called. The caller will be able to run the | 314 function will be called. The caller will be able to run the |
| 292 echoString() method and will get its response via a Promise. | 315 echoString() method and will get its response via a Promise. |
| 293 | 316 |
| 294 | 317 |
| 295 -- Final note | 318 ## Final note |
| 296 | 319 |
| 297 An initiator's serviceProvider object can be retained and used to | 320 An initiator's serviceProvider object can be retained and used to |
| 298 request or provide services at any time, not just from within | 321 request or provide services at any time, not just from within |
| 299 application's acceptConnection() method. | 322 application's acceptConnection() method. |
| 300 | 323 |
| 301 | 324 |
| 302 --- Interface Parameters --- | 325 # Interface Parameters |
| 303 | 326 |
| 304 The caller and callee use cases that follow are in terms of the following mojom
: | 327 The caller and callee use cases that follow are in terms of the following mojom
: |
| 305 | 328 |
| 306 ``` | 329 ``` |
| 307 [Client=Bar] | 330 [Client=Bar] |
| 308 interface Foo { | 331 interface Foo { |
| 309 } | 332 } |
| 310 | 333 |
| 311 [Client=Foo] // Redundant but always implicitly true. | 334 [Client=Foo] // Redundant but always implicitly true. |
| 312 interface Bar { | 335 interface Bar { |
| 313 } | 336 } |
| 314 | 337 |
| 315 interface I { | 338 interface I { |
| 316 provideFoo(Foo foo); | 339 provideFoo(Foo foo); |
| 317 requestFoo(Foo& foo); // effectively: provideFoo(Bar bar) | 340 requestFoo(Foo& foo); // effectively: provideFoo(Bar bar) |
| 318 } | 341 } |
| 319 ``` | 342 ``` |
| 320 | 343 |
| 321 -- In General | 344 ## Stubs and Proxies |
| 345 |
| 346 TODO: briefly introduce message pipes. |
| 347 TODO: explain what stubs and proxies are, explain what's meant by "local" and "r
emote". |
| 348 TODO: explain the StubBindings and ProxyBindings functions. |
| 349 TODO: support creating a proxy from a handle new MyProxy(someHandle); |
| 350 TODO: explain the Connection object and how it relates to this stuff. |
| 322 | 351 |
| 323 From a user's point of view, the bindings are in terms of the (remote) | 352 From a user's point of view, the bindings are in terms of the (remote) |
| 324 proxy class and the (local) stub class's implementation delegate | 353 proxy class and the (local) stub class. Properties are added to instances |
| 325 (internally, that's the stub class's delegate$ property). The | 354 of these classes using functions called StubBindings and ProxyBindings. |
| 326 bindings will add/use a local$ property on proxy objects which points | |
| 327 to the stub class's implementation delegate. They also manage remote$ | |
| 328 property on the implementation delegate whose value is the proxy. | |
| 329 | |
| 330 All that implies: | |
| 331 | |
| 332 fooImpl.remote$.local$ == fooImpl (the stub class's delegate) | |
| 333 fooProxy.local$.remote$ == fooProxy | |
| 334 | 355 |
| 335 | 356 |
| 336 -- Callers | 357 |
| 358 ## Callers |
| 337 | 359 |
| 338 Assuming that we have a proxy for interface I, iProxy. | 360 Assuming that we have a proxy for interface I, iProxy. |
| 339 | 361 |
| 340 An iProxy.provideFoo() call implies that we have an implementation of | 362 An iProxy.provideFoo() call implies that we have an implementation of |
| 341 Foo, and want a proxy for Bar (Foo's client). | 363 Foo, and want a proxy for Bar (Foo's client). |
| 342 | 364 |
| 343 ```javascript | 365 ```javascript |
| 344 var myFooImpl; | 366 var barProxy; |
| 345 provideFoo(myFooImpl); | 367 iProxy.provideFoo(function(remote) { |
| 346 myFooImpl.remote$; // A Bar proxy initialized by provideFoo(), undefined if Foo
has no client. | 368 barProxy = remote; |
| 369 return myFooImpl; |
| 370 }); |
| 347 ``` | 371 ``` |
| 348 | 372 |
| 349 An iProxy.requestFoo() call implies that we have an implementation of | 373 An iProxy.requestFoo() call implies that we have an implementation of |
| 350 Bar and want a proxy for Foo (Bar's client). | 374 Bar and want a proxy for Foo (Bar's client). |
| 351 | 375 |
| 352 ```javascript | 376 ```javascript |
| 353 var myBarImpl; // If Foo has no client then this is just {}. | 377 var fooProxy; |
| 354 requestFoo(myBarImpl); | 378 iProxy.requestFoo(function(remote) { |
| 355 myBarImpl.remote$; // A Foo proxy initialized by requestFoo. | 379 fooProxy = remote; |
| 380 return myBarImpl; |
| 381 }); |
| 356 ``` | 382 ``` |
| 357 | 383 |
| 384 In the requestFoo() case, if no client were defined for Bar the function |
| 385 parameter need not return anything. |
| 386 |
| 358 The wget.js example includes a request for the URLLoader service. | 387 The wget.js example includes a request for the URLLoader service. |
| 359 | 388 |
| 360 -- Callees | 389 ## Callees |
| 361 | 390 |
| 362 An implementation of provideFoo(Foo foo) implies that we have an | 391 An implementation of provideFoo(Foo foo) implies that we have an |
| 363 implementation of Bar (Foo's client) and want a proxy to the Foo | 392 implementation of Bar (Foo's client) and want a proxy to the Foo |
| 364 that has been passed to us. | 393 that has been passed to us. |
| 365 | 394 |
| 366 ```javascript | 395 ```javascript |
| 367 void provideFoo(fooProxy) { | 396 void provideFoo(fooProxy) { |
| 368 fooProxy.local$ = myBarImpl; // sets myFooImpl.remote$ = fooProxy | 397 ProxyBindings(fooProxy).setLocalDelegate(myMyBarImpl); |
| 369 } | 398 } |
| 370 ``` | 399 ``` |
| 371 | 400 |
| 372 An implementation of requestFoo(Foo& foo) implies that we have an | 401 An implementation of requestFoo(Foo& foo) implies that we have an |
| 373 implementation of Foo and want a proxy for the Bar (Foo's client) | 402 implementation of Foo and want a proxy for the Bar (Foo's client) |
| 374 that's been passed to us. | 403 that's been passed to us. |
| 375 | 404 |
| 376 ```javascript | 405 ```javascript |
| 377 void requestFoo(barProxy) { | 406 void requestFoo(barProxy) { |
| 378 barProxy.local$ = myFooImpl; // sets myFooImpl.remote$ = barProxy | 407 ProxyBindings(barProxy).setLocallocalDelegate(myFooImpl); |
| 379 } | 408 } |
| 380 ``` | 409 ``` |
| 381 | |
| OLD | NEW |