Home AMX User Forum NetLinx Studio

Button Events using get_last

I have been using the get_last(array) for getting the last button/channel pressed from an array of touchpanels. I currently use a single array called channels and pass that to all of the modules I made. I noticed that there could be a situation in which there are two panels being used at the same time and could interfere with each others operation depending on how the events operate. Is it a common practice to use a different array of integers containing the channels for each array of TPs?

Comments

  • ericmedleyericmedley Posts: 4,177
    bb3177 wrote: »
    I have been using the get_last(array) for getting the last button/channel pressed from an array of touchpanels. I currently use a single array called channels and pass that to all of the modules I made. I noticed that there could be a situation in which there are two panels being used at the same time and could interfere with each others operation depending on how the events operate. Is it a common practice to use a different array of integers containing the channels for each array of TPs?

    Well, a lot depends upon your code.

    in the strictest sense, a set of events don't happen at the same time. One will always occur before another. they might be incredibly close together timewise, but the don't happen (computer tick-wise) simultaneously.

    Having said that, you do need to take care that your button events reference things that A) do not allow the second event to do anything until you're darned sure the first is done or B) make sure your functions being called upon don't use any system-wide variables that the values can change during the operation of the event.

    You could, in theory, create a queue for all your button pushes and let that handle the rate at which your program deals with button events.

    There are a variety of ways to handle the problem you describe.

    Having said that, I do have some of my older programs out there chocked full of system wide variables on button events that have never collided. I wrote them way back when dinosaurs roamed the Earth and I didn't know better. In general, if you BEs use Stack_Vars and reference functions in the end, you'll probably be okay. If you're experiencing collisions, you'll have to write a queue for them to keep the cats herded properly.

    I queue my stuff myself when I've got a lot of panels.
  • viningvining Posts: 4,368
    No, a single button array should suffice since only one event can ever be processed at a time. Other pushes occuring at nearly the same time get stacked in a FIFO queue waitng for their turn to be processed. The only time this used to come into play was in "hold events" but that is no longer the case since the master can now differentiate between holds occuring at the same time by all the UIs in the associated UI array for the button event.
  • viningvining Posts: 4,368
    Also like E. was eluding too if you have waits in any part of the code that runs as a result of the button push you'll need to take that into account when you write your code. If a wait is pending when a nother button is pushed it won't be able to run for that push. Likewise if a wait uses a local or global var the value can change by the second push before it executes for the first push causing the first push to finish with possibly wrong values.

    Usually there's a work around but it is conceivably possibly that you may need a button event handler fo each UI. You wouldn't need seperate arrays though just a seperate button event for each UI.
  • DHawthorneDHawthorne Posts: 4,584
    I put the button channels in one array, and the panels in another. Then I use GET_LAST on each, so all the panel events are perfectly discrete. No worry at all about collisions that way.
  • ericmedleyericmedley Posts: 4,177
    DHawthorne wrote: »
    I put the button channels in one array, and the panels in another. Then I use GET_LAST on each, so all the panel events are perfectly discrete. No worry at all about collisions that way.

    Ditto for me too.
  • jjamesjjames Posts: 2,908
    DHawthorne wrote: »
    I put the button channels in one array, and the panels in another. Then I use GET_LAST on each, so all the panel events are perfectly discrete. No worry at all about collisions that way.
    I third that.
  • Thanks for all the informative feedback! As long as I am using my local variable in each event only for that event I am fine right? What I was thinking is that if I have many TPs being used at the same time and several people push a button that is included in my "integer channels[] = {1,2,3.....255}". The first event triggers lets say TP1 in a tp array with channel 4, it drops into the event and right before the get_last() is called someone pushes a different channel in the same TP array with channel 5. At what point does the get_last() return the updated value of 5 and not 4? I think its the get_last that is confusing me. The controller would process all the events that are in the queue waiting to be processed at some point in the processor cycle, but how does it know to return a different get_last value for the second event even though there were two triggered in the past from that array?

    Talking about waits, does the wait work as a "mimic" or "fake" to threading, similar to a costate/wait/waitfor/yield? Where the processor passes the program control over to another section of code and waits to execute the remaining section until some condition is met. How is threading or multitasking done in netlinx?
  • jjamesjjames Posts: 2,908
    I completely forget the outcome of the entire thread (and I personally don't feel like reading all of it right now), but I brought up the same exact thing back in '06. My fear was like yours, except I was noticing that the RELEASE wasn't getting executed. I think my personal conclusion was that the chances of it happening in actual usage was about as close as winning the lottery that I don't even play.

    This might be an interesting read: http://www.amxforums.com/showthread.php?1473-Release-Time

    Keep in mind, get_last has been changed recently so it could be used in a HOLD event. I guess what you *could* do is lock out the ability of firing the event all together if it's too close.

    Example theory:
    button_event[dv_tp,i_channels]
    {
        push:
        {
    	local_var i_lock;
    	if(i_lock == 0)
    	{
    	    on[i_lock]
    	    stack_var integer i_panel;
    	    i_panel = get_last(dv_tp);
    	    // do your stuff here
    	}
        }
    }
    
  • viningvining Posts: 4,368
    bb3177 wrote: »
    last post
    The master can only handle one event at a time so your first button push fires an event which has to finish before any other button pushes can be processed. I believe all button pushes or any other events are put into a FIFO queue which is checked after every pass of the mainline (DP) or after completion of an event. So button pushes occuring at nealy the same time are stacked in this queue and processed one at a time. The first handled button push must complete before the next can be process.

    The problem discussed earlier with changing value occurs when you have waits in your event code or in any code triggered by your event code. The waits are seperate events and are processed when the wait time completes and the master may have processed several other pushes depending on how long the wait time is and how many users are using at the same time. So if a button is pushed on a TP and that event runs and comes across a wait which uses a local or global var of some value and this value is assigned outside of the waits code block it will change but since the wait is pending that code won't work for the second button push but it will possibly change the value of the vars used in the wait's related code that's pending for the first button push.

    Hope that helps but it is a little confusing.

    One way around this as E was eluding to is to create your own queue for stacking events (pushes in this case) and process them in a timeline that repeats at a rate longer than your longest wait or some flag. Fortunately most button events don't need waits since they usually generate strings to devices. Those strings can be put in queues to control their delivery timing whether you just seperate send strings by a fixed time period or wait for a ack from the deivce before sending.
Sign In or Register to comment.