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.
- 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
|
[](http://badge.fury.io/rb/netlinx-erb)
|
8
8
|
[](http://www.rubydoc.info/gems/netlinx-erb)
|
9
|
+
[](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
|
+

|
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`.
|