Home AMX User Forum NetLinx Studio

Get_Last alternatives

2

Comments

  • viningvining X Member Posts: 4,368
    Since the previous code I posted had logical flaws in respect to the whole GET_LAST thing especially when dealing with HOLDs I figured I'd re-write it and correct the mistake and then notice other mistakes besides the obvioius.

    It appeared to me that putting blocking VAR in the push even if I did it right wouldn't work because the release would have changed the values as well if some one else pushed/released a TP's button that ran through this code block while a HOLD was in progress on another TP. So I had to modify the way that worked as well.

    This revision doesn't actually block further pushes or releases any more either but simple holds the HOLD values for use during a hold and then compares release values to the hold values to determine if the correct (BTN being held) button was released. So if my thinking is correct other TPs can still use this code while a hold is in progress and there should be no negative outcome.

    The only thing I'm not sure of is what happens when another TP using this same device/code HOLDs a button at the same time. My thinking is that nothing will happen, no second hold taking over or changing values since the hold is affectively a wait. My thinking that since a "HOLD" wait is pending another attemp to "HOLD" wait will simply be disregarded.
    DEFINE_VARIABLE //VAV VARS
    
    VOLATILE INTEGER nHOLD_BTN = 0 ;
    VOLATILE INTEGER nHOLD_TP_INDEX = 0 ;
    VOLATILE INTEGER nHold_In_Progress = 0 ;
    
    BUTTON_EVENT[dvTPArry,nBtnArry] //Buttons pushed 
         
         {
         PUSH:
    	  {
    	  STACK_VAR INTEGER nPUSH_BTN ;
    	  STACK_VAR INTEGER nPUSH_TP_INDEX ;
    	  
    	  if(!nHold_In_Progress)
    	       {
    	       nHOLD_BTN = GET_LAST(nBtnArry) ; //Get index of last BTN whose button was Pushed. For Hold & Release code block.
    	       nHOLD_TP_INDEX = GET_LAST(dvTPArry) ; //Get index of last TP whose button was Pushed. For Hold & Release code block.
    	       }
    	  nPUSH_BTN = GET_LAST(nBtnArry) ; //Get index of last BTN whose button was Pushed. For this code block
    	  nPUSH_TP_INDEX = GET_LAST(dvTPArry) ; //Get index of last TP whose button was Pushed. For this code block
    	  SWITCH(nPUSH_BTN)
    	       {
    	       CASE 1:	 
    		    {
    		    //
    		    }
    	       CASE 2:	 
    		    {
    		    //
    		    }
    	       }
    	  }
         HOLD[6,REPEAT]:
    	  {
    	  nHold_In_Progress = 1 ;
               SWITCH(nHOLD_BTN)
    	       {
    	       CASE 5:    
    		    {
    		    //
    		    }
    	       CASE 6:	
    		    {
    		    //
    		    }
    	       }
    	  }
         RELEASE:
    	  {
    	  STACK_VAR INTEGER nTPArryIndex ;
    	  STACK_VAR INTEGER nRELEASE_BTN ;
    	  
    	  nTPArryIndex = GET_LAST(dvTPArry) ; //Get index of last TP whose button was released
    	  nRELEASE_BTN = GET_LAST(nBtnArry) ; //Get index of last button released on panel
    	  if((nRELEASE_BTN == nHOLD_BTN) && (nTPArryIndex == nHOLD_TP_INDEX))//don't waist time evaluating to DPS.
    	       {
    	       nHold_In_Progress = 0 ;
    	       }
    	  SWITCH(nRELEASE_BTN)
    	       {
    	       CASE 5:  
    		    {
    		    //
    		    }
    	       CASE 6:	
    		    {
    		    //
    		    }
    	       }
    	  }
         }
    
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    Fortunately the right thing happens when two TPs are holding an event for the same IR device. The hold for the first stops and the hold for the second device takes over. This seems like reasonable behavior to me so I leave it alone.
    Paul
  • viningvining X Member Posts: 4,368
    a_riot42 wrote:
    Fortunately the right thing happens when two TPs are holding an event for the same IR device. The hold for the first stops and the hold for the second device takes over. This seems like reasonable behavior to me so I leave it alone.
    Paul
    So it's reasonable to have the 1st user get bumped by another user. The point of this thread was trying to avoid that. If any thing the code should be written so the 1st user takes presedence and if nothing else locks out the ability of another user from screwing up the 1st users inputs until he/she are finished.

    The question is does the system treat the hold like a system named wait or in other words any wait in the system that isn't explicitly named by us. Then I would think in the code I just posted that the second hold would be ignored since the wait is already pending. Of course If I had time I could test it but that not going to happen any time soon.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    a_riot42 wrote:
    So it's reasonable to have the 1st user get bumped by another user. The point of this thread was trying to avoid that. If any thing the code should be written so the 1st user takes presedence and if nothing else locks out the ability of another user from screwing up the 1st users inputs until he/she are finished.

    I don't agree, but obviously its a judgement call. A user can't expect a device to respond to two holds at the same time from two different UIs so the question is what should happen in that event.

    You can do as you do, and block a user from being able to trigger a hold, and popping up your "Please wait...System busy" popup, annoying the user further and adding to their confusion as to why the device isn't responding correctly. Or you can just not do anything, and let the system sort it out for you, in which case if a user is holding a button and it mysteriously stops holding its fairly obvious someone else has taken control from you and you will have to hit the button again if you want to regain control.

    This scenario means that whoever hit a button on a UI most recently, has control, which is more consistent to me than whoever hit a button most recently has control unless someone is holding a button and then you are blocked until all users release that button, and you have cleared your "Please wait...System busy" popup, by which time someone has hit hold again so you get the popup again, and so on and so on, until you are so tired and confused you turn off the TV and go to bed.

    My way means noone is ever denied control when they ask for it, but it may impinge on another user should they be using a hold when you want to as well. C'est la vie n'est-pa?
    Paul
  • viningvining X Member Posts: 4,368
    Well the likely hood of two users trying to issue holds simultaneously on the same device/code block is rare enough for me not to worry about it but the idea of the 1st user getting bumped by the 2nd user who then gets bumped by the 1st user trying to continue his task who then get bumped again by the 2nd user so on and so forth as they both try to ramp their volume in their respective areas is a real clever way of handling things. My method of "Please Wait" or your method of "ignorance is bliss" so they will just think the system is screwed up, your right, it's a judgement call.

    Actually the method I most recently posted doesn't use a "Please Wait" and although not tested it should allow both users to do pushes even if one person is holding. My only thought was if the second person tried a hold while the first person was holding, the second hold wouldn't execute the way my code is written but that depends on how the system evaluates the hold, is it like a wait or not? I think that's prefferable to the dueling hold method since we're only talking about a second or two of waiting. Plus individual button pushes would still work and most folks aren't even aware that they can actually do holds anyway.
  • jjamesjjames Just another dude Posts: 2,906
    a_riot42 wrote: »
    I don't agree, but obviously its a judgement call. A user can't expect a device to respond to two holds at the same time from two different UIs so the question is what should happen in that event.

    So when two users try to change their respective audio zones off of an Autopatch or anything other RS-232 device, someone should get locked out? I beg to differ. Things like that are EASILY avoidable with timelines. Fire a timeline off for each zone that's trying to adjusted.

    Now, two users trying to control the same IR device, that's a different story, but then again - how often is someone going to try to control the same satellite box, or cable box, or anything else that's IR? And you know, if it's explained to the users well enough, there will never be a problem. The users need to know the limitations. Period.
  • viningvining X Member Posts: 4,368
    jjames wrote;
    Things like that are EASILY avoidable with timelines. Fire a timeline off for each zone that's trying to adjusted.
    That would actually solve the problem completely. Do you create a time line ID for each zone or create just enough to cover the max amount of users that could ever possibly what to change volume at the same time plus 1 for good measure and pick the 1st available !ACTIVE?
  • jjamesjjames Just another dude Posts: 2,906
    vining wrote: »
    That would actually solve the problem completely. Do you create a time line ID for each zone or create just enough to cover the max amount of users that could ever possibly what to change volume at the same time plus 1 for good measure and pick the 1st available !ACTIVE?

    I use the number of outputs on whatever audio switcher we're using (usually an 18x18 Autopatch.) So there are always at least 18 timelines, even if at the moment we're using 10 of those outputs (allows for expandability.) Now of course, no two people can control the same zone at the same time (i.e. one wants to go up, the other wants to go down), but again - that's just an obvious limitation of the system the user needs to understand.

    Here's a code snippet:
    BUTTON_EVENT[dv_TP,nVOLUME_BTNS]
    {
       PUSH:
       {
          STACK_VAR INTEGER nPNL
    		STACK_VAR INTEGER nAV_Zone
    		nPNL = GET_LAST(dv_TP)
    		
    		// ASSIGN CURRENT AV ZONE
    		nAV_Zone = nAV_ZONE_MAP[nPNL][1] 
    		
    		// If the zone is on, and it's not already being ramped
    		IF (nAV_ZONE_SOURCE[nAV_Zone] AND (!nVOL_RAMP_STATE[nAV_Zone]))
    		{
    			// Assign direction (1-up, 2-down, 3-mute)
    			nVOL_RAMP_STATE[nAV_Zone] = GET_LAST(nVOLUME_BTNS)
    			
    			// If it's not the mute button
    			IF (BUTTON.INPUT.CHANNEL <> nVOLUME_BTNS[3]) 
    			{
    				ON[BUTTON.INPUT]
    				// If it's mute, go ahead and unmute it here....
    				
    				// Fire off your time line for that zone
    				TIMELINE_CREATE(nAV_Zone+10,nVOL_RAMP_DELAY,1,TIMELINE_RELATIVE,TIMELINE_ONCE)
    			}
    			
    			// Mute button
    			ELSE 
    			{
    				nZONE_VOL_MUTE[nAV_Zone] =	!nZONE_VOL_MUTE[nAV_Zone] // TOGGLE MUTE
    				// Send string or do function to mute
    			}
    		}
       }
    	RELEASE:
    	{
    		STACK_VAR INTEGER nPNL
    		STACK_VAR INTEGER nAV_Zone
    		nPNL = GET_LAST(dv_TP)
    		
    		// ASSIGN CURRENT AV ZONE
    		nAV_Zone = nPNL_AV[nPNL] 
    		
    		// Turn off the "ramp" state
    		nVOL_RAMP_STATE[nAV_Zone] = 0 
    		
    		// Is the zone on?
    		IF (nAV_ZONE_SOURCE[nAV_Zone])
    		{
    			// If it's not the mute button, turn off feedback
    			IF (BUTTON.INPUT.CHANNEL <> nVOLUME_BTNS[3])
    				OFF[BUTTON.INPUT]
    			
    			// Kill the timeline
    			IF (TIMELINE_ACTIVE(nAV_Zone+10))
    				TIMELINE_KILL(nAV_Zone+10)
    		}
    	}
    }
    
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    How would using a timeline help if more than one person is holding a button that affects a single IR device? The problem is the IR device not being able to handle simultaneous IR commands that is the problem, not the control system. Since it can happen in multizone projects using global sources what happens in that case using your timeline approach?

    In your volume code, I am assuming you are not using the AP Duet module? I guess I am confused why you are using a timeline to control volume on a RS232 switch? I guess I haven't encountered the problem you are trying to solve.
    Paul
  • jjamesjjames Just another dude Posts: 2,906
    a_riot42 wrote: »
    How would using a timeline help if more than one person is holding a button that affects a single IR device? The problem is the IR device not being able to handle simultaneous IR commands that is the problem, not the control system. Since it can happen in multizone projects using global sources what happens in that case using your timeline approach?

    Instead of jumping the gun and shooting your mouth off like usual, allow me to quote myself:
    jjames wrote:
    Now, two users trying to control the same IR device, that's a different story, but then again - how often is someone going to try to control the same satellite box, or cable box, or anything else that's IR? And you know, if it's explained to the users well enough, there will never be a problem. The users need to know the limitations. Period.
    Translation:
    I know you can't control an IR device with more than two codes at the same time, which is a limitation of the system and needs to be explained to the client. Period.
    a_riot wrote:
    In your volume code, I am assuming you are not using the AP Duet module?
    No - I don't use modules with devices I use time and time again. I prefer to use my own code, as they're usually way too bloated and rarely achieve what I'm trying to do.
    a_riot wrote:
    I guess I am confused why you are using a timeline to control volume on a RS232 switch?
    How else do you plan on doing it? Instead of criticizing everything, why not pony up the "perfect" code you use?
    a_riot wrote:
    I guess I haven't encountered the problem you are trying to solve.
    Ok
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    jjames wrote: »
    Instead of jumping the gun and shooting your mouth off like usual, allow me to quote myself:

    Woah...no need for the ad hominem attack, they were just some simple questions.
    jjames wrote: »
    Translation:
    I know you can't control an IR device with more than two codes at the same time, which is a limitation of the system and needs to be explained to the client. Period.

    Yes, but that wasn't my question. There are apparently at least two different ways of dealing with this, one is the way Vinning recommends which is to block other users, and the way I do it which is to always give control to the last user in a hold and not block. You didn't answer the question of what your method does in that instance.
    jjames wrote: »
    How else do you plan on doing it? Instead of criticizing everything, why not pony up the "perfect" code you use?

    I use the AMX AP module which seems to deal with this quite well so it isn't a problem I have come across. Perhaps your module is dealing with that situation differently and so you encounter the issue more regularly.
    Paul
  • jjamesjjames Just another dude Posts: 2,906
    a_riot42 wrote: »
    I use the AMX AP module which seems to deal with this quite well so it isn't a problem I have come across. Perhaps your module is dealing with that situation differently and so you encounter the issue more regularly.
    I don't understand . . . because I don't have an issue I'm encountering, what I posted works fine. Though of course it is watered down, but the idea remains.
    a_riot wrote:
    Yes, but that wasn't my question. There are apparently at least two different ways of dealing with this, one is the way Vinning recommends which is to block other users, and the way I do it which is to always give control to the last user in a hold and not block. You didn't answer the question of what your method does in that instance.
    My posted method does nothing with IR.

    Maybe I didn't answer the question because I *very rarely* use HOLD events, and never to control a device.
    a_riot wrote:
    Woah...no need for the ad hominem attack, they were just some simple questions.
    Not an ad hominem "attack", I was just saying - read what I wrote, perhaps just a little on the brash side though. ;)
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    Spire_Jeff wrote: »
    I think that the HOLD problem with GET_LAST() will still exist even if you assign it to a variable. The problem arises in HOLD events because they are more like WAITs. The problem will only manifest itself if you are in the middle of a hold event on one panel and a user on a different panel pushes a button from the same array as I recall.

    Jeff

    If you assign the result of get_last to a variable then there should be no problem, like Dave mentions. Since the result is in a variable, it doesn't matter if another panel uses the same hold code since it will be operating on a different variable. From the testing I have done, get_last will return the last touch panel button pressed system-wide.
    Spire_Jeff wrote: »
    DEFINE_FUNCTION INTEGER myGetLast(INTEGER nCHANNEL, INTEGER nARRAY[]){
    }
    DEFINE_FUNCTION INTEGER myGetLastDev(DEV nCHANNEL, DEV nARRAY[])
    {
    }

    I don't understand why you would write functions that duplicate built-in functions. get_last probably has access to a pointer that you don't have access to, and hence you have to search arrays in linear time.

    There is no point in calling get_last in a hold event because its return value could be a different panel/channel/etc than the one that caused the push you are holding on. That is the point of storing it in a variable.
  • Spire_JeffSpire_Jeff Formerly Caffeinated Programmer Posts: 1,917
    a_riot42 wrote: »
    I don't understand why you would write functions that duplicate built-in functions. get_last probably has access to a pointer that you don't have access to, and hence you have to search arrays in linear time.

    There is no point in calling get_last in a hold event because its return value could be a different panel/channel/etc than the one that caused the push you are holding on. That is the point of storing it in a variable.

    All of the tests I ran with the built-in GET_LAST indicate that it is doing the same thing my function does, only it seems to be overloaded in that you can pass it an array of integers or an array of devices. For some reason, it also does not function properly on a hold. The functions I wrote do work properly in a hold event.

    Now that I think about it, GET_LAST does work a little differently than my function. It is obviously tracking all of these events somewhere as you can call GET_LAST from anywhere and it will return the last value for the array you pass it. In order for my functions to work the same way, you would need to create tracking variables for every array you want to track, then update the tracking variables when ever an event occurs that involves a member of every array being tracked. This would actually add a lot of overhead and it would in fact cause the same problems that currently exist in GET_LAST. This raises a question: Does the processor ALWAYS track this information, or does it build these tracking variables only when a GET_LAST is used in code?

    The reason I initially wrote the modules was to explore and enhance my understanding of the NetLinx processor and its functionality. After writing the functions, and seeing that they work, I have decided to use them because they let me easily update some old code that was written with GET_LAST. This is code that has been working fine, but the possibility did exist in which it would not function properly. By using a get_last that functions properly, I don't have to revisit or rewrite the rest of the code. This means less chance of screwing up functional code because I already tested the new functions and I haven't changed any of the other code.

    In the end, I just developed a different way to skin the cat. It seems to me that your approach to deal with the flaws in GET_LAST is by writing additional code that is written to overcome the flaws. My approach is to simply fix the flaws in GET_LAST. Which way is correct? I would say both. A lot depends on what you are trying to accomplish. It sounds like your approach does add some other functionality, but in the situation I was faced with, I didn't need more, I just needed it to function the same in all cases. I consider my new functions as new tools in my tool box, I just need to know when to use them.

    Jeff
  • mpullinmpullin Obvious Troll Account, Marked for Deletion Posts: 949
    a_riot42 wrote: »
    Woah...no need for the ad hominem attack, they were just some simple questions.
    I'd prefer an alien hominid attack.
  • Spire_JeffSpire_Jeff Formerly Caffeinated Programmer Posts: 1,917
    mpullin wrote: »
    I'd prefer an alien hominid attack.
    a_riot42 wrote: »
    Woah...no need for the ad hominem attack, they were just some simple questions.

    I'd prefer an Eminem attack... they tend rhyme and are done to a beat :P

    Jeff
  • jason_the_adamsjason_the_adams Junior Member Posts: 108
    Spire_Jeff wrote: »
    I'd prefer an Eminem attack... they tend rhyme and are done to a beat :P
    I agree; if conflict is going to ensue, it might as well happen to a funky beat - be it Westside Story with some tap dancing and finger snapping, rapping until someone passes out or their mama has been thoroughly trash talked, or break dancing with serious attitude. Heck, given the present circumstances, I'd even settle for dueling programmers typing out mad code to a stellar rhythm.

    Just think about it.
  • jjamesjjames Just another dude Posts: 2,906
    LOL . . . c'mon . . . it was a completely harmless remark; it wasn't meant to be a put down. My apologies if it was taken that way though.

    Anyway, back on subject . . . I have a question for the users of B.I.C., when writing an event, do you use the actual button number in the definition of the button event, or do you define a constant and use that instead?
  • ColzieColzie Senior Member Posts: 470
    When I use BIC I always assign a constant. I like having all of my button numbers assigned to either constants or arrays at the top of the program. If anything needs to change you don't have to go searching throughout the entire program.
  • ColzieColzie Senior Member Posts: 470
    ...with the exception of IR commands which I correspond the button number to the IR command.
  • viningvining X Member Posts: 4,368
    Spire_Jeff wrote:
    The reason I initially wrote the modules was to explore and enhance my understanding of the NetLinx processor and its functionality.
    Good enough reason for me! Doesn't even matter if it works better or worse or even at all if knowledge was gained.
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    Spire_Jeff wrote: »

    In the end, I just developed a different way to skin the cat. It seems to me that your approach to deal with the flaws in GET_LAST is by writing additional code that is written to overcome the flaws. My approach is to simply fix the flaws in GET_LAST. Which way is correct? I would say both. A lot depends on what you are trying to accomplish. It sounds like your approach does add some other functionality, but in the situation I was faced with, I didn't need more, I just needed it to function the same in all cases. I consider my new functions as new tools in my tool box, I just need to know when to use them.

    Jeff

    I don't know if I would characterize it the way you are. I don't think there are any flaws in get_last per se. It does what it is supposed to do. The problem is the way a hold is implemented, in that the system doesn't know when a hold is actually occurring, it just assumes a hold is taking place when a push with no release happens. get_last cannot return the correct value in a hold since no hardware event occurs for a hold. Since a hold can go on for some time while other touch panels are being used, the value that get_last returns will change while you are processing the hold. The way around this is to save the result from get_last in the push and use it in the hold. That way it won't matter if three people are all holding the same button on three different UIs because the hold will process a different variable for each. You don't really need to write new functions, but of course you can if you want to. Rewriting system functions can have unintended consequences so you might find other bugs.
    Paul
  • viningvining X Member Posts: 4,368
    a_riot42 wrote:
    That way it won't matter if three people are all holding the same button on three different UIs because the hold will process a different variable for each.
    Ya know it never occurred to me to make a "nTPs_ON_HOLD[nNum_TPs]" INTEGER array based on the number of TPs and then using my PUSH get_last TPArry index to track a hold for each TP. My brain was stuck on single HOLD var for all TPs. This should work equally as nice as TIME_LINES w/o the extra code.

    Of course the likely hood of any of this really happening on any of my system is so rare it's not worth fussing about but having the knowledge should I choose to use it was worth the trip.
  • mpullinmpullin Obvious Troll Account, Marked for Deletion Posts: 949
    AMX: It's your world!
    vining wrote: »
    Of course the likely hood of any of this really happening on any of my system is so rare it's not worth fussing about but having the knowledge should I choose to use it was worth the trip.
    I'd think you'd WANT to know when 5 kids were holding the same button, so that your control system could summon Captain Planet...
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    vining wrote: »
    a_riot42 wrote:
    Of course the likely hood of any of this really happening on any of my system is so rare it's not worth fussing about but having the knowledge should I choose to use it was worth the trip.

    Lol...You sound like my boss. I always have the argument with him that rarity of an event shouldn't determine whether it works or not.
    Paul
  • a_riot42a_riot42 AMX Wizard Posts: 1,619
    Does someone feel like testing get_last to see what happens if you have the same TP defined in two different arrays?
    If you have two button events that have two different TP arrays, but there is an identical TP defined in each one, will get_last return different values for each button event?
    define_device
    dvTP1 = 10001:1:1
    dvTP2 = 10002:1:1 
    dvTP3 = 10003:1:1 
    
    dvTPArray1[2] = {dvTP1, dvTP2}
    dvTPArray2[2] = {dvTP2, dvTP3}
    
    
    button_event{dvTPArray1, 10]
    {
      stack_var integer result
      result = get_last(dvTPArray1)
    }
    
    button_event{dvTPArray2, 10]
    {
      stack_var integer result
      result = get_last(dvTPArray2)
    }
    

    If get_last is implemented correctly, it should return two different values in each button event when button 10 is pressed on dvTP2.
    Paul
  • jjamesjjames Just another dude Posts: 2,906
    Without even testing it, my guess is both events will be fired and the proper index will be returned. Will post back in a few minutes with results.
  • jjamesjjames Just another dude Posts: 2,906
    Okay, it didn't even take that long . . . .
    DEFINE_DEVICE
    dvTP_LGR			=	10001:01:00	// MVP-8400i v2.83.9, 		IP - 192.168.1.81
    dvTP_KIT			=	10002:01:00	// MVP-8400i v2.83.9, 		IP - 192.168.1.82
    dvTP_MBA			=	10003:01:00	// NXD-CV7 v-.--.-, 		IP - 192.168.1.83
    
    
    DEFINE_CONSTANT
    DEV dv_TP_TEST1[]=
    {
    	 dvTP_LGR
    	,dvTP_KIT
    }
    
    DEV dv_TP_TEST2[]=
    {
    	 dvTP_KIT
    	,dvTP_MBA
    }
    
    DEFINE_EVENT
    BUTTON_EVENT[dv_TP_TEST1,9993]
    {
    	PUSH:
    	{
    		LOCAL_VAR INTEGER nRESULT1;
    		nRESULT1 = GET_LAST(dv_TP_TEST1);
    		
    		SEND_STRING 0,"'Index ',ITOA(nRESULT1),' was pressed from Array 1'"
    	}
    }
    
    BUTTON_EVENT[dv_TP_TEST2,9993]
    {
    	PUSH:
    	{
    		LOCAL_VAR INTEGER nRESULT2;
    		nRESULT2 = GET_LAST(dv_TP_TEST2);
    		
    		SEND_STRING 0,"'Index ',ITOA(nRESULT2),' was pressed from Array 2'"
    	}
    }
    

    Results:
    Line      9 (17:26:51.718):: Index 2 was pressed from Array 1
    Line     10 (17:26:51.718):: Index 1 was pressed from Array 2
    

    Multiple events are fired if the same button number and device code are defined, hence why sometimes you may get a double pulse or something with IR if one forgets to remove a specific statement from their code (an error I've made plenty of times when I first started coding.)

    The results should not come as a surprise.
  • Spire_JeffSpire_Jeff Formerly Caffeinated Programmer Posts: 1,917
    a_riot42 wrote: »
    Does someone feel like testing get_last to see what happens if you have the same TP defined in two different arrays?
    If you have two button events that have two different TP arrays, but there is an identical TP defined in each one, will get_last return different values for each button event?

    If get_last is implemented correctly, it should return two different values in each button event when button 10 is pressed on dvTP2.
    Paul

    Push and Release function the way you describe. Hold is still subjected to the same limitations.

    Here is the code I used:
    DEFINE_VARIABLE
    DEV dvTPs[] ={dvTEST1,dvTEST2,dvTEST3,dvTEST4,dvTEST5}
    DEV dvTPs2[] ={dvTEST5,dvTEST4,dvTEST3,dvTEST2,dvTEST1}
    
    
    
    DEFINE_EVENT
    BUTTON_EVENT[dvTPs,nUSER_BTN_TEST1]{
    	PUSH:
    		SEND_STRING 0,"'nUSER_BTN_TEST1: GET_LAST() = ',ITOA(GET_LAST(nUSER_BTN_TEST1))";
    }
    BUTTON_EVENT[dvTPs,nUSER_BTN_TEST1]{
    	PUSH:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'###############################################################################'";
    		SEND_STRING 0,"'|[PUSH:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    	}
    	HOLD [20,REPEAT]:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'*******************************************************************************'";
    		SEND_STRING 0,"'|[HOLD:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    
    		DO_PUSH_TIMED(dvTPs[RANDOM_NUMBER(5)+1],nUSER_BTN_TEST1[RANDOM_NUMBER(15)+1],5);
    		
    	}
    	RELEASE:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'-=============================================================================-'";
    		SEND_STRING 0,"'|[RELEASE:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    		SEND_STRING 0,"'/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/'";
    	}
    
    }
    
    
    BUTTON_EVENT[dvTPs2,nUSER_BTN_TEST1]{
    	PUSH:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs2);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'###############################################################################'";
    		SEND_STRING 0,"'|[PUSH:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Push:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    	}
    	HOLD [20,REPEAT]:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs2);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'*******************************************************************************'";
    		SEND_STRING 0,"'|[HOLD:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Hold:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    
    		DO_PUSH_TIMED(dvTPs2[RANDOM_NUMBER(5)+1],nUSER_BTN_TEST1[RANDOM_NUMBER(15)+1],5);
    		
    	}
    	RELEASE:{
    		LOCAL_VAR INTEGER x,y;
    		x = GET_LAST(dvTPs2);
    		y = GET_LAST(nUSER_BTN_TEST);
    		SEND_STRING 0,"'-=============================================================================-'";
    		SEND_STRING 0,"'|[RELEASE:]'";
    		SEND_STRING 0,"'| GET_LAST() -Dev:',ITOA(GET_LAST(dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(GET_LAST(nUSER_BTN_TEST))";
    		SEND_STRING 0,"'| Variable() -Dev:',ITOA(x),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' Get_Last Index:',ITOA(y)";
    		SEND_STRING 0,"'|       my() -Dev:',ITOA(myGetLastDev(BUTTON.INPUT.DEVICE,dvTPs2)),' Actual Dev:',
    										ITOA(BUTTON.INPUT.DEVICE.NUMBER),':',ITOA(BUTTON.INPUT.DEVICE.PORT),':',ITOA(BUTTON.INPUT.DEVICE.SYSTEM),
    										' | Actual Button Release:',ITOA(BUTTON.INPUT.CHANNEL),' myGetLast Index:',ITOA(myGetLast(BUTTON.INPUT.CHANNEL,nUSER_BTN_TEST))";
    		SEND_STRING 0,"'/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/'";
    	}
    
    }
    
    

    here are the results: (ignore the incorrect button index as I forgot to change the array it is looking at :) )
    Line      1 (18:55:12):: Button 25 was pushed!  ********************
    Line      2 (18:55:12):: nUSER_BTN_TEST1: GET_LAST() = 5
    Line      3 (18:55:12):: ###############################################################################
    Line      4 (18:55:12):: |[PUSH:]
    Line      5 (18:55:12):: | GET_LAST() -Dev:1 Actual Dev:10001:1:1 | Actual Button Push:25 Get_Last Index:0
    Line      6 (18:55:12):: | Variable() -Dev:1 Actual Dev:10001:1:1 | Actual Button Push:25 Get_Last Index:0
    Line      7 (18:55:12):: |       my() -Dev:1 Actual Dev:10001:1:1 | Actual Button Push:25 myGetLast Index:0
    Line      8 (18:55:12):: ###############################################################################
    Line      9 (18:55:12):: |[PUSH:]
    Line     10 (18:55:12):: | GET_LAST() -Dev:5 Actual Dev:10001:1:1 | Actual Button Push:25 Get_Last Index:0
    Line     11 (18:55:12):: | Variable() -Dev:5 Actual Dev:10001:1:1 | Actual Button Push:25 Get_Last Index:0
    Line     12 (18:55:12):: |       my() -Dev:5 Actual Dev:10001:1:1 | Actual Button Push:25 myGetLast Index:0
    Line     13 (18:55:14):: *******************************************************************************
    Line     14 (18:55:14):: |[HOLD:]
    Line     15 (18:55:14):: | GET_LAST() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     16 (18:55:14):: | Variable() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     17 (18:55:14):: |       my() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line     18 (18:55:14):: *******************************************************************************
    Line     19 (18:55:14):: |[HOLD:]
    Line     20 (18:55:14):: | GET_LAST() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     21 (18:55:14):: | Variable() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     22 (18:55:14):: |       my() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line     23 (18:55:14):: Button 34 was pushed!  ********************
    Line     24 (18:55:14):: nUSER_BTN_TEST1: GET_LAST() = 14
    Line     25 (18:55:14):: ###############################################################################
    Line     26 (18:55:14):: |[PUSH:]
    Line     27 (18:55:14):: | GET_LAST() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:34 Get_Last Index:0
    Line     28 (18:55:14):: | Variable() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:34 Get_Last Index:0
    Line     29 (18:55:14):: |       my() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:34 myGetLast Index:0
    Line     30 (18:55:14):: ###############################################################################
    Line     31 (18:55:14):: |[PUSH:]
    Line     32 (18:55:14):: | GET_LAST() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:34 Get_Last Index:0
    Line     33 (18:55:14):: | Variable() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:34 Get_Last Index:0
    Line     34 (18:55:14):: |       my() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:34 myGetLast Index:0
    Line     35 (18:55:14):: Button 26 was pushed!  ********************
    Line     36 (18:55:14):: nUSER_BTN_TEST1: GET_LAST() = 6
    Line     37 (18:55:14):: ###############################################################################
    Line     38 (18:55:14):: |[PUSH:]
    Line     39 (18:55:14):: | GET_LAST() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:26 Get_Last Index:0
    Line     40 (18:55:14):: | Variable() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:26 Get_Last Index:0
    Line     41 (18:55:14):: |       my() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:26 myGetLast Index:0
    Line     42 (18:55:14):: ###############################################################################
    Line     43 (18:55:14):: |[PUSH:]
    Line     44 (18:55:14):: | GET_LAST() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:26 Get_Last Index:0
    Line     45 (18:55:14):: | Variable() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:26 Get_Last Index:0
    Line     46 (18:55:14):: |       my() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:26 myGetLast Index:0
    Line     47 (18:55:14):: Button 34 was released!  ******************
    Line     48 (18:55:14):: -=============================================================================-
    Line     49 (18:55:14):: |[RELEASE:]
    Line     50 (18:55:14):: | GET_LAST() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:34 Get_Last Index:0
    Line     51 (18:55:14):: | Variable() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:34 Get_Last Index:0
    Line     52 (18:55:14):: |       my() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:34 myGetLast Index:0
    Line     53 (18:55:14):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line     54 (18:55:14):: -=============================================================================-
    Line     55 (18:55:14):: |[RELEASE:]
    Line     56 (18:55:14):: | GET_LAST() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:34 Get_Last Index:0
    Line     57 (18:55:14):: | Variable() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:34 Get_Last Index:0
    Line     58 (18:55:14):: |       my() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:34 myGetLast Index:0
    Line     59 (18:55:14):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line     60 (18:55:14):: Button 26 was released!  ******************
    Line     61 (18:55:14):: -=============================================================================-
    Line     62 (18:55:14):: |[RELEASE:]
    Line     63 (18:55:14):: | GET_LAST() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:26 Get_Last Index:0
    Line     64 (18:55:14):: | Variable() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:26 Get_Last Index:0
    Line     65 (18:55:14):: |       my() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:26 myGetLast Index:0
    Line     66 (18:55:14):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line     67 (18:55:14):: -=============================================================================-
    Line     68 (18:55:14):: |[RELEASE:]
    Line     69 (18:55:14):: | GET_LAST() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:26 Get_Last Index:0
    Line     70 (18:55:14):: | Variable() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:26 Get_Last Index:0
    Line     71 (18:55:14):: |       my() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:26 myGetLast Index:0
    Line     72 (18:55:14):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line     73 (18:55:16):: *******************************************************************************
    Line     74 (18:55:16):: |[HOLD:]
    Line     75 (18:55:16):: | GET_LAST() -Dev:2 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     76 (18:55:16):: | Variable() -Dev:2 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     77 (18:55:16):: |       my() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line     78 (18:55:16):: *******************************************************************************
    Line     79 (18:55:16):: |[HOLD:]
    Line     80 (18:55:16):: | GET_LAST() -Dev:4 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     81 (18:55:16):: | Variable() -Dev:4 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line     82 (18:55:16):: |       my() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line     83 (18:55:16):: Button 22 was pushed!  ********************
    Line     84 (18:55:16):: nUSER_BTN_TEST1: GET_LAST() = 2
    Line     85 (18:55:16):: ###############################################################################
    Line     86 (18:55:16):: |[PUSH:]
    Line     87 (18:55:16):: | GET_LAST() -Dev:4 Actual Dev:10004:1:1 | Actual Button Push:22 Get_Last Index:0
    Line     88 (18:55:16):: | Variable() -Dev:4 Actual Dev:10004:1:1 | Actual Button Push:22 Get_Last Index:0
    Line     89 (18:55:16):: |       my() -Dev:4 Actual Dev:10004:1:1 | Actual Button Push:22 myGetLast Index:0
    Line     90 (18:55:16):: ###############################################################################
    Line     91 (18:55:16):: |[PUSH:]
    Line     92 (18:55:16):: | GET_LAST() -Dev:2 Actual Dev:10004:1:1 | Actual Button Push:22 Get_Last Index:0
    Line     93 (18:55:16):: | Variable() -Dev:2 Actual Dev:10004:1:1 | Actual Button Push:22 Get_Last Index:0
    Line     94 (18:55:16):: |       my() -Dev:2 Actual Dev:10004:1:1 | Actual Button Push:22 myGetLast Index:0
    Line     95 (18:55:16):: Button 30 was pushed!  ********************
    Line     96 (18:55:16):: nUSER_BTN_TEST1: GET_LAST() = 10
    Line     97 (18:55:16):: ###############################################################################
    Line     98 (18:55:16):: |[PUSH:]
    Line     99 (18:55:16):: | GET_LAST() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:30 Get_Last Index:0
    Line    100 (18:55:16):: | Variable() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:30 Get_Last Index:0
    Line    101 (18:55:16):: |       my() -Dev:5 Actual Dev:10005:1:1 | Actual Button Push:30 myGetLast Index:0
    Line    102 (18:55:16):: ###############################################################################
    Line    103 (18:55:16):: |[PUSH:]
    Line    104 (18:55:16):: | GET_LAST() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:30 Get_Last Index:0
    Line    105 (18:55:16):: | Variable() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:30 Get_Last Index:0
    Line    106 (18:55:16):: |       my() -Dev:1 Actual Dev:10005:1:1 | Actual Button Push:30 myGetLast Index:0
    Line    107 (18:55:16):: Button 22 was released!  ******************
    Line    108 (18:55:16):: -=============================================================================-
    Line    109 (18:55:16):: |[RELEASE:]
    Line    110 (18:55:16):: | GET_LAST() -Dev:4 Actual Dev:10004:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    111 (18:55:16):: | Variable() -Dev:4 Actual Dev:10004:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    112 (18:55:16):: |       my() -Dev:4 Actual Dev:10004:1:1 | Actual Button Release:22 myGetLast Index:0
    Line    113 (18:55:16):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    114 (18:55:16):: -=============================================================================-
    Line    115 (18:55:16):: |[RELEASE:]
    Line    116 (18:55:16):: | GET_LAST() -Dev:2 Actual Dev:10004:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    117 (18:55:16):: | Variable() -Dev:2 Actual Dev:10004:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    118 (18:55:16):: |       my() -Dev:2 Actual Dev:10004:1:1 | Actual Button Release:22 myGetLast Index:0
    Line    119 (18:55:16):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    120 (18:55:16):: Button 30 was released!  ******************
    Line    121 (18:55:16):: -=============================================================================-
    Line    122 (18:55:16):: |[RELEASE:]
    Line    123 (18:55:16):: | GET_LAST() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:30 Get_Last Index:0
    Line    124 (18:55:16):: | Variable() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:30 Get_Last Index:0
    Line    125 (18:55:16):: |       my() -Dev:5 Actual Dev:10005:1:1 | Actual Button Release:30 myGetLast Index:0
    Line    126 (18:55:16):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    127 (18:55:16):: -=============================================================================-
    Line    128 (18:55:16):: |[RELEASE:]
    Line    129 (18:55:16):: | GET_LAST() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:30 Get_Last Index:0
    Line    130 (18:55:16):: | Variable() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:30 Get_Last Index:0
    Line    131 (18:55:16):: |       my() -Dev:1 Actual Dev:10005:1:1 | Actual Button Release:30 myGetLast Index:0
    Line    132 (18:55:16):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    133 (18:55:18):: *******************************************************************************
    Line    134 (18:55:18):: |[HOLD:]
    Line    135 (18:55:18):: | GET_LAST() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line    136 (18:55:18):: | Variable() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line    137 (18:55:18):: |       my() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line    138 (18:55:18):: *******************************************************************************
    Line    139 (18:55:18):: |[HOLD:]
    Line    140 (18:55:18):: | GET_LAST() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line    141 (18:55:18):: | Variable() -Dev:1 Actual Dev:10001:1:1 | Actual Button Hold:25 Get_Last Index:0
    Line    142 (18:55:18):: |       my() -Dev:5 Actual Dev:10001:1:1 | Actual Button Hold:25 myGetLast Index:0
    Line    143 (18:55:18):: Button 34 was pushed!  ********************
    Line    144 (18:55:18):: nUSER_BTN_TEST1: GET_LAST() = 14
    Line    145 (18:55:18):: ###############################################################################
    Line    146 (18:55:18):: |[PUSH:]
    Line    147 (18:55:18):: | GET_LAST() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 Get_Last Index:0
    Line    148 (18:55:18):: | Variable() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 Get_Last Index:0
    Line    149 (18:55:18):: |       my() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 myGetLast Index:0
    Line    150 (18:55:18):: ###############################################################################
    Line    151 (18:55:18):: |[PUSH:]
    Line    152 (18:55:18):: | GET_LAST() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 Get_Last Index:0
    Line    153 (18:55:18):: | Variable() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 Get_Last Index:0
    Line    154 (18:55:18):: |       my() -Dev:3 Actual Dev:10003:1:1 | Actual Button Push:34 myGetLast Index:0
    Line    155 (18:55:18):: Button 22 was pushed!  ********************
    Line    156 (18:55:18):: nUSER_BTN_TEST1: GET_LAST() = 2
    Line    157 (18:55:18):: ###############################################################################
    Line    158 (18:55:18):: |[PUSH:]
    Line    159 (18:55:18):: | GET_LAST() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:22 Get_Last Index:0
    Line    160 (18:55:18):: | Variable() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:22 Get_Last Index:0
    Line    161 (18:55:18):: |       my() -Dev:2 Actual Dev:10002:1:1 | Actual Button Push:22 myGetLast Index:0
    Line    162 (18:55:18):: ###############################################################################
    Line    163 (18:55:18):: |[PUSH:]
    Line    164 (18:55:18):: | GET_LAST() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:22 Get_Last Index:0
    Line    165 (18:55:18):: | Variable() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:22 Get_Last Index:0
    Line    166 (18:55:18):: |       my() -Dev:4 Actual Dev:10002:1:1 | Actual Button Push:22 myGetLast Index:0
    Line    167 (18:55:18):: Button 25 was released!  ******************
    Line    168 (18:55:18):: -=============================================================================-
    Line    169 (18:55:18):: |[RELEASE:]
    Line    170 (18:55:18):: | GET_LAST() -Dev:1 Actual Dev:10001:1:1 | Actual Button Release:25 Get_Last Index:0
    Line    171 (18:55:18):: | Variable() -Dev:1 Actual Dev:10001:1:1 | Actual Button Release:25 Get_Last Index:0
    Line    172 (18:55:18):: |       my() -Dev:1 Actual Dev:10001:1:1 | Actual Button Release:25 myGetLast Index:0
    Line    173 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    174 (18:55:18):: -=============================================================================-
    Line    175 (18:55:18):: |[RELEASE:]
    Line    176 (18:55:18):: | GET_LAST() -Dev:5 Actual Dev:10001:1:1 | Actual Button Release:25 Get_Last Index:0
    Line    177 (18:55:18):: | Variable() -Dev:5 Actual Dev:10001:1:1 | Actual Button Release:25 Get_Last Index:0
    Line    178 (18:55:18):: |       my() -Dev:5 Actual Dev:10001:1:1 | Actual Button Release:25 myGetLast Index:0
    Line    179 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    180 (18:55:18):: Button 34 was released!  ******************
    Line    181 (18:55:18):: -=============================================================================-
    Line    182 (18:55:18):: |[RELEASE:]
    Line    183 (18:55:18):: | GET_LAST() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 Get_Last Index:0
    Line    184 (18:55:18):: | Variable() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 Get_Last Index:0
    Line    185 (18:55:18):: |       my() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 myGetLast Index:0
    Line    186 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    187 (18:55:18):: -=============================================================================-
    Line    188 (18:55:18):: |[RELEASE:]
    Line    189 (18:55:18):: | GET_LAST() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 Get_Last Index:0
    Line    190 (18:55:18):: | Variable() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 Get_Last Index:0
    Line    191 (18:55:18):: |       my() -Dev:3 Actual Dev:10003:1:1 | Actual Button Release:34 myGetLast Index:0
    Line    192 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    193 (18:55:18):: Button 22 was released!  ******************
    Line    194 (18:55:18):: -=============================================================================-
    Line    195 (18:55:18):: |[RELEASE:]
    Line    196 (18:55:18):: | GET_LAST() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    197 (18:55:18):: | Variable() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    198 (18:55:18):: |       my() -Dev:2 Actual Dev:10002:1:1 | Actual Button Release:22 myGetLast Index:0
    Line    199 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Line    200 (18:55:18):: -=============================================================================-
    Line    201 (18:55:18):: |[RELEASE:]
    Line    202 (18:55:18):: | GET_LAST() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    203 (18:55:18):: | Variable() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:22 Get_Last Index:0
    Line    204 (18:55:18):: |       my() -Dev:4 Actual Dev:10002:1:1 | Actual Button Release:22 myGetLast Index:0
    Line    205 (18:55:18):: /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    
    

    As in my other tests, myGetLast functions worked properly in all events including the Hold event. No variable needed.

    Now that I think about it, when you are using variables to track the current hold buttons, are you creating a seperate tracking array for each and every button event, or are you using one array for all button event tracking?

    Jeff
  • jjamesjjames Just another dude Posts: 2,906
    Jeff,
    Either you did something terribly wrong, or I did . . . not sure how I get the "correct" index every time and yours returns 0 every time.....

    Anyway . . . I really don't think there is a problem at all with GET_LAST, I feel it's how you use it. If you try to use the GET_LAST value outside of the event that calls it, well . . . expect problems. Otherwise, if it's used within the same event (except HOLD), then it will always return the correct event.

    I still don't see why people still use the HOLD event when it has such limitations. There are more flexible substitutes of REPEAT (using timelines), and the whole setting of presets using WAITs and CANCEL_WAITs, and I for one intend to make every system as flexible as possible, because when someone wants to add several more touch panels to the system, all I want to do is make a few definitions, and move on with life - not rewrite the entire code.
Sign In or Register to comment.