Feedback
Frankie
Posts: 71
Ok just as a general question. Do most of you put your feedback in main line or do you use a timeline?
If you do it in a timeline where do you start the timeline? In Define_Start or do you do it when the TP comes online?
If you do it in a timeline where do you start the timeline? In Define_Start or do you do it when the TP comes online?
0
Comments
Since I am rarely dealing with only one panel, but an array of them, I put start my timeline in DEFINE_START. Then, I have a simple flag array that matches the size of the panel array. Online and offline events can set the flags, and the timeline only acts onthe panels that have the flag set on. I generally break this down even further, and have individual timelines for each device requiring feedback, and only setting the appropriate flags on when that device is in use. When done as a module, this is fairly trivial to maintain. I'm a very firm believer in minimizing network traffic at every turn, and this helps greatly. strange things happen when too mcuh traffic is passing to your panels.
Jeff
In order of preference and use:
1. Timelines
2. Mainline - but under an IF() conditional where the condition is satisfied using a timed WAIT so that the code is only executed on certain passes of Mainline. Certainly the conditional is evaluated each pass of Mainline and is therefore less efficient than a TIMELINE. However, the conditional can be easily set anywhere in code under an event handler for instance to cause the next pass of Mainline to update feedback easily.
3. Update feedback only when it changes and refresh feedback on panels when they come ONLINE (don't worry about feedback in Timelines or Mainline).
Note: variable text updates/feedback to panels is only done when the text actually changes and is generally not part of my feedback handling. In other words, if it does not change, don't send it unless a panel goes offline and then comes back online at which point feedback and text is updated on that panel.
More and more though I try to write code so I don't need to be evaluating feedback at all. For instance if you have a bunch of interlocking presets, I just have every button turn off the feedback for the whole array of buttons, then use get_last to turn the last one pressed back on as well as do whatever the button needs to do. There's no need to be constantly evaluating something where you're in control of the only buttons that affect the feedback.
I was shocked the other day to do some work where I inheritied a file that had been started by the AMX folks in Costa Mesa. This code had feedback which was in FOR loops in Mainline. And it was throwing errors constantly because of a zero value array index - the error comes up ".....index to large" - I wish, please AMX, could you fix this to say "TOO large". That's what it should say. It bugs me every time I see it.
**another background fact: when I first moved from the UK to the US in 1992, for the longest time I thought TOO in American was spelt TO. I just never saw it spelt correctly. Then finally I did, and I thought, OK they DO spell it that way, but it seemed an awful lot of people didn't Sorry for the rant - I'm just kind of anal about spelling.....
For those of you who do feedback in Timelines, could you give an example? I usually just do feedback for buttons under the DEFINE_PROGRAM section.
Thanks! This is a great place to learn new progamming techniques.
DEFINE_CONSTANT
FeedbackTimeline = 1
DEFINE_VARIABLE
VOLATILE LONG FeedbackLoopTime[] = {100}
DEFINE_START
TIMELINE_CREATE (FeedbackTimeline,FeedbackLoopTime,1,TIMELINE_ABSOLUTE,TIMELINE_REPEAT)
DEFINE_EVENT
TIMELINE_EVENT [FeedbackTimeline]
{
// Throw all of your feedback code here
}
Adjust the number - in 1000's of a second - for FeedbackLoopTime to adjust how frequently you want your feedback updated. 100 to 200 usually works pretty well, and don't go down to or below 50 - at that point, your master will be running your feedback code and not much else.
You can put TIMELINE_EVENT [FeedbackTimeline] in multiple areas of your code, so you could put the VCR feedback right after the VCR control code, the projector feedback right after the projector code, etc...
- Chip
Hmmm... I remember picking up on this at a training class at the PA office, but I don't know if it was one of the "regular" ones...
Feedback with FOR loops? Something like:
FOR (x=1;x<=10;x++)
{
[TP,x] = FeedbackArray[x]
}
It takes up more space, but I found in the past that doing each one individually ran a lot faster...
[TP,1] = FeedbackArray[1]
[TP,2] = FeedbackArray[2]
[TP,3] = FeedbackArray[3]
etc...
- Chip
For a small job, it probably doesn't matter. But for me now, always in a timeline, ever since that job a few years ago. In my first few Netlinx systems I did feedback in mainline, but when I encountered That Big Job, the mainline feedback concept proved not to be scaleable - it just slowed the system to a crawl, trying to update thousands of buttons in every pass through mainline. After I put my feedback in a timeline, the system appeared considerably more responsive, so I like to say that I speeded thing up by slowing things down.
By putting feedback in a timeline, the buttons are updated at intervals that you control. You could even have more than one timeline for feedback - a faster one for the more-critical feedback (source selection?) and a slower one for the less critical (projector lamp hours?).
For feedback that needs to be somewhat realtime, like device selection, I played around with timeline times to find something that was as slow as possible while still seeming realtime-ish. The range of 150 to 200 ms seems about right for that. YMMV.
For the record, I start the timeline like this:
<code>
DEFINE_START
timeline_create(FBupdate,FBupdateT,1,timeline_relative,timeline_repeat)
</code>
Note that you can invoke the timeline_event multiple times in your program. So I have a button_event where the user selects which projector they want to control, followed by
<code>
timeline_event[FBupdate]
{
[dcDestSel[1]] = (destSel = 1)
</code>
... and so on. Yes, you could certainly put this in a for() loop, as in
<code>
timeline_event[FBupdate]
{
local_var integer i
for(i = 1; i <= nDests; n++)
[dcDestSel] = (destSel = i)
</code>
But if it's only 8 or 12 inputs I might not bother.
Then later on in the program, there is a button_event for the user to select a source, followed by
<code>
timeline_event[FBupdate]
{
[dcSourceSel[1]] = (switcherStatus = 1)
[dcSourceSel[2]] = (switcherStatus = 2)
</code>
...and so on.
Point being twofold: 1) you can name the same timeline_event in multiple places to maintain readabilty ('cause guess who's going to have to figure this out next year, when the client wants an upgrade) and 2) by simply changing the value of (in this case) FBupdateT, you can tune the apparent responsiveness of your program. I find that a *little* bit of lag is good, because it appears that the system has "done something", as opposed to just responded to its own internals (as with an Interlock in Brand C), but you don't want much lag - a barely-perceptible fraction of a second is good. But for anything that matters, like which computer they're seeing right now, I try to use real feedback. That is, "the routing switcher says it's on input 4, and the projector claims to be powered up, unmuted and looking at its VGA input" - that's the best I can do.
HTH.