UNPKG

dreemgl

Version:

DreemGL is an open-source multi-screen prototyping framework for mediated environments, with a visual editor and shader styling for webGL and DALi runtimes written in JavaScript. As a toolkit for gpu-accelerated multiscreen development, DreemGL includes

1 lines 15.7 kB
Ext.data.JsonP.components({"guide":"<h1 id='components-section-dreemgl-external-component-authoring-guide'>DreemGL External Component Authoring Guide</h1>\n<div class='toc'>\n<p><strong>Contents</strong></p>\n<ul>\n<li>1. <a href='#!/guide/components-section-simple-web-service-as-a-dreemgl-component'>Simple Web Service as a DreemGL Component</a>\n <ul>\n<li>1.1. <a href='#!/guide/components-section-live-example'>Live Example</a>\n </li>\n<li>1.2. <a href='#!/guide/components-section-live-slides'>Live Slides</a>\n </li>\n</ul></li>\n<li>2. <a href='#!/guide/components-section-setting-up'>Setting Up</a>\n <ul>\n<li>2.1. <a href='#!/guide/components-section-include-readme.md-%26amp%3B-package.json'>Include README.md &amp; package.json</a>\n </li>\n</ul></li>\n<li>3. <a href='#!/guide/components-section-creating-a-new-component'>Creating a New Component</a>\n <ul>\n<li>3.1. <a href='#!/guide/components-section-server-side'>Server Side</a>\n </li>\n<li>3.2. <a href='#!/guide/components-section-screen%2Fclient-side'>Screen/Client Side</a>\n </li>\n</ul></li>\n<li>4. <a href='#!/guide/components-section-including-examples-and-usage'>Including Examples and Usage</a>\n <ul>\n<li>4.1. <a href='#!/guide/components-section-examples'>Examples</a>\n </li>\n<li>4.2. <a href='#!/guide/components-section-usage'>Usage</a>\n </li>\n</ul></li>\n<li>5. <a href='#!/guide/components-section-working-with-screen-%26lt%3B%26mdash%3B%26gt%3B-server-rpc'>Working with screen &lt;&mdash;&gt; server RPC</a>\n <ul>\n<li>5.1. <a href='#!/guide/components-section-attributes'>Attributes</a>\n </li>\n<li>5.2. <a href='#!/guide/components-section-methods'>Methods</a>\n </li>\n</ul></li>\n<li>6. <a href='#!/guide/components-section-using-post-api'>Using POST API</a>\n <ul>\n<li>6.1. <a href='#!/guide/components-section-rpc-id'>RPC ID</a>\n </li>\n<li>6.2. <a href='#!/guide/components-section-attributes'>Attributes</a>\n </li>\n<li>6.3. <a href='#!/guide/components-section-method-calls'>Method Calls</a>\n </li>\n</ul></li>\n</ul></div>\n\n<p>This document describes how to extend DreemGL to communicate with and access IoT devices, web services and other external resources.</p>\n\n<h2 id='components-section-simple-web-service-as-a-dreemgl-component'>Simple Web Service as a DreemGL Component</h2>\n\n<p>The example provided by the guide can be found mounted at <a href=\"/docs/examples/components\">/docs/examples/components</a>.</p>\n\n<p>The guide will walk you through building a simple component that talks to a server-side web service. This component will\nprovide a search object and simple UI for the <a href=\"http://omdbapi.com/\">OMDB</a> database.</p>\n\n<h3 id='components-section-live-example'>Live Example</h3>\n\n<p>If you have the DreemGL server running the example outlined in this document will render below:</p>\n\n<iframe style=\"border:0;width:900px; height:600px\" src=\"/docs/examples/components\"></iframe>\n\n\n<h3 id='components-section-live-slides'>Live Slides</h3>\n\n<p>Additionally, a live slide-show that demonstrates many of the same concepts in this guide can be found <a href=\"/docs/slides/extendingdreem\">/docs/slides/extendingdreem</a></p>\n\n<h2 id='components-section-setting-up'>Setting Up</h2>\n\n<p>Dreem GL components provide additonal functionality for compositions and are implemented in thier own repository and\nthen linked in as sibling directories that live within the DreemGL directory structure. The simplest way to add a\ncomponent to a Dreem GL server is with a symlink into the DreemGL <code>$root</code> directory:</p>\n\n<pre><code>ln -s /path/to/component-directory/ /path/to/dreemgl's-$root/&lt;componentname&gt;\n</code></pre>\n\n<p>Note here that the name you choose for <code>&lt;componentname&gt;</code> is important in that it will be the namespace that other\ncompositions will use to instantiate it's classes later. For example, this guide is in <code>./docs/examples/components</code>,\nso all of it's classes can then be accessed using <code>$docs$guides$components$&lt;classname&gt;</code>,\n<code>$docs$, examples$components$&lt;classname&gt;</code> or <code>$docs$examples$components$, &lt;classname&gt;</code>. Within a component you can\nuse '$$' to search the current directory, so this name is only important in how other components and compositions will\naccess the component's objects.</p>\n\n<h3 id='components-section-include-readme.md-%26amp%3B-package.json'>Include README.md &amp; package.json</h3>\n\n<p>Be sure to include a <code>README.md</code> with instructions for use and a <code>package.json</code> to help manage dependancies:</p>\n\n<pre><code>{\n \"name\": \"&lt;component name&gt;\",\n \"version\": \"0.0.1\",\n \"description\": \"&lt;description&gt;\",\n \"dependencies\": {},\n \"engine\": \"node &gt;= 0.10.0\"\n}\n</code></pre>\n\n<p>If required, be sure to install any dependancies in the component directory:</p>\n\n<pre><code>npm install\n</code></pre>\n\n<h2 id='components-section-creating-a-new-component'>Creating a New Component</h2>\n\n<h3 id='components-section-server-side'>Server Side</h3>\n\n<p>DreemGL components are usually collections of both server objects and UI widgets. If your component has some\nserver-side behavior, include a <code>$server/service</code> object. This example provides a server-side lookups of the\n<a href=\"http://omdbapi.com/\">OMDB</a> database. Here is a simple object that encapsulates a single \"search\" within the\ndatabase (see <code>./docs/examples/components/search.js</code> for more detailed version):</p>\n\n<pre><code>define.class('$server/service', function(require) {\n\n this.attributes = {\n results: Config({type:Array}),\n keyword: Config({type:String})\n };\n\n this.onkeyword = function (keyword) {\n var request = require('request');\n request(\"http://www.omdbapi.com/?s=\" + keyword.replace(/[^a-z0-9_-]/ig, '+'), (function (error, response, body) {\n if (!error &amp;&amp; response.statusCode == 200) {\n this.results = JSON.parse(body)[\"Search\"];\n }\n }).bind(this))\n }\n});\n</code></pre>\n\n<p>The search object has two attributes, the <code>keyword</code> to search term used in the search and the resulting list of movie\nobjects <code>results</code> from the server. Setting the <code>keyword</code> triggers the <code>onkeyword</code> event which fetches the data from the\nsearch API and sets it's own results attribute upon return.</p>\n\n<h3 id='components-section-screen%2Fclient-side'>Screen/Client Side</h3>\n\n<p>Client-side UI views are also an important part of external components, and this example provies a simple view\nto consume the data coming from it's server component (see <code>./docs/examples/components/movie.js</code> for complete code):</p>\n\n<pre><code>define.class('$ui/view', function (label) {\n\n this.attributes = {\n Title: Config({type:String}),\n Year: Config({type:String}),\n Poster: Config({type:String})\n }\n this.onPoster = function (poster) { this.bgimage = poster; };\n\n this.render = function() { return [\n label({ fgcolor:'black', text:this.Title + '[' + this.Year + ']' })\n ]; }\n\n});\n</code></pre>\n\n<p>The server returns blocks of JSON which look like this:</p>\n\n<pre><code>{\"Title\":\"Snow White and the Huntsman\",\n \"Year\":\"2012\",\n \"imdbID\":\"tt1735898\",\n \"Type\":\"movie\",\n \"Poster\":\"...\"}\n</code></pre>\n\n<p>When rendered into a javascript object these blocks can be consumed directly by the <code>movie()</code> object to create\nnew movies views which can be added directly to the heirarchy. An example of how this can be accomplished is provided\nin the next section.</p>\n\n<h2 id='components-section-including-examples-and-usage'>Including Examples and Usage</h2>\n\n<h3 id='components-section-examples'>Examples</h3>\n\n<p>In addition to a <code>REAMDE.md</code> DreemGL components often provide one or more example compositions. Including an <code>index.js</code>\ncomposition with some simple examples and usage information is usually a good practice, as these will immediately be\navailable to anyone browing to your component's root directory.</p>\n\n<p>For this guide one screen gathers user input (see <code>./docs/examples/components/browser.js</code>) and displays the list of\nmovies (as <code>movie</code> objects) returned by the web service:</p>\n\n<pre><code>define.class('$ui/screen', function($ui$, view, button, label, $$, movie) {\n\n this.attributes = {\n term: Config({type:String}),\n movies: Config({type:Array})\n };\n\n this.renderMovies = function() {\n var mviews = [];\n for (var i=0;i&lt;this.movies.length;i++) {\n mviews.push(movie(this.movies[i]));\n }\n return mviews;\n };\n\n this.render = function() { return [\n view(\n {flexdirection:'column'},\n label({ name:'search', text:'Aliens'}),\n button({text:'Search', click:function() {\n this.screen.term = this.parent.search.text;\n }}),\n view(this.renderMovies())\n )\n ] }\n});\n</code></pre>\n\n<p>And finally, the <code>index.js</code> wires all the components together:</p>\n\n<pre><code>define.class('$server/composition', function($$, search, browser) {\n\n this.render = function() { return [\n search({\n name:'omdb',\n keyword:wire('this.rpc.main.term')\n }),\n browser({\n name:'main',\n movies:wire('this.rpc.omdb.results')\n })\n ] }\n});\n</code></pre>\n\n<h3 id='components-section-usage'>Usage</h3>\n\n<p>Individual DreemGL classes can include inline usage examples directly in thier codebase. To add inline examples,\nattach them to <code>this.constructor</code> as an attribute named <code>examples</code>. For example:</p>\n\n<pre><code> var example = this.constructor; \n this.constructor.examples = {\n // Basic Usage\n Usage:function(){\n return [\n example({some:'attributes'})\n ]\n },\n // Some other use case\n Exmaple:function(){\n return [\n example({some:[{other:'example'}]})\n ]\n } \n } \n</code></pre>\n\n<h2 id='components-section-working-with-screen-%26lt%3B%26mdash%3B%26gt%3B-server-rpc'>Working with screen &lt;&mdash;&gt; server RPC</h2>\n\n<p>All communication between the user and the server must go though the RPC bus, availabel via <code>this.rpc</code>. To make\ncalls on the server, use <code>this.rpc.serverObjectName.attributeOrMethodName</code> for server objects\nand <code>this.rpc.screenName.attributeOrMethodName</code> for screen objects.</p>\n\n<h3 id='components-section-attributes'>Attributes</h3>\n\n<p>Attributes can be get and set like so:</p>\n\n<pre><code>this.rpc.object.someAttribute = \"value\"\n\nconsole.log(\"My value is\", this.rpc.object.someAttribute);\n</code></pre>\n\n<h3 id='components-section-methods'>Methods</h3>\n\n<p>All RPC method calls are promises that return with the result of the method, and can be called like so:</p>\n\n<pre><code>this.rpc.server.methodCall().then(function(ret) {\n console.log(\"My value is:\", ret.value);\n})\n</code></pre>\n\n<h1 id='components-section-communicating-with-external-services-and-devices'>Communicating with External Services and Devices</h1>\n\n<p>When you have a physcial device or external service that cannot be integrated directly within the Dreem system itself,\nor if you otherwise need to send data into the system, you can interact directly with Dreem objects using the HTTP\nPOST API methods.</p>\n\n<h2 id='components-section-using-post-api'>Using POST API</h2>\n\n<p>The composition server will respond to HTTP POSTs requests sending JSON data in the following format:</p>\n\n<pre><code>{\n \"rpcid\": \"&lt;see below&gt;\",\n \"type\": \"&lt;attribute|method&gt;\",\n\n //used only if type=attribute\n \"get\":true|false,\n \"attribute\": \"&lt;attribute name&gt;\",\n \"value\": \"&lt;attribute value, if setting&gt;\",\n\n //used only if type=method\n \"method\": \"&lt;method name&gt;\",\n \"args\": [\"&lt;array&gt;\", \"&lt;of&gt;\", \"&lt;arguments&gt;\"]\n}\n</code></pre>\n\n<h3 id='components-section-rpc-id'>RPC ID</h3>\n\n<p>The RPC ID refers to the object that the RPC method will be called on, and is simply the string that would otherwise\ncome after a call to <code>this.rpc</code> in Dreem code, except for the name of the attribute or method name itself. For example,\nthe attribute you would have set in this code <code>this.rpc.mobile.deviceID</code> would have an\nRPC ID of <code>mobile</code>. Likewise, a method called with <code>this.rpc.localapi.register()</code> would have an RPC ID of <code>localapi</code>.</p>\n\n<h3 id='components-section-attributes'>Attributes</h3>\n\n<h4 id='components-section-setter'>Setter</h4>\n\n<p>The JSON structure for a setting an attribute is as follows:</p>\n\n<pre><code>{\n \"rpcid\": \"&lt;see above&gt;\",\n \"type\": \"attribute\",\n\n \"attribute\": \"&lt;attribute name&gt;\",\n \"value\": \"&lt;attribute value&gt;\"\n}\n</code></pre>\n\n<p>An an example, to set the search term variable on the example above, you can use <a href=\"http://curl.haxx.se/\">curl</a> like so:</p>\n\n<pre><code>curl -X POST -d '{\"rpcid\":\"main\", \"type\":\"attribute\", \"attribute\":\"term\", \"value\":\"Snow\"}' http://localhost:2000/docs/examples/components\n</code></pre>\n\n<p>Which will return:</p>\n\n<pre><code>{\"type\":\"return\",\"attribute\":\"term\",\"value\":\"OK\"}\n</code></pre>\n\n<h4 id='components-section-getter'>Getter</h4>\n\n<p>Getting attributes is identical to setting, but without a <code>value</code> property and setting the <code>get</code> property:</p>\n\n<pre><code>{\n \"rpcid\": \"&lt;see above&gt;\",\n \"type\": \"attribute\",\n \"get\": true,\n\n \"attribute\": \"&lt;attribute name&gt;\"\n}\n</code></pre>\n\n<p>Reading the kework attribute off the omdb search object:</p>\n\n<pre><code>curl -X POST -d '{\"rpcid\":\"omdb\", \"type\":\"attribute\", \"attribute\":\"keyword\", \"get\":true}' http://localhost:2000/docs/examples/components\n</code></pre>\n\n<p>If you had set the search term with the previous example, it will now return:</p>\n\n<pre><code>{\"type\":\"return\",\"attribute\":\"keyword\",\"value\":\"Snow\"}\n</code></pre>\n\n<h3 id='components-section-method-calls'>Method Calls</h3>\n\n<p>In additon to setting attributes, methods can be called directly on Dreem objects. The method JSON structure looks\nlike this:</p>\n\n<pre><code>{\n \"rpcid\": \"&lt;see above&gt;\",\n \"type\": \"method\",\n\n \"method\": \"&lt;method name&gt;\",\n \"args\": [\"&lt;array&gt;\", \"&lt;of&gt;\", \"&lt;arguments&gt;\"]\n}\n</code></pre>\n\n<p>This will directly manipulate the <code>onkeyword</code> function of the omdb search object to trigger a</p>\n\n<pre><code>curl -X POST -d '{\"rpcid\":\"omdb\", \"type\":\"method\", \"method\":\"onkeyword\", \"args\":[\"Red\"]}' http://localhost:2000/docs/examples/components\n</code></pre>\n\n<p>The screen will redraw and this the API will return:</p>\n\n<pre><code>{\"type\":\"return\",\"method\":\"onkeyword\"}\n</code></pre>\n\n<h1 id='components-section-examples-of-connected-devices'>Examples of Connected Devices</h1>\n\n<p>See the Hue ambient lights example here: <a href=\"http://localhost:2000/examples/components/hue/README.md\">http://localhost:2000/examples/components/hue/README.md</a></p>\n","title":"DreemGL External Component Authoring Guide"});