netlinx-erb 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -687,7 +687,7 @@ data_event[vdvRPC]
687
687
  </div>
688
688
 
689
689
  <div id="footer">
690
- Generated on Wed Feb 25 14:28:07 2015 by
690
+ Generated on Mon Jun 29 16:09:05 2015 by
691
691
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
692
692
  0.8.7.6 (ruby-2.1.3).
693
693
  </div>
@@ -208,12 +208,12 @@
208
208
  <pre class="lines">
209
209
 
210
210
 
211
- 378
212
- 379
213
- 380</pre>
211
+ 368
212
+ 369
213
+ 370</pre>
214
214
  </td>
215
215
  <td>
216
- <pre class="code"><span class="info file"># File 'lib/netlinx/erb/helpers.rb', line 378</span>
216
+ <pre class="code"><span class="info file"># File 'lib/netlinx/erb/helpers.rb', line 368</span>
217
217
 
218
218
  <span class='kw'>def</span> <span class='id identifier rubyid_remove_comma_after_last_item'>remove_comma_after_last_item</span>
219
219
  <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_gsub'>gsub</span><span class='lparen'>(</span><span class='tstring'><span class='regexp_beg'>/</span><span class='tstring_content'>(?&lt;=\}),(.*?)\z</span><span class='regexp_end'>/</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'> \1</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span>
@@ -283,17 +283,17 @@
283
283
  <pre class="lines">
284
284
 
285
285
 
286
- 390
287
- 391
288
- 392
289
- 393
290
- 394
291
- 395
292
- 396
293
- 397</pre>
286
+ 380
287
+ 381
288
+ 382
289
+ 383
290
+ 384
291
+ 385
292
+ 386
293
+ 387</pre>
294
294
  </td>
295
295
  <td>
296
- <pre class="code"><span class="info file"># File 'lib/netlinx/erb/helpers.rb', line 390</span>
296
+ <pre class="code"><span class="info file"># File 'lib/netlinx/erb/helpers.rb', line 380</span>
297
297
 
298
298
  <span class='kw'>def</span> <span class='id identifier rubyid_to_hiqnet'>to_hiqnet</span> <span class='id identifier rubyid_sv'>sv</span> <span class='op'>=</span> <span class='kw'>nil</span>
299
299
  <span class='id identifier rubyid_sv'>sv</span> <span class='op'>||=</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_end'>&#39;</span></span>
@@ -313,7 +313,7 @@
313
313
  </div>
314
314
 
315
315
  <div id="footer">
316
- Generated on Wed Feb 25 14:28:07 2015 by
316
+ Generated on Mon Jun 29 16:09:05 2015 by
317
317
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
318
318
  0.8.7.6 (ruby-2.1.3).
319
319
  </div>
@@ -195,6 +195,24 @@
195
195
  </ul>
196
196
 
197
197
 
198
+ <ul id="alpha_P" class="alpha">
199
+ <li class="letter">P</li>
200
+ <ul>
201
+
202
+ <li>
203
+ <span class='object_link'><a href="NetLinx/Rake/ERB/Push.html" title="NetLinx::Rake::ERB::Push (class)">Push</a></span>
204
+
205
+ <small>(NetLinx::Rake::ERB)</small>
206
+
207
+ </li>
208
+
209
+ </ul>
210
+ </ul>
211
+
212
+
213
+ </td><td valign='top' width="33%">
214
+
215
+
198
216
  <ul id="alpha_R" class="alpha">
199
217
  <li class="letter">R</li>
200
218
  <ul>
@@ -215,9 +233,6 @@
215
233
  </ul>
216
234
 
217
235
 
218
- </td><td valign='top' width="33%">
219
-
220
-
221
236
  <ul id="alpha_S" class="alpha">
222
237
  <li class="letter">S</li>
223
238
  <ul>
@@ -239,7 +254,7 @@
239
254
  </div>
240
255
 
241
256
  <div id="footer">
242
- Generated on Wed Feb 25 14:28:05 2015 by
257
+ Generated on Mon Jun 29 16:09:01 2015 by
243
258
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
244
259
  0.8.7.6 (ruby-2.1.3).
245
260
  </div>
@@ -50,7 +50,7 @@
50
50
 
51
51
  <ul id="full_list" class="class">
52
52
  <li><span class='object_link'><a href="top-level-namespace.html" title="Top Level Namespace (root)">Top Level Namespace</a></span></li>
