netlinx-erb 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +440 -6
- data/doc/Array.html +5 -5
- data/doc/Hash.html +5 -5
- data/doc/NetLinx.html +3 -3
- data/doc/NetLinx/ERB.html +401 -13
- data/doc/NetLinx/ERB/HashHelpers.html +1 -1
- data/doc/NetLinx/ERB/Helpers.html +5 -130
- data/doc/NetLinx/Rake.html +3 -3
- data/doc/NetLinx/Rake/ERB.html +4 -4
- data/doc/NetLinx/Rake/ERB/GenerateERB.html +6 -14
- data/doc/NetLinx/Rake/ERB/GenerateRPC.html +1 -1
- data/doc/NetLinx/Rake/ERB/Lines.html +1 -1
- data/doc/NetLinx/Rake/ERB/Push.html +417 -0
- data/doc/RPC.html +1 -1
- data/doc/String.html +14 -14
- data/doc/_index.html +19 -4
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +477 -9
- data/doc/file.license.html +1 -1
- data/doc/index.html +477 -9
- data/doc/method_list.html +40 -22
- data/doc/top-level-namespace.html +1 -1
- data/lib/netlinx-erb.rb +3 -20
- data/lib/netlinx/erb.rb +22 -0
- data/lib/netlinx/erb/erb.rb +71 -6
- data/lib/netlinx/erb/helpers.rb +0 -10
- data/lib/netlinx/rake/erb.rb +2 -0
- data/lib/netlinx/rake/erb/generate_erb.rb +3 -7
- data/lib/netlinx/rake/erb/push.rb +65 -0
- data/template.zip +0 -0
- metadata +6 -3
data/doc/file.license.html
CHANGED
@@ -64,7 +64,7 @@
|
|
64
64
|
<div id="content"><div id='filecontents'>The MIT License (MIT)<br/><br/>Copyright (c) 2014-2015 Alex McLain and Joe McIlvain<br/><br/>Permission is hereby granted, free of charge, to any person obtaining a copy<br/>of this software and associated documentation files (the "Software"), to deal<br/>in the Software without restriction, including without limitation the rights<br/>to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br/>copies of the Software, and to permit persons to whom the Software is<br/>furnished to do so, subject to the following conditions:<br/><br/>The above copyright notice and this permission notice shall be included in<br/>all copies or substantial portions of the Software.<br/><br/>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br/>IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br/>FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br/>AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br/>LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br/>OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br/>THE SOFTWARE.</div></div>
|
65
65
|
|
66
66
|
<div id="footer">
|
67
|
-
Generated on
|
67
|
+
Generated on Mon Jun 29 16:09:05 2015 by
|
68
68
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
69
69
|
0.8.7.6 (ruby-2.1.3).
|
70
70
|
</div>
|
data/doc/index.html
CHANGED
@@ -66,15 +66,17 @@
|
|
66
66
|
|
67
67
|
<p>netlinx-erb</p>
|
68
68
|
|
69
|
-
<p>A code generation
|
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
|
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
|
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-
|
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
|
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's the theory. The
|
293
|
+
problem is that in reality NetLinx Studio only contains the features that
|
294
|
+
AMX thinks you need, and can'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'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'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
|
-
<
|
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 'amx-lib-log'
|
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'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'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'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'll connect touch panel buttons to the corresponding
|
406
|
+
buttons on the cable box remote control. To keep the code encapulated,
|
407
|
+
we'll have <code>include/cable-box.axi</code> model the cable box'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'll configure the touch panels. Open
|
422
|
+
<code>include/ui/_config.axi.erb</code>. This is where we'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'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'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'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 <%= "MY_PROJECT_TP_#{@tmpl_suffix}" %>
|
479
|
+
#define <%= "MY_PROJECT_TP_#{@tmpl_suffix}" %> 1</code></pre>
|
480
|
+
|
481
|
+
<p>Let'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
|
+
<%= "#{@dvTP} = #{@tmpl_dps}:1:0;" %></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'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
|
+
<%
|
527
|
+
# Remember, this template generates multiple files.
|
528
|
+
# Guard your global code to prevent include conflicts!
|
529
|
+
-%>
|
530
|
+
#if_not_defined MY_PROJECT_TP_CONSTANTS
|
531
|
+
#define MY_PROJECT_TP_CONSTANTS 1
|
532
|
+
|
533
|
+
<% global_constant_justify = 26 -%>
|
534
|
+
// Cable Box Buttons
|
535
|
+
<%=
|
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
|
+
%>
|
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'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
|
+
<%=
|
571
|
+
button_event_block(cable_box_buttons.remap(:key), momentary: true) { |key|
|
572
|
+
"cable_box_key(#{key})"
|
573
|
+
}
|
574
|
+
%></code></pre>
|
575
|
+
|
576
|
+
<p>Does this section of code look unusually short compared to its NetLinx
|
577
|
+
counterpart? Well there'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'>"</span><span class='tstring_content'>Blank</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Podium 1</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Wall Panel 1</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Podium 2</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Wall Panel 2</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Podium 3</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Wall Panel 3</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Blu-Ray</span><span class='tstring_end'>"</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'>"</span><span class='tstring_content'>Cable TV</span><span class='tstring_end'>"</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 'amx-lib-log'
|
663
|
+
|
664
|
+
#include 'panel-conference-table'
|
665
|
+
#include 'panel-wall'</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 'cable-box'</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'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
|
693
|
+
Generated on Mon Jun 29 16:09:03 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>
|