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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 058274100b19e63f0c50839b65a4e514a93dbdb4
|
4
|
+
data.tar.gz: 04b579e0639b2d4dd95a630fd1fb8e514f373131
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9faa8838f45ded9b837c28e1fefa81394d8305d7433ce503bff322ba8b14f9a6ab137b5e1d4ed23cb48f04823f2705951d54322747e6cd82a5d6e4a5827c331d
|
7
|
+
data.tar.gz: e8ecc9bfe0a0dca6ce4fa9f309d4564efe67a17c805806766be362e5f23b59b0604b48dbcfba77833b52354727c9002e23f9f2823a03172c87261c6236b7ad63
|
data/README.md
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
netlinx-erb
|
4
4
|
|
5
|
-
A code generation
|
5
|
+
A code generation framework for AMX NetLinx control systems.
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/netlinx-erb.svg)](http://badge.fury.io/rb/netlinx-erb)
|
8
8
|
[![API Documentation](http://img.shields.io/badge/docs-api-blue.svg)](http://www.rubydoc.info/gems/netlinx-erb)
|
9
|
+
[![MIT License](https://img.shields.io/badge/license-MIT-yellowgreen.svg)](https://github.com/amclain/netlinx-erb/blob/master/license.txt)
|
9
10
|
|
10
|
-
Syntax highlighting is included in [sublime-netlinx](https://github.com/amclain/sublime-netlinx).
|
11
|
+
Syntax highlighting is included in [sublime-netlinx](https://github.com/amclain/sublime-netlinx#sublime-text-amx-netlinx-plugin).
|
11
12
|
|
12
13
|
|
13
14
|
## Overview
|
@@ -54,7 +55,7 @@ arguments.
|
|
54
55
|
|
55
56
|
For the following function:
|
56
57
|
|
57
|
-
```
|
58
|
+
```netlinx
|
58
59
|
define_function patch_video(integer input, integer output)
|
59
60
|
{
|
60
61
|
// Patch video matrix.
|
@@ -112,23 +113,456 @@ installed on your computer for this utility to work. It is included in the
|
|
112
113
|
NetLinx Studio installation by default.*
|
113
114
|
|
114
115
|
**If you receive the following error when running gem install:**
|
115
|
-
|
116
|
+
```text
|
117
|
+
Unable to download data from https://rubygems.org/ - SSL_connect returned=1
|
118
|
+
```
|
116
119
|
|
117
120
|
Follow this guide:
|
118
121
|
[Workaround RubyGems' SSL errors on Ruby for Windows (RubyInstaller)](https://gist.github.com/luislavena/f064211759ee0f806c88)
|
119
122
|
|
120
123
|
|
121
|
-
##
|
124
|
+
## Prerequisites
|
122
125
|
|
123
126
|
netlinx-erb is a complex utility and does have a learning curve. However, the
|
124
127
|
time invested in learning this utility pays off in time saved from generating
|
125
128
|
code that would otherwise be handwritten, and troubleshooting fewer bugs. Due
|
126
129
|
to this, project maintenance also becomes easier.
|
127
130
|
|
131
|
+
### Programming Languages
|
132
|
+
|
128
133
|
Basic experience with the [Ruby programming language](https://www.ruby-lang.org)
|
129
134
|
is required, as well as [ERB templating](http://www.stuartellis.eu/articles/erb/).
|
135
|
+
The concept of [Model Oriented Programming (MOP)](http://download.imatix.com/mop/introduction.html)
|
136
|
+
is also used by this framework.
|
137
|
+
|
138
|
+
**Resources:**
|
139
|
+
|
140
|
+
* [Head First Ruby](http://shop.oreilly.com/product/9780596803995.do)
|
141
|
+
* [Design Patterns in Ruby](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)
|
142
|
+
* [Practical Object-Oriented Design in Ruby](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)
|
143
|
+
|
144
|
+
### Development Tools
|
145
|
+
|
146
|
+
#### Text Editor
|
147
|
+
|
148
|
+
A good text editor is crucial for working with netlinx-erb. [Sublime Text 3](http://www.sublimetext.com/3)
|
149
|
+
with the [sublime-netlinx](https://github.com/amclain/sublime-netlinx#sublime-text-amx-netlinx-plugin)
|
150
|
+
plugin is recommended, as it provides syntax highlighting and code completion
|
151
|
+
for netlinx-erb.
|
152
|
+
|
153
|
+
>***Use a Single Editor Well***
|
154
|
+
|
155
|
+
>*The editor should be an extension of your hand; make sure your editor is
|
156
|
+
configurable, extensible, and programmable.*
|
157
|
+
-- [The Pragmatic Programmer](http://www.informit.com/store/pragmatic-programmer-from-journeyman-to-master-9780201616224)
|
158
|
+
|
159
|
+
#### Command Prompt
|
160
|
+
|
161
|
+
The command prompt is a powerful, flexible way to issue commands. Due to this,
|
162
|
+
many of the tools that netlinx-erb is built on use command line interfaces.
|
163
|
+
|
164
|
+
This guide will assume the reader is proficient with the command prompt.
|
165
|
+
SS64 is a great [command line reference](http://ss64.com/) if you need to look
|
166
|
+
up a command.
|
167
|
+
|
168
|
+
|
169
|
+
## Workflow
|
170
|
+
|
171
|
+
Developing a NetLinx project with netlinx-erb is significantly different than
|
172
|
+
with NetLinx Studio. Although netlinx-erb and NetLinx Studio are not strictly
|
173
|
+
mutually exclusive, trying to use NetLinx Studio to develop a netlinx-erb
|
174
|
+
project will create unnecessary friction.
|
175
|
+
|
176
|
+
There are three applications you will bounce between when developing a
|
177
|
+
netlinx-erb project:
|
178
|
+
|
179
|
+
* Text Editor
|
180
|
+
* Command Prompt
|
181
|
+
* Source Control Management System
|
182
|
+
|
183
|
+
At times you may need to open some of the standalone NetLinx tools like
|
184
|
+
NetLinx Diagnostics.
|
185
|
+
|
186
|
+
### Transitioning From NetLinx Studio
|
187
|
+
|
188
|
+
The big difference to understand coming from NetLinx Studio is that NetLinx
|
189
|
+
Studio is designed to be a monolithic, all-in-one application that contains
|
190
|
+
all of the features that you need. Or at least that's the theory. The problem
|
191
|
+
is that in reality NetLinx Studio only contains the features that AMX thinks
|
192
|
+
you need, and can't support features you want to add yourself.
|
193
|
+
|
194
|
+
What happens when you want to add code generation and automation to NetLinx
|
195
|
+
Studio to save time on repetitive tasks? Well, you can't.
|
196
|
+
|
197
|
+
netlinx-erb takes the opposite approach, building on many different components
|
198
|
+
that are smaller in scope. To the greatest extent possible, these components
|
199
|
+
are extendable, customizable, and cross-platform. This means you're able to
|
200
|
+
modify a netlinx-erb development environment to suit a particular project, or
|
201
|
+
your workflow in general.
|
202
|
+
|
203
|
+
Integrating with source control management (SCM) systems like [Mercurial](http://tortoisehg.bitbucket.org/)
|
204
|
+
and [Git](http://git-scm.com/) was also an important goal of netlinx-erb. Due
|
205
|
+
to this, most files are plain text and typically easy to read by a human. The
|
206
|
+
philosophy is that configuration should happen in your text editor, not a
|
207
|
+
proprietary GUI.
|
130
208
|
|
131
209
|
|
132
210
|
## Getting Started
|
133
211
|
|
134
|
-
|
212
|
+
### Creating A New Project
|
213
|
+
|
214
|
+
Open the command prompt in the directory used for your NetLinx projects and type:
|
215
|
+
|
216
|
+
```text
|
217
|
+
netlinx-erb -n my_project
|
218
|
+
```
|
219
|
+
|
220
|
+
Enter the `my_project` directory and take a minute to skim through the files
|
221
|
+
that have been generated.
|
222
|
+
|
223
|
+
### Configuring The Workspace
|
224
|
+
|
225
|
+
`workspace.config.yaml`, referred to as the workspace configuration, is a text
|
226
|
+
file that replaces the functionality of a NetLinx Studio `.apw` workspace file.
|
227
|
+
Change this file to the following:
|
228
|
+
|
229
|
+
```yaml
|
230
|
+
systems:
|
231
|
+
-
|
232
|
+
name: My Project
|
233
|
+
connection: 192.168.1.2 # (or your master)
|
234
|
+
touch_panels:
|
235
|
+
-
|
236
|
+
path: touch_panel.TP4
|
237
|
+
dps:
|
238
|
+
- 10001:1:0
|
239
|
+
- 10002:1:0
|
240
|
+
ir:
|
241
|
+
-
|
242
|
+
path: cable_box.irl
|
243
|
+
dps: 5001:1:0
|
244
|
+
```
|
245
|
+
|
246
|
+
* [YAML Workspace Configuration Reference](https://github.com/amclain/netlinx-workspace#yaml-workspace-configuration)
|
247
|
+
|
248
|
+
Now create `My Project.axs` and `include/cable-box.axi`. Using Sublime Text,
|
249
|
+
these files can be populated using the `NetLinx: New From Template: Overview`
|
250
|
+
and `NetLinx: New From Template: Include` commands, respectively. If you used
|
251
|
+
the templates, comment out the code for the [logger](https://github.com/amclain/amx-lib-log#amx-log-library)
|
252
|
+
for this example.
|
253
|
+
|
254
|
+
```netlinx
|
255
|
+
(***********************************************************)
|
256
|
+
(* INCLUDES GO BELOW *)
|
257
|
+
(***********************************************************)
|
258
|
+
|
259
|
+
// Comment this out for the example.
|
260
|
+
// #include 'amx-lib-log'
|
261
|
+
|
262
|
+
(***********************************************************)
|
263
|
+
(* STARTUP CODE GOES BELOW *)
|
264
|
+
(***********************************************************)
|
265
|
+
DEFINE_START
|
266
|
+
|
267
|
+
// Comment this out for the example.
|
268
|
+
// logSetLevel(LOG_LEVEL_DETAIL);
|
269
|
+
```
|
270
|
+
|
271
|
+
Also create `ir/cable_box.irl` and `touch_panel/touch_panel.TP4`. These files can
|
272
|
+
be empty, or the real thing. It doesn't matter for the example.
|
273
|
+
|
274
|
+
To get an idea of how the workspace config file relates to a traditional NetLinx
|
275
|
+
Studio workspace, run:
|
276
|
+
|
277
|
+
```text
|
278
|
+
rake generate_apw
|
279
|
+
```
|
280
|
+
|
281
|
+
Open `My Project.apw` in NetLinx Studio and take a look at the workspace tree.
|
282
|
+
|
283
|
+
![NetLinx Studio Workspace Screenshot](guides/getting_started/my_project_apw_01.png)
|
284
|
+
|
285
|
+
The master source code, touch panel, and IR files show up in the tree, just like
|
286
|
+
we would expect. What you might not expect is that `cable-box` has shown up
|
287
|
+
under the `Include` folder even though it wasn't specified in the config.
|
288
|
+
This is a feature of [netlinx-workspace](https://github.com/amclain/netlinx-workspace#netlinx-workspace),
|
289
|
+
which automatically consumes include files since there will probably be a lot of
|
290
|
+
them. Don't worry though, unwanted [files can be explicity excluded](https://github.com/amclain/netlinx-workspace/blob/6e99397b4fcfa6bd1cd6766008fd75e8dd5092c0/spec/workspace/yaml/single_system/workspace.config.yaml#L11-L13).
|
291
|
+
|
292
|
+
### Code Generation
|
293
|
+
|
294
|
+
*At this point it is important to have a working knowledge of Ruby and ERB. (See
|
295
|
+
[prerequisites](https://github.com/amclain/netlinx-erb#prerequisites).)*
|
296
|
+
|
297
|
+
In this example we'll connect touch panel buttons to the corresponding buttons
|
298
|
+
on the cable box remote control. To keep the code encapulated, we'll have
|
299
|
+
`include/cable-box.axi` model the cable box's remote control, and
|
300
|
+
`include/ui/template/panel.axi.erb.tmpl` will model the functions of the
|
301
|
+
identical touch panels.
|
302
|
+
|
303
|
+
* ["My Project" Reference Files](guides/getting_started/my_project)
|
304
|
+
|
305
|
+
First, create [include/cable-box.axi](guides/getting_started/my_project/include/cable-box.axi).
|
306
|
+
This file uses the traditional `.axi` extension because no code generation is
|
307
|
+
necessary. For a file this simple, code generation may actually create more work
|
308
|
+
and make the code harder to understand.
|
309
|
+
|
310
|
+
Next we'll configure the touch panels. Open `include/ui/_config.axi.erb`. This
|
311
|
+
is where we'll instruct the system to generate `.axi` files for each of the
|
312
|
+
touch panels:
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
# Params - Converted into @tmpl_[key]
|
316
|
+
# First key (panel name) is available as @tmpl_suffix
|
317
|
+
touch_panels = {
|
318
|
+
CONFERENCE_TABLE: { dps: 10001 },
|
319
|
+
WALL: { dps: 10002 },
|
320
|
+
}
|
321
|
+
```
|
322
|
+
|
323
|
+
The important thing to notice about this file is that values can be passed into
|
324
|
+
each touch panel's hash, which then become available in the template as instance
|
325
|
+
variables. By using the instance variable `@tmpl_dps` in the template, the value
|
326
|
+
`10001` will be written to `panel-conference-table.axi`, and `10002` will be
|
327
|
+
written to `panel-wall.axi`. We'll go over this more when creating the template
|
328
|
+
file.
|
329
|
+
|
330
|
+
* Note: [_config.axi.erb will be deprecated](https://github.com/amclain/netlinx-erb/issues/1)
|
331
|
+
|
332
|
+
>**Why not use `DEFINE_COMBINE`?**
|
333
|
+
|
334
|
+
>Device combining concatenates all of the events into a single DPS, hiding which
|
335
|
+
touch panel actually sent the event. Conceptually, all of the physical touch
|
336
|
+
panels have to be thought of as one virtual touch panel -- they all mirror each
|
337
|
+
other. This means that touch panels that want to share the same code are forced
|
338
|
+
to share the same state as well.
|
339
|
+
|
340
|
+
>The answer to this problem is an advanced topic that will be covered in
|
341
|
+
another section. It is practical in situations like room combining where touch
|
342
|
+
panel B needs to operate autonomously when the rooms are separated, but needs to
|
343
|
+
mirror touch panel A when the rooms are combined (a state machine).
|
344
|
+
|
345
|
+
Since the touch panels share the same design file, `touch_panel.TP4`,
|
346
|
+
we'll use code generation to create the source code for each panel based on a
|
347
|
+
single template.
|
348
|
+
|
349
|
+
Create [include/ui/template/panel.axi.erb.tmpl](guides/getting_started/my_project/include/ui/template/panel.axi.erb.tmpl).
|
350
|
+
The first thing to notice is that unique names for the include guards can be
|
351
|
+
code generated:
|
352
|
+
|
353
|
+
```netlinx+erb
|
354
|
+
(***********************************************************
|
355
|
+
Example Touch Panel
|
356
|
+
|
357
|
+
For the netlinx-erb getting started project.
|
358
|
+
************************************************************)
|
359
|
+
|
360
|
+
#if_not_defined <%= "MY_PROJECT_TP_#{@tmpl_suffix}" %>
|
361
|
+
#define <%= "MY_PROJECT_TP_#{@tmpl_suffix}" %> 1
|
362
|
+
```
|
363
|
+
|
364
|
+
Let's apply this to assigning the DPS to each touch panel. Since a device
|
365
|
+
definition takes the form of `CONSTANT_NAME = DPS`, we can use code generation
|
366
|
+
to populate the constant name and device number for each file:
|
367
|
+
|
368
|
+
```netlinx+erb
|
369
|
+
(***********************************************************)
|
370
|
+
(* DEVICE NUMBER DEFINITIONS GO BELOW *)
|
371
|
+
(***********************************************************)
|
372
|
+
DEFINE_DEVICE
|
373
|
+
|
374
|
+
<%= "#{@dvTP} = #{@tmpl_dps}:1:0;" %>
|
375
|
+
```
|
376
|
+
|
377
|
+
When the `.axi` files are generated, `panel-conference-table.axi` will contain
|
378
|
+
`dvTP_CONFERENCE_TABLE = 10001:1:0;`, and `panel-wall.axi` will contain
|
379
|
+
`dvTP_WALL = 10002:1:0;`.
|
380
|
+
|
381
|
+
>When authoring an `erb` template it is important to think on a higher level of
|
382
|
+
abstration than you would with an `axi` file, keeping in mind that you're
|
383
|
+
writing code that writes code. Creating variations of a similar piece of code is
|
384
|
+
a perfect job for the code generator.
|
385
|
+
|
386
|
+
At this point we have a few different sets of data that need to be connected
|
387
|
+
together:
|
388
|
+
|
389
|
+
* Touch panel button numbers
|
390
|
+
* Named constants for those buttons
|
391
|
+
* The key on the cable box remote control that needs to be triggered when its
|
392
|
+
corresponding touch panel button is pressed
|
393
|
+
|
394
|
+
These connections can be described in one place, making future changes simple:
|
395
|
+
|
396
|
+
```netlinx+erb
|
397
|
+
(***********************************************************)
|
398
|
+
(* CONSTANT DEFINITIONS GO BELOW *)
|
399
|
+
(***********************************************************)
|
400
|
+
DEFINE_CONSTANT
|
401
|
+
|
402
|
+
<%
|
403
|
+
# Remember, this template generates multiple files.
|
404
|
+
# Guard your global code to prevent include conflicts!
|
405
|
+
-%>
|
406
|
+
#if_not_defined MY_PROJECT_TP_CONSTANTS
|
407
|
+
#define MY_PROJECT_TP_CONSTANTS 1
|
408
|
+
|
409
|
+
<% global_constant_justify = 26 -%>
|
410
|
+
// Cable Box Buttons
|
411
|
+
<%=
|
412
|
+
generate_constant_ivars cable_box_buttons = {
|
413
|
+
# :btn - Touch panel button number.
|
414
|
+
# :key - Cable box remote control key from `cable-box.axi`.
|
415
|
+
BTN_CABLE_BOX_1: { btn: 101, key: :CABLE_BOX_KEY_1 },
|
416
|
+
BTN_CABLE_BOX_2: { btn: 102, key: :CABLE_BOX_KEY_2 },
|
417
|
+
BTN_CABLE_BOX_3: { btn: 103, key: :CABLE_BOX_KEY_3 },
|
418
|
+
BTN_CABLE_BOX_4: { btn: 104, key: :CABLE_BOX_KEY_4 },
|
419
|
+
BTN_CABLE_BOX_5: { btn: 105, key: :CABLE_BOX_KEY_5 },
|
420
|
+
BTN_CABLE_BOX_6: { btn: 106, key: :CABLE_BOX_KEY_6 },
|
421
|
+
BTN_CABLE_BOX_7: { btn: 107, key: :CABLE_BOX_KEY_7 },
|
422
|
+
BTN_CABLE_BOX_8: { btn: 108, key: :CABLE_BOX_KEY_8 },
|
423
|
+
BTN_CABLE_BOX_9: { btn: 109, key: :CABLE_BOX_KEY_9 },
|
424
|
+
BTN_CABLE_BOX_0: { btn: 110, key: :CABLE_BOX_KEY_0 },
|
425
|
+
}
|
426
|
+
|
427
|
+
print_constant_hash cable_box_buttons.remap(:btn), justify: global_constant_justify
|
428
|
+
%>
|
429
|
+
|
430
|
+
#end_if
|
431
|
+
```
|
432
|
+
|
433
|
+
* [Helper Method API Reference](http://www.rubydoc.info/gems/netlinx-erb/NetLinx/ERB/Helpers)
|
434
|
+
|
435
|
+
Now it's time to add a button event handler to connect the touch panel button
|
436
|
+
to the cable box IR code:
|
437
|
+
|
438
|
+
```netlinx+erb
|
439
|
+
(***********************************************************)
|
440
|
+
(* THE EVENTS GO BELOW *)
|
441
|
+
(***********************************************************)
|
442
|
+
DEFINE_EVENT
|
443
|
+
|
444
|
+
// Cable Box Controls
|
445
|
+
<%=
|
446
|
+
button_event_block(cable_box_buttons.remap(:key), momentary: true) { |key|
|
447
|
+
"cable_box_key(#{key})"
|
448
|
+
}
|
449
|
+
%>
|
450
|
+
```
|
451
|
+
|
452
|
+
Does this section of code look unusually short compared to its NetLinx
|
453
|
+
counterpart? Well there's a good reason for that: The code it writes is
|
454
|
+
incredibly repetitive and therefore a lot of work can be handed off to the
|
455
|
+
code generator. Even better, since this code references the `cable_box_buttons`
|
456
|
+
hash, every time a button is added or modified this section of generated code is
|
457
|
+
updated automatically.
|
458
|
+
|
459
|
+
```netlinx
|
460
|
+
// GENERATED FILE `panel-conference-table.axi`
|
461
|
+
|
462
|
+
(***********************************************************)
|
463
|
+
(* THE EVENTS GO BELOW *)
|
464
|
+
(***********************************************************)
|
465
|
+
DEFINE_EVENT
|
466
|
+
|
467
|
+
// Cable Box Controls
|
468
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_1]
|
469
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_2]
|
470
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_3]
|
471
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_4]
|
472
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_5]
|
473
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_6]
|
474
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_7]
|
475
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_8]
|
476
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_9]
|
477
|
+
button_event[dvTP_CONFERENCE_TABLE, BTN_CABLE_BOX_0]
|
478
|
+
{
|
479
|
+
push:
|
480
|
+
{
|
481
|
+
to[button.input];
|
482
|
+
|
483
|
+
switch (button.input.channel)
|
484
|
+
{
|
485
|
+
case BTN_CABLE_BOX_1: cable_box_key(CABLE_BOX_KEY_1);
|
486
|
+
case BTN_CABLE_BOX_2: cable_box_key(CABLE_BOX_KEY_2);
|
487
|
+
case BTN_CABLE_BOX_3: cable_box_key(CABLE_BOX_KEY_3);
|
488
|
+
case BTN_CABLE_BOX_4: cable_box_key(CABLE_BOX_KEY_4);
|
489
|
+
case BTN_CABLE_BOX_5: cable_box_key(CABLE_BOX_KEY_5);
|
490
|
+
case BTN_CABLE_BOX_6: cable_box_key(CABLE_BOX_KEY_6);
|
491
|
+
case BTN_CABLE_BOX_7: cable_box_key(CABLE_BOX_KEY_7);
|
492
|
+
case BTN_CABLE_BOX_8: cable_box_key(CABLE_BOX_KEY_8);
|
493
|
+
case BTN_CABLE_BOX_9: cable_box_key(CABLE_BOX_KEY_9);
|
494
|
+
case BTN_CABLE_BOX_0: cable_box_key(CABLE_BOX_KEY_0);
|
495
|
+
}
|
496
|
+
}
|
497
|
+
|
498
|
+
release: {}
|
499
|
+
}
|
500
|
+
```
|
501
|
+
|
502
|
+
A remote control is a simple example of code generation in action. For a device
|
503
|
+
like a video matrix, imagine what happens when one of the inputs or outputs
|
504
|
+
needs to be repatched or renamed. All of the configuration information is in one
|
505
|
+
place; no need to find-and-replace throughout a file. This also helps to make
|
506
|
+
the code self-documenting, as all of the system configuration information is
|
507
|
+
grouped together.
|
508
|
+
|
509
|
+
```ruby
|
510
|
+
matrix_inputs = {
|
511
|
+
VID_SRC_BLANK: { input: 0, name: "Blank" },
|
512
|
+
VID_SRC_ROOM_1_PODIUM: { input: 1, name: "Podium 1" },
|
513
|
+
VID_SRC_ROOM_1_WP: { input: 2, name: "Wall Panel 1" },
|
514
|
+
VID_SRC_ROOM_2_PODIUM: { input: 7, name: "Podium 2" },
|
515
|
+
VID_SRC_ROOM_2_WP: { input: 4, name: "Wall Panel 2" },
|
516
|
+
VID_SRC_ROOM_3_PODIUM: { input: 5, name: "Podium 3" },
|
517
|
+
VID_SRC_ROOM_3_WP: { input: 6, name: "Wall Panel 3" },
|
518
|
+
VID_SRC_BLURAY: { input: 9, name: "Blu-Ray" },
|
519
|
+
VID_SRC_CABLE: { input: 10, name: "Cable TV" },
|
520
|
+
}
|
521
|
+
```
|
522
|
+
|
523
|
+
>**Separating Configuration From Implementation**
|
524
|
+
|
525
|
+
>netlinx-erb is designed to keep configuration and implementation code separated
|
526
|
+
as much as reasonably possible. This makes configuration changes fast and easy,
|
527
|
+
with significantly less risk that those changes will introduce bugs or break
|
528
|
+
the system.
|
529
|
+
|
530
|
+
Now that we have a touch panel template, open `My Project.axs` and add the
|
531
|
+
includes for `panel-conference-table` and `panel-wall`:
|
532
|
+
|
533
|
+
```netlinx
|
534
|
+
(***********************************************************)
|
535
|
+
(* INCLUDES GO BELOW *)
|
536
|
+
(***********************************************************)
|
537
|
+
|
538
|
+
// Comment this out for the example.
|
539
|
+
// #include 'amx-lib-log'
|
540
|
+
|
541
|
+
#include 'panel-conference-table'
|
542
|
+
#include 'panel-wall'
|
543
|
+
```
|
544
|
+
|
545
|
+
Also remember the include for `cable-box` in `panel.axi.erb.tmpl`:
|
546
|
+
|
547
|
+
```netlinx
|
548
|
+
(***********************************************************)
|
549
|
+
(* INCLUDES GO BELOW *)
|
550
|
+
(***********************************************************)
|
551
|
+
|
552
|
+
#include 'cable-box'
|
553
|
+
```
|
554
|
+
|
555
|
+
### Compiling
|
556
|
+
|
557
|
+
From the command line:
|
558
|
+
|
559
|
+
```text
|
560
|
+
rake
|
561
|
+
```
|
562
|
+
|
563
|
+
Yes, it's really that simple. This command runs the code generator, generates
|
564
|
+
the RPC file, compiles the project, and creates the source code bundle. You can
|
565
|
+
also add your own [rake tasks](https://github.com/ruby/rake#description) if you
|
566
|
+
need to customize this process.
|
567
|
+
|
568
|
+
See all of the built-in rake tasks with `rake -T`.
|