53
- <li><span class='object_link'><a href="Array.html" title="Array (class)">Array</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><span class='object_link'><a href="Hash.html" title="Hash (class)">Hash</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx.html" title="NetLinx (module)">NetLinx</a></span><small class='search_info'>Top Level Namespace</small></li><ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/ERB.html" title="NetLinx::ERB (module)">ERB</a></span><small class='search_info'>NetLinx</small></li><ul><li><span class='object_link'><a href="NetLinx/ERB/HashHelpers.html" title="NetLinx::ERB::HashHelpers (module)">HashHelpers</a></span><small class='search_info'>NetLinx::ERB</small></li><li><span class='object_link'><a href="NetLinx/ERB/Helpers.html" title="NetLinx::ERB::Helpers (module)">Helpers</a></span><small class='search_info'>NetLinx::ERB</small></li></ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/Rake.html" title="NetLinx::Rake (module)">Rake</a></span><small class='search_info'>NetLinx</small></li><ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/Rake/ERB.html" title="NetLinx::Rake::ERB (module)">ERB</a></span><small class='search_info'>NetLinx::Rake</small></li><ul><li><span class='object_link'><a href="NetLinx/Rake/ERB/GenerateERB.html" title="NetLinx::Rake::ERB::GenerateERB (class)">GenerateERB</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li><li><span class='object_link'><a href="NetLinx/Rake/ERB/GenerateRPC.html" title="NetLinx::Rake::ERB::GenerateRPC (class)">GenerateRPC</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li><li><span class='object_link'><a href="NetLinx/Rake/ERB/Lines.html" title="NetLinx::Rake::ERB::Lines (class)">Lines</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li></ul></ul></ul><li><span class='object_link'><a href="RPC.html" title="RPC (class)">RPC</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><span class='object_link'><a href="String.html" title="String (class)">String</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li>
53
+ <li><span class='object_link'><a href="Array.html" title="Array (class)">Array</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><span class='object_link'><a href="Hash.html" title="Hash (class)">Hash</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx.html" title="NetLinx (module)">NetLinx</a></span><small class='search_info'>Top Level Namespace</small></li><ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/ERB.html" title="NetLinx::ERB (module)">ERB</a></span><small class='search_info'>NetLinx</small></li><ul><li><span class='object_link'><a href="NetLinx/ERB/HashHelpers.html" title="NetLinx::ERB::HashHelpers (module)">HashHelpers</a></span><small class='search_info'>NetLinx::ERB</small></li><li><span class='object_link'><a href="NetLinx/ERB/Helpers.html" title="NetLinx::ERB::Helpers (module)">Helpers</a></span><small class='search_info'>NetLinx::ERB</small></li></ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/Rake.html" title="NetLinx::Rake (module)">Rake</a></span><small class='search_info'>NetLinx</small></li><ul><li><a class='toggle'></a> <span class='object_link'><a href="NetLinx/Rake/ERB.html" title="NetLinx::Rake::ERB (module)">ERB</a></span><small class='search_info'>NetLinx::Rake</small></li><ul><li><span class='object_link'><a href="NetLinx/Rake/ERB/GenerateERB.html" title="NetLinx::Rake::ERB::GenerateERB (class)">GenerateERB</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li><li><span class='object_link'><a href="NetLinx/Rake/ERB/GenerateRPC.html" title="NetLinx::Rake::ERB::GenerateRPC (class)">GenerateRPC</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li><li><span class='object_link'><a href="NetLinx/Rake/ERB/Lines.html" title="NetLinx::Rake::ERB::Lines (class)">Lines</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li><li><span class='object_link'><a href="NetLinx/Rake/ERB/Push.html" title="NetLinx::Rake::ERB::Push (class)">Push</a></span> &lt; TaskLib<small class='search_info'>NetLinx::Rake::ERB</small></li></ul></ul></ul><li><span class='object_link'><a href="RPC.html" title="RPC (class)">RPC</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li><li><span class='object_link'><a href="String.html" title="String (class)">String</a></span> &lt; Object<small class='search_info'>Top Level Namespace</small></li>
54
54
 
55
55
  </ul>
56
56
  </div>
@@ -66,15 +66,17 @@
66
66
 
67
67
  <p>netlinx-erb</p>
68
68
 
69
- <p>A code generation utility for AMX NetLinx control systems.</p>
69
+ <p>A code generation framework for AMX NetLinx control systems.</p>
70
70
 
71
71
  <p><a href="http://badge.fury.io/rb/netlinx-erb"><img
72
72
  src="https://badge.fury.io/rb/netlinx-erb.svg"></a> <a
73
73
  href="http://www.rubydoc.info/gems/netlinx-erb"><img
74
- src="http://img.shields.io/badge/docs-api-blue.svg"></a></p>
74
+ src="http://img.shields.io/badge/docs-api-blue.svg"></a> <a
75
+ href="https://github.com/amclain/netlinx-erb/blob/master/license.txt"><img
76
+ src="https://img.shields.io/badge/license-MIT-yellowgreen.svg"></a></p>
75
77
 
76
78
  <p>Syntax highlighting is included in <a
77
- href="https://github.com/amclain/sublime-netlinx">sublime-netlinx</a>.</p>
79
+ href="https://github.com/amclain/sublime-netlinx#sublime-text-amx-netlinx-plugin">sublime-netlinx</a>.</p>
78
80
 
79
81
  <h2 id="label-Overview">Overview</h2>
80
82
 
@@ -198,31 +200,497 @@ be installed on your computer for this utility to work. It is included in
198
200
  the NetLinx Studio installation by default.</em></p>
199
201
 
200
202
  <p><strong>If you receive the following error when running gem
201
- install:</strong> <code>Unable to download data from https://rubygems.org/
202
- - SSL_connect returned=1</code></p>
203
+ install:</strong> <code>text Unable to download data from
204
+ https://rubygems.org/ - SSL_connect returned=1 </code></p>
203
205
 
204
206
  <p>Follow this guide: <a
205
207
  href="https://gist.github.com/luislavena/f064211759ee0f806c88">Workaround
206
208
  RubyGems’ SSL errors on Ruby for Windows (RubyInstaller)</a></p>
207
209
 
208
- <h2 id="label-Prerequisite+Knowledge">Prerequisite Knowledge</h2>
210
+ <h2 id="label-Prerequisites">Prerequisites</h2>
209
211
 
210
212
  <p>netlinx-erb is a complex utility and does have a learning curve. However,
211
213
  the time invested in learning this utility pays off in time saved from
212
214
  generating code that would otherwise be handwritten, and troubleshooting
213
215
  fewer bugs. Due to this, project maintenance also becomes easier.</p>
214
216
 
217
+ <h3 id="label-Programming+Languages">Programming Languages</h3>
218
+
215
219
  <p>Basic experience with the <a href="https://www.ruby-lang.org">Ruby
216
220
  programming language</a> is required, as well as <a
217
- href="http://www.stuartellis.eu/articles/erb/">ERB templating</a>.</p>
221
+ href="http://www.stuartellis.eu/articles/erb/">ERB templating</a>. The
222
+ concept of <a href="http://download.imatix.com/mop/introduction.html">Model
223
+ Oriented Programming (MOP)</a> is also used by this framework.</p>
224
+
225
+ <p><strong>Resources:</strong></p>
226
+ <ul><li>
227
+ <p><a href="http://shop.oreilly.com/product/9780596803995.do">Head First
228
+ Ruby</a></p>
229
+ </li><li>
230
+ <p><a
231
+ href="http://www.amazon.com/Design-Patterns-Ruby-Russ-Olsen/dp/0321490452/ref=sr_1_1?ie=UTF8&qid=1424904889&sr=8-1&keywords=ruby+design+patterns">Design
232
+ Patterns in Ruby</a></p>
233
+ </li><li>
234
+ <p><a
235
+ href="http://www.amazon.com/Practical-Object-Oriented-Design-Ruby-Addison-Wesley/dp/0321721330/ref=sr_1_2?ie=UTF8&qid=1424904889&sr=8-2&keywords=ruby+design+patterns">Practical
236
+ Object-Oriented Design in Ruby</a></p>
237
+ </li></ul>
238
+
239
+ <h3 id="label-Development+Tools">Development Tools</h3>
240
+
241
+ <h4 id="label-Text+Editor">Text Editor</h4>
242
+
243
+ <p>A good text editor is crucial for working with netlinx-erb. <a
244
+ href="http://www.sublimetext.com/3">Sublime Text 3</a> with the <a
245
+ href="https://github.com/amclain/sublime-netlinx#sublime-text-amx-netlinx-plugin">sublime-netlinx</a>
246
+ plugin is recommended, as it provides syntax highlighting and code
247
+ completion for netlinx-erb.</p>
248
+
249
+ <blockquote>
250
+ <p><strong><em>Use a Single Editor Well</em></strong></p>
251
+
252
+ <p><em>The editor should be an extension of your hand; make sure your editor
253
+ is configurable, extensible, and programmable.</em> – <a
254
+ href="http://www.informit.com/store/pragmatic-programmer-from-journeyman-to-master-9780201616224">The
255
+ Pragmatic Programmer</a></p>
256
+ </blockquote>
257
+
258
+ <h4 id="label-Command+Prompt">Command Prompt</h4>
259
+
260
+ <p>The command prompt is a powerful, flexible way to issue commands. Due to
261
+ this, many of the tools that netlinx-erb is built on use command line
262
+ interfaces.</p>
263
+
264
+ <p>This guide will assume the reader is proficient with the command prompt.
265
+ SS64 is a great <a href="http://ss64.com/">command line reference</a> if
266
+ you need to look up a command.</p>
267
+
268
+ <h2 id="label-Workflow">Workflow</h2>
269
+
270
+ <p>Developing a NetLinx project with netlinx-erb is significantly different
271
+ than with NetLinx Studio. Although netlinx-erb and NetLinx Studio are not
272
+ strictly mutually exclusive, trying to use NetLinx Studio to develop a
273
+ netlinx-erb project will create unnecessary friction.</p>
274
+
275
+ <p>There are three applications you will bounce between when developing a
276
+ netlinx-erb project:</p>
277
+ <ul><li>
278
+ <p>Text Editor</p>
279
+ </li><li>
280
+ <p>Command Prompt</p>
281
+ </li><li>
282
+ <p>Source Control Management System</p>
283
+ </li></ul>
284
+
285
+ <p>At times you may need to open some of the standalone NetLinx tools like
286
+ NetLinx Diagnostics.</p>
287
+
288
+ <h3 id="label-Transitioning+From+NetLinx+Studio">Transitioning From NetLinx Studio</h3>
289
+
290
+ <p>The big difference to understand coming from NetLinx Studio is that NetLinx
291
+ Studio is designed to be a monolithic, all-in-one application that contains
292
+ all of the features that you need. Or at least that&#39;s the theory. The
293
+ problem is that in reality NetLinx Studio only contains the features that
294
+ AMX thinks you need, and can&#39;t support features you want to add
295
+ yourself.</p>
296
+
297
+ <p>What happens when you want to add code generation and automation to NetLinx
298
+ Studio to save time on repetitive tasks? Well, you can&#39;t.</p>
299
+
300
+ <p>netlinx-erb takes the opposite approach, building on many different
301
+ components that are smaller in scope. To the greatest extent possible,
302
+ these components are extendable, customizable, and cross-platform. This
303
+ means you&#39;re able to modify a netlinx-erb development environment to
304
+ suit a particular project, or your workflow in general.</p>
305
+
306
+ <p>Integrating with source control management (SCM) systems like <a
307
+ href="http://tortoisehg.bitbucket.org/">Mercurial</a> and <a
308
+ href="http://git-scm.com/">Git</a> was also an important goal of
309
+ netlinx-erb. Due to this, most files are plain text and typically easy to
310
+ read by a human. The philosophy is that configuration should happen in your
311
+ text editor, not a proprietary GUI.</p>
218
312
 
219
313
  <h2 id="label-Getting+Started">Getting Started</h2>
220
314
 
221
- <h2 id="label-Code+Examples">Code Examples</h2>
315
+ <h3 id="label-Creating+A+New+Project">Creating A New Project</h3>
316
+
317
+ <p>Open the command prompt in the directory used for your NetLinx projects and
318
+ type:</p>
319
+
320
+ <pre class="code ruby"><code class="ruby">netlinx-erb -n my_project</code></pre>
321
+
322
+ <p>Enter the <code>my_project</code> directory and take a minute to skim
323
+ through the files that have been generated.</p>
324
+
325
+ <h3 id="label-Configuring+The+Workspace">Configuring The Workspace</h3>
326
+
327
+ <p><code>workspace.config.yaml</code>, referred to as the workspace
328
+ configuration, is a text file that replaces the functionality of a NetLinx
329
+ Studio <code>.apw</code> workspace file. Change this file to the following:</p>
330
+
331
+ <pre class="code ruby"><code class="ruby">systems:
332
+ -
333
+ name: My Project
334
+ connection: 192.168.1.2 # (or your master)
335
+ touch_panels:
336
+ -
337
+ path: touch_panel.TP4
338
+ dps:
339
+ - 10001:1:0
340
+ - 10002:1:0
341
+ ir:
342
+ -
343
+ path: cable_box.irl
344
+ dps: 5001:1:0</code></pre>
345
+ <ul><li>
346
+ <p><a
347
+ href="https://github.com/amclain/netlinx-workspace#yaml-workspace-configuration">YAML
348
+ Workspace Configuration Reference</a></p>
349
+ </li></ul>
350
+
351
+ <p>Now create <code>My Project.axs</code> and
352
+ <code>include/cable-box.axi</code>. Using Sublime Text, these files can be
353
+ populated using the <code>NetLinx: New From Template: Overview</code> and
354
+ <code>NetLinx: New From Template: Include</code> commands, respectively. If
355
+ you used the templates, comment out the code for the <a
356
+ href="https://github.com/amclain/amx-lib-log#amx-log-library">logger</a>
357
+ for this example.</p>
358
+
359
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
360
+ (* INCLUDES GO BELOW *)
361
+ (***********************************************************)
362
+
363
+ // Comment this out for the example.
364
+ // #include &#39;amx-lib-log&#39;
365
+
366
+ (***********************************************************)
367
+ (* STARTUP CODE GOES BELOW *)
368
+ (***********************************************************)
369
+ DEFINE_START
370
+
371
+ // Comment this out for the example.
372
+ // logSetLevel(LOG_LEVEL_DETAIL);</code></pre>
373
+
374
+ <p>Also create <code>ir/cable_box.irl</code> and
375
+ <code>touch_panel/touch_panel.TP4</code>. These files can be empty, or the
376
+ real thing. It doesn&#39;t matter for the example.</p>
377
+
378
+ <p>To get an idea of how the workspace config file relates to a traditional
379
+ NetLinx Studio workspace, run:</p>
380
+
381
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_rake'>rake</span> <span class='id identifier rubyid_generate_apw'>generate_apw</span>
382
+ </code></pre>
383
+
384
+ <p>Open <code>My Project.apw</code> in NetLinx Studio and take a look at the
385
+ workspace tree.</p>
386
+
387
+ <p><img src="guides/getting_started/my_project_apw_01.png"></p>
388
+
389
+ <p>The master source code, touch panel, and IR files show up in the tree, just
390
+ like we would expect. What you might not expect is that
391
+ <code>cable-box</code> has shown up under the <code>Include</code> folder
392
+ even though it wasn&#39;t specified in the config. This is a feature of <a
393
+ href="https://github.com/amclain/netlinx-workspace#netlinx-workspace">netlinx-workspace</a>,
394
+ which automatically consumes include files since there will probably be a
395
+ lot of them. Don&#39;t worry though, unwanted <a
396
+ href="https://github.com/amclain/netlinx-workspace/blob/6e99397b4fcfa6bd1cd6766008fd75e8dd5092c0/spec/workspace/yaml/single_system/workspace.config.yaml#L11-L13">files
397
+ can be explicity excluded</a>.</p>
398
+
399
+ <h3 id="label-Code+Generation">Code Generation</h3>
400
+
401
+ <p><em>At this point it is important to have a working knowledge of Ruby and
402
+ ERB. (See <a
403
+ href="https://github.com/amclain/netlinx-erb#prerequisites">prerequisites</a>.)</em></p>
404
+
405
+ <p>In this example we&#39;ll connect touch panel buttons to the corresponding
406
+ buttons on the cable box remote control. To keep the code encapulated,
407
+ we&#39;ll have <code>include/cable-box.axi</code> model the cable box&#39;s
408
+ remote control, and <code>include/ui/template/panel.axi.erb.tmpl</code>
409
+ will model the functions of the identical touch panels.</p>
410
+ <ul><li>
411
+ <p><a href="guides/getting_started/my_project">“My Project” Reference
412
+ Files</a></p>
413
+ </li></ul>
414
+
415
+ <p>First, create <a
416
+ href="guides/getting_started/my_project/include/cable-box.axi">include/cable-box.axi</a>.
417
+ This file uses the traditional <code>.axi</code> extension because no code
418
+ generation is necessary. For a file this simple, code generation may
419
+ actually create more work and make the code harder to understand.</p>
420
+
421
+ <p>Next we&#39;ll configure the touch panels. Open
422
+ <code>include/ui/_config.axi.erb</code>. This is where we&#39;ll instruct
423
+ the system to generate <code>.axi</code> files for each of the touch
424
+ panels:</p>
425
+
426
+ <pre class="code ruby"><code class="ruby"><span class='comment'># Params - Converted into @tmpl_[key]
427
+ </span><span class='comment'># First key (panel name) is available as @tmpl_suffix
428
+ </span><span class='id identifier rubyid_touch_panels'>touch_panels</span> <span class='op'>=</span> <span class='lbrace'>{</span>
429
+ <span class='label'>CONFERENCE_TABLE:</span> <span class='lbrace'>{</span> <span class='label'>dps:</span> <span class='int'>10001</span> <span class='rbrace'>}</span><span class='comma'>,</span>
430
+ <span class='label'>WALL:</span> <span class='lbrace'>{</span> <span class='label'>dps:</span> <span class='int'>10002</span> <span class='rbrace'>}</span><span class='comma'>,</span>
431
+ <span class='rbrace'>}</span>
432
+ </code></pre>
433
+
434
+ <p>The important thing to notice about this file is that values can be passed
435
+ into each touch panel&#39;s hash, which then become available in the
436
+ template as instance variables. By using the instance variable
437
+ <code>@tmpl_dps</code> in the template, the value <code>10001</code> will
438
+ be written to <code>panel-conference-table.axi</code>, and
439
+ <code>10002</code> will be written to <code>panel-wall.axi</code>.
440
+ We&#39;ll go over this more when creating the template file.</p>
441
+ <ul><li>
442
+ <p>Note: <a
443
+ href="https://github.com/amclain/netlinx-erb/issues/1">_config.axi.erb will
444
+ be deprecated</a></p>
445
+ </li></ul>
446
+
447
+ <blockquote>
448
+ <p><strong>Why not use <code>DEFINE_COMBINE</code>?</strong></p>
449
+
450
+ <p>Device combining concatenates all of the events into a single DPS, hiding
451
+ which touch panel actually sent the event. Conceptually, all of the
452
+ physical touch panels have to be thought of as one virtual touch panel –
453
+ they all mirror each other. This means that touch panels that want to share
454
+ the same code are forced to share the same state as well.</p>
455
+
456
+ <p>The answer to this problem is an advanced topic that will be covered in
457
+ another section. It is practical in situations like room combining where
458
+ touch panel B needs to operate autonomously when the rooms are separated,
459
+ but needs to mirror touch panel A when the rooms are combined (a state
460
+ machine).</p>
461
+ </blockquote>
462
+
463
+ <p>Since the touch panels share the same design file,
464
+ <code>touch_panel.TP4</code>, we&#39;ll use code generation to create the
465
+ source code for each panel based on a single template.</p>
466
+
467
+ <p>Create <a
468
+ href="guides/getting_started/my_project/include/ui/template/panel.axi.erb.tmpl">include/ui/template/panel.axi.erb.tmpl</a>.
469
+ The first thing to notice is that unique names for the include guards can
470
+ be code generated:</p>
471
+
472
+ <pre class="code ruby"><code class="ruby">(***********************************************************
473
+ Example Touch Panel
474
+
475
+ For the netlinx-erb getting started project.
476
+ ************************************************************)
477
+
478
+ #if_not_defined &lt;%= &quot;MY_PROJECT_TP_#{@tmpl_suffix}&quot; %&gt;
479
+ #define &lt;%= &quot;MY_PROJECT_TP_#{@tmpl_suffix}&quot; %&gt; 1</code></pre>
480
+
481
+ <p>Let&#39;s apply this to assigning the DPS to each touch panel. Since a
482
+ device definition takes the form of <code>CONSTANT_NAME = DPS</code>, we
483
+ can use code generation to populate the constant name and device number for
484
+ each file:</p>
485
+
486
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
487
+ (* DEVICE NUMBER DEFINITIONS GO BELOW *)
488
+ (***********************************************************)
489
+ DEFINE_DEVICE
490
+
491
+ &lt;%= &quot;#{@dvTP} = #{@tmpl_dps}:1:0;&quot; %&gt;</code></pre>
492
+
493
+ <p>When the <code>.axi</code> files are generated,
494
+ <code>panel-conference-table.axi</code> will contain
495
+ <code>dvTP_CONFERENCE_TABLE = 10001:1:0;</code>, and
496
+ <code>panel-wall.axi</code> will contain <code>dvTP_WALL =
497
+ 10002:1:0;</code>.</p>
498
+
499
+ <blockquote>
500
+ <p>When authoring an <code>erb</code> template it is important to think on a
501
+ higher level of abstration than you would with an <code>axi</code> file,
502
+ keeping in mind that you&#39;re writing code that writes code. Creating
503
+ variations of a similar piece of code is a perfect job for the code
504
+ generator.</p>
505
+ </blockquote>
506
+
507
+ <p>At this point we have a few different sets of data that need to be
508
+ connected together:</p>
509
+ <ul><li>
510
+ <p>Touch panel button numbers</p>
511
+ </li><li>
512
+ <p>Named constants for those buttons</p>
513
+ </li><li>
514
+ <p>The key on the cable box remote control that needs to be triggered when its
515
+ corresponding touch panel button is pressed</p>
516
+ </li></ul>
517
+
518
+ <p>These connections can be described in one place, making future changes
519
+ simple:</p>
520
+
521
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
522
+ (* CONSTANT DEFINITIONS GO BELOW *)
523
+ (***********************************************************)
524
+ DEFINE_CONSTANT
525
+
526
+ &lt;%
527
+ # Remember, this template generates multiple files.
528
+ # Guard your global code to prevent include conflicts!
529
+ -%&gt;
530
+ #if_not_defined MY_PROJECT_TP_CONSTANTS
531
+ #define MY_PROJECT_TP_CONSTANTS 1
532
+
533
+ &lt;% global_constant_justify = 26 -%&gt;
534
+ // Cable Box Buttons
535
+ &lt;%=
536
+ generate_constant_ivars cable_box_buttons = {
537
+ # :btn - Touch panel button number.
538
+ # :key - Cable box remote control key from `cable-box.axi`.
539
+ BTN_CABLE_BOX_1: { btn: 101, key: :CABLE_BOX_KEY_1 },
540
+ BTN_CABLE_BOX_2: { btn: 102, key: :CABLE_BOX_KEY_2 },
541
+ BTN_CABLE_BOX_3: { btn: 103, key: :CABLE_BOX_KEY_3 },
542
+ BTN_CABLE_BOX_4: { btn: 104, key: :CABLE_BOX_KEY_4 },
543
+ BTN_CABLE_BOX_5: { btn: 105, key: :CABLE_BOX_KEY_5 },
544
+ BTN_CABLE_BOX_6: { btn: 106, key: :CABLE_BOX_KEY_6 },
545
+ BTN_CABLE_BOX_7: { btn: 107, key: :CABLE_BOX_KEY_7 },
546
+ BTN_CABLE_BOX_8: { btn: 108, key: :CABLE_BOX_KEY_8 },
547
+ BTN_CABLE_BOX_9: { btn: 109, key: :CABLE_BOX_KEY_9 },
548
+ BTN_CABLE_BOX_0: { btn: 110, key: :CABLE_BOX_KEY_0 },
549
+ }
550
+
551
+ print_constant_hash cable_box_buttons.remap(:btn), justify: global_constant_justify
552
+ %&gt;
553
+
554
+ #end_if</code></pre>
555
+ <ul><li>
556
+ <p><a
557
+ href="http://www.rubydoc.info/gems/netlinx-erb/NetLinx/ERB/Helpers">Helper
558
+ Method API Reference</a></p>
559
+ </li></ul>
560
+
561
+ <p>Now it&#39;s time to add a button event handler to connect the touch panel
562
+ button to the cable box IR code:</p>
563
+
564
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
565
+ (* THE EVENTS GO BELOW *)
566
+ (***********************************************************)
567
+ DEFINE_EVENT
568
+
569
+ // Cable Box Controls
570
+ &lt;%=
571
+ button_event_block(cable_box_buttons.remap(:key), momentary: true) { |key|
572
+ &quot;cable_box_key(#{key})&quot;
573
+ }
574
+ %&gt;</code></pre>
575
+
576
+ <p>Does this section of code look unusually short compared to its NetLinx
577
+ counterpart? Well there&#39;s a good reason for that: The code it writes is
578
+ incredibly repetitive and therefore a lot of work can be handed off to the
579
+ code generator. Even better, since this code references the
580
+ <code>cable_box_buttons</code> hash, every time a button is added or
581
+ modified this section of generated code is updated automatically.</p>
582
+
583
+ <pre class="code ruby"><code class="ruby">// GENERATED FILE `panel-conference-table.axi`
584
+
585
+ (***********************************************************)
586
+ (* THE EVENTS GO BELOW *)
587
+ (***********************************************************)
588
+ DEFINE_EVENT
589
+
590
+ // Cable Box Controls
591
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_1]
592
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_2]
593
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_3]
594
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_4]
595
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_5]
596
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_6]
597
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_7]
598
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_8]
599
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_9]
600
+ button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_0]
601
+ {
602
+ push:
603
+ {
604
+ to[button.input];
605
+
606
+ switch (button.input.channel)
607
+ {
608
+ case BTN_CABLE_BOX_1: cable_box_key(CABLE_BOX_KEY_1);
609
+ case BTN_CABLE_BOX_2: cable_box_key(CABLE_BOX_KEY_2);
610
+ case BTN_CABLE_BOX_3: cable_box_key(CABLE_BOX_KEY_3);
611
+ case BTN_CABLE_BOX_4: cable_box_key(CABLE_BOX_KEY_4);
612
+ case BTN_CABLE_BOX_5: cable_box_key(CABLE_BOX_KEY_5);
613
+ case BTN_CABLE_BOX_6: cable_box_key(CABLE_BOX_KEY_6);
614
+ case BTN_CABLE_BOX_7: cable_box_key(CABLE_BOX_KEY_7);
615
+ case BTN_CABLE_BOX_8: cable_box_key(CABLE_BOX_KEY_8);
616
+ case BTN_CABLE_BOX_9: cable_box_key(CABLE_BOX_KEY_9);
617
+ case BTN_CABLE_BOX_0: cable_box_key(CABLE_BOX_KEY_0);
618
+ }
619
+ }
620
+
621
+ release: {}
622
+ }</code></pre>
623
+
624
+ <p>A remote control is a simple example of code generation in action. For a
625
+ device like a video matrix, imagine what happens when one of the inputs or
626
+ outputs needs to be repatched or renamed. All of the configuration
627
+ information is in one place; no need to find-and-replace throughout a file.
628
+ This also helps to make the code self-documenting, as all of the system
629
+ configuration information is grouped together.</p>
630
+
631
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_matrix_inputs'>matrix_inputs</span> <span class='op'>=</span> <span class='lbrace'>{</span>
632
+ <span class='label'>VID_SRC_BLANK:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>0</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Blank</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
633
+ <span class='label'>VID_SRC_ROOM_1_PODIUM:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>1</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Podium 1</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
634
+ <span class='label'>VID_SRC_ROOM_1_WP:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>2</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Wall Panel 1</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
635
+ <span class='label'>VID_SRC_ROOM_2_PODIUM:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>7</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Podium 2</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
636
+ <span class='label'>VID_SRC_ROOM_2_WP:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>4</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Wall Panel 2</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
637
+ <span class='label'>VID_SRC_ROOM_3_PODIUM:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>5</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Podium 3</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
638
+ <span class='label'>VID_SRC_ROOM_3_WP:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>6</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Wall Panel 3</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
639
+ <span class='label'>VID_SRC_BLURAY:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>9</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Blu-Ray</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
640
+ <span class='label'>VID_SRC_CABLE:</span> <span class='lbrace'>{</span> <span class='label'>input:</span> <span class='int'>10</span><span class='comma'>,</span> <span class='label'>name:</span> <span class='tstring'><span class='tstring_beg'>&quot;</span><span class='tstring_content'>Cable TV</span><span class='tstring_end'>&quot;</span></span> <span class='rbrace'>}</span><span class='comma'>,</span>
641
+ <span class='rbrace'>}</span>
642
+ </code></pre>
643
+
644
+ <blockquote>
645
+ <p><strong>Separating Configuration From Implementation</strong></p>
646
+
647
+ <p>netlinx-erb is designed to keep configuration and implementation code
648
+ separated as much as reasonably possible. This makes configuration changes
649
+ fast and easy, with significantly less risk that those changes will
650
+ introduce bugs or break the system.</p>
651
+ </blockquote>
652
+
653
+ <p>Now that we have a touch panel template, open <code>My Project.axs</code>
654
+ and add the includes for <code>panel-conference-table</code> and
655
+ <code>panel-wall</code>:</p>
656
+
657
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
658
+ (* INCLUDES GO BELOW *)
659
+ (***********************************************************)
660
+
661
+ // Comment this out for the example.
662
+ // #include &#39;amx-lib-log&#39;
663
+
664
+ #include &#39;panel-conference-table&#39;
665
+ #include &#39;panel-wall&#39;</code></pre>
666
+
667
+ <p>Also remember the include for <code>cable-box</code> in
668
+ <code>panel.axi.erb.tmpl</code>:</p>
669
+
670
+ <pre class="code ruby"><code class="ruby">(***********************************************************)
671
+ (* INCLUDES GO BELOW *)
672
+ (***********************************************************)
673
+
674
+ #include &#39;cable-box&#39;</code></pre>
675
+
676
+ <h3 id="label-Compiling">Compiling</h3>
677
+
678
+ <p>From the command line:</p>
679
+
680
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_rake'>rake</span>
681
+ </code></pre>
682
+
683
+ <p>Yes, it&#39;s really that simple. This command runs the code generator,
684
+ generates the RPC file, compiles the project, and creates the source code
685
+ bundle. You can also add your own <a
686
+ href="https://github.com/ruby/rake#description">rake tasks</a> if you need
687
+ to customize this process.</p>
688
+
689
+ <p>See all of the built-in rake tasks with <code>rake -T</code>.</p>
222
690
  </div></div>
223
691
 
224
692
  <div id="footer">
225
- Generated on Wed Feb 25 14:28:07 2015 by
693
+ Generated on Mon Jun 29 16:09:05 2015 by
226
694
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
227
695
  0.8.7.6 (ruby-2.1.3).
228
696
  </div>