Home AMX User Forum AMX General Discussion

LEVEL_EVENT ?

In a module I'm working on I was having issues firing off level events using the 1st level event method but nothing fired so I added the 2nd level event method, leaving the 1st method in the code too.

The 2nd one fires no problem but not the first, why? I have several modules that use the LEVEL.INPUT.LEVEL method and apparently they've been working fine. Any thoughts?
LEVEL_EVENT [vdvWeb,LEVEL.INPUT.LEVEL]         

     {
     fnWebDeBug("'Rcv''d LEVEL-',itoa(LEVEL.INPUT.LEVEL),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
     if(LEVEL.INPUT.LEVEL <= nNumConfigBtns)
	  {
	  STACK_VAR INTEGER nPage ;
	  STACK_VAR INTEGER nBtn ;
	  
           nRXNewValue = 1 ;
	  nPage = ((LEVEL.INPUT.LEVEL - 1) / 24) ;
	  nBtn  = (LEVEL.INPUT.LEVEL - (nPage * 24)) ;
	  
	  sWEB_PAGE[nPage + 1].BTN[nBtn].Value = LEVEL.VALUE ;
	  fnWebDeBug("'Rcv''d LEVEL-',itoa(LEVEL.INPUT.LEVEL),' for Page-',itoa(nPage + 1),
					     ' * Btn-',itoa(nBtn),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
         }
     }

LEVEL_EVENT [vdvWeb,0]         

     {
     fnWebDeBug("'Rcv''d LEVEL_0-',itoa(LEVEL.INPUT.LEVEL),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
     if(LEVEL.INPUT.LEVEL <= nNumConfigBtns)
	  {
	  STACK_VAR INTEGER nPage ;
	  STACK_VAR INTEGER nBtn ;
	  
	  nRXNewValue = 1 ;
	  nPage = ((LEVEL.INPUT.LEVEL - 1) / 24) ;
	  nBtn  = (LEVEL.INPUT.LEVEL - (nPage * 24)) ;
	  
	  sWEB_PAGE[nPage + 1].BTN[nBtn].Value = LEVEL.VALUE ;
	  fnWebDeBug("'Rcv''d LEVEL_0-',itoa(LEVEL.INPUT.LEVEL),' for Page-',itoa(nPage + 1),
					     ' * Btn-',itoa(nBtn),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
	  }
     }

If I enable debug I get debug strings from the 2nd event but not the 1st. They should both be firing, shouldn't they?

Comments

  • ericmedleyericmedley Posts: 4,177
    vining wrote: »
    In a module I'm working on I was having issues firing off level events using the 1st level event method but nothing fired so I added the 2nd level event method, leaving the 1st method in the code too.

    The 2nd one fires no problem but not the first, why? I have several modules that use the LEVEL.INPUT.LEVEL method and apparently they've been working fine. Any thoughts?
    LEVEL_EVENT [vdvWeb,LEVEL.INPUT.LEVEL]         
    
         {
         fnWebDeBug("'Rcv''d LEVEL-',itoa(LEVEL.INPUT.LEVEL),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
         if(LEVEL.INPUT.LEVEL <= nNumConfigBtns)
    	  {
    	  STACK_VAR INTEGER nPage ;
    	  STACK_VAR INTEGER nBtn ;
    	  
               nRXNewValue = 1 ;
    	  nPage = ((LEVEL.INPUT.LEVEL - 1) / 24) ;
    	  nBtn  = (LEVEL.INPUT.LEVEL - (nPage * 24)) ;
    	  
    	  sWEB_PAGE[nPage + 1].BTN[nBtn].Value = LEVEL.VALUE ;
    	  fnWebDeBug("'Rcv''d LEVEL-',itoa(LEVEL.INPUT.LEVEL),' for Page-',itoa(nPage + 1),
    					     ' * Btn-',itoa(nBtn),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
             }
         }
    
    LEVEL_EVENT [vdvWeb,0]         
    
         {
         fnWebDeBug("'Rcv''d LEVEL_0-',itoa(LEVEL.INPUT.LEVEL),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
         if(LEVEL.INPUT.LEVEL <= nNumConfigBtns)
    	  {
    	  STACK_VAR INTEGER nPage ;
    	  STACK_VAR INTEGER nBtn ;
    	  
    	  nRXNewValue = 1 ;
    	  nPage = ((LEVEL.INPUT.LEVEL - 1) / 24) ;
    	  nBtn  = (LEVEL.INPUT.LEVEL - (nPage * 24)) ;
    	  
    	  sWEB_PAGE[nPage + 1].BTN[nBtn].Value = LEVEL.VALUE ;
    	  fnWebDeBug("'Rcv''d LEVEL_0-',itoa(LEVEL.INPUT.LEVEL),' for Page-',itoa(nPage + 1),
    					     ' * Btn-',itoa(nBtn),'.  >-Line-<',ITOA(__LINE__),'>'",1) ;
    	  }
         }
    

    If I enable debug I get debug strings from the 2nd event but not the 1st. They should both be firing, shouldn't they?

    is
    LEVEL_EVENT [vdvWeb,LEVEL.INPUT.LEVEL
    a struct you setup? I'm not sure... but if you're using this as an event handler, Level.input.level isn't going to have a value until the event happens. So, I suppose it's value is zero. but is that the same as putting a zero as you do in the 2nd event? A zero implies 'an event on this device from any button/channel/level depending upon which event it's with.' But does a variable having a value of zero mean the same thing as the integer zero to the compiler?

    curious...

    I suppose one could try something like:
    DEFINE_VARIABLE
    
    volatile integer nButton
    
    DEFINE_EVENT
    
    BUTTON_EVENT[vdv_device,nButton]
    {
    push:
      {
      send_string 0 ," atoi (button.input.channel) "
      }
    }
    

    then in debug, set the variable to zero and see what happens. You could then use emulate device to push different button numbers and see if nButton=0 sends through all button pushes. I'd do it myself but I'm nowhere near a master to test. I don't even know if this will compile... Or, if so, will changing nButton during runtime actually change the working of the Button_Event. It sounds to me like it would not.
  • a_riot42a_riot42 Posts: 1,624
    vining wrote: »
    [code]
    LEVEL_EVENT [vdvWeb,LEVEL.INPUT.LEVEL]

    I am surprised the compiler let you do that. What level code are you using to trigger this level_event and how can level.input.level have that value prior to being triggered?
    Paul
  • In the code that's giving you trouble, is there a REBUILD_EVENT somewhere? Remember that the event table gets built at startup, so initially level.input.level is equal to 0 during startup. As long as the event table isn't rebuilt, then the level event will essentially be LEVEL_EVENT[vdvWeb,0] which will capture all level events.

    If the event table gets rebuilt after startup via the Rebuild_Event command, it's possible that Level.Input.Level has a different value and your Level_Event will only fire when that particular level is triggered.

    --John
  • viningvining Posts: 4,368
    a_riot42 wrote:
    I am surprised the compiler let you do that. What level code are you using to trigger this level_event and how can level.input.level have that value prior to being triggered?

    Of course I never really gave this any thought but it must be as eric said and at complie time LEVEL.INPUT.LEVEL would have the value of 0 but that would make it identical to the 2nd method which works.

    I've done this using LEVEL.INPUT.LEVEL or BUTTON.INPUT.CHANNEL and it's always worked, again probably because it compiles as [vdvWeb,0]. I started doing this after seeing it done this way iin AMX modules again never gave any thought as to what it was actually doing.

    Since using [vdvWeb,LEVEL.INPUT.LEVEL] has got to compile as [vdvWeb,0] why doesn't it work and why when I've done this on button events haven't I experience the "hold" problems when using "0" since a hold event with fire when upon any button release and the B.I.C value is then = 0.

    I check a few of my modules where I did this on button event and they didn't use a "hold" handler so maybe thats why. I might have to go back to using arrays.

    Either way if they both compile the same why would one work and not the other especially when they've worked before. I have other modules that use this with out any problem.

    John Gonzales wrote:
    if the event table gets rebuilt after startup via the Rebuild_Event command, it's possible that Level.Input.Level has a different value and your Level_Event will only fire when that particular level is triggered.
    I don't see how Level.Input.Level would have a value other that zero accept during an event itself. I do have a rebuild event after I set my virtual level count at startup but since we run a single thread these two things cna't happen at the same time.
  • I don't see how Level.Input.Level would have a value other that zero accept during an event itself.

    LEVEL.INPUT.LEVEL doesn't get reinitialized to 0 after the event is over. It holds its value so the rebuild_event doesn't have to occur during the level_event to mess it up, but anytime after. Here's some code to test it:
    PROGRAM_NAME='level_input_level test'
    (***********************************************************)
    (*          DEVICE NUMBER DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_DEVICE
    dvTP	     =	10001:1:1	
    dvMaster    = 	5001:1:1
    (***********************************************************)
    (*               CONSTANT DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_CONSTANT
    
    (***********************************************************)
    (*              DATA TYPE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_TYPE
    
    (***********************************************************)
    (*               VARIABLE DEFINITIONS GO BELOW             *)
    (***********************************************************)
    DEFINE_VARIABLE
    
    
    (***********************************************************)
    (*                STARTUP CODE GOES BELOW                  *)
    (***********************************************************)
    DEFINE_START
    SEND_STRING 0, "'AT STARTUP, LEVEL.INPUT.LEVEL = ', ITOA(LEVEL.INPUT.LEVEL)"
    (***********************************************************)
    (*                THE EVENTS GO BELOW                      *)
    (***********************************************************)
    DEFINE_EVENT
    LEVEL_EVENT [dvTP,0]
    {
      SEND_STRING 0, "'AT LEVEL_EVENT, LEVEL.INPUT.LEVEL = ', ITOA(LEVEL.INPUT.LEVEL)"
    }
    
    (***********************************************************)
    (*            THE ACTUAL PROGRAM GOES BELOW                *)
    (***********************************************************)
    DEFINE_PROGRAM
    WAIT 50 
      SEND_STRING 0, "'LEVEL.INPUT.LEVEL = ', ITOA(LEVEL.INPUT.LEVEL)"
    
    (***********************************************************)
    (*                     END OF PROGRAM                      *)
    (*        DO NOT PUT ANY CODE BELOW THIS COMMENT           *)
    (***********************************************************)
    
    
    

    If the only time you have a rebuild_event is during startup, then I'm not sure why your code doesn't work unless it has something to do with the fact that you're in a module and not in _main.axs. Adding this line into your startup code should tell you for sure if level.input.level is at 0 before your rebuild event:
    SEND_STRING 0, "'AT STARTUP, LEVEL.INPUT.LEVEL = ', ITOA(LEVEL.INPUT.LEVEL)"
    

    --John
  • a_riot42a_riot42 Posts: 1,624
    vining wrote: »
    Of course I never really gave this any thought but it must be as eric said and at complie time LEVEL.INPUT.LEVEL would have the value of 0 but that would make it identical to the 2nd method which works.

    I would have thought that level.input.level was undefined prior to the level_event being triggered, or perhaps it retains its value from the last level event triggered. Are you sure it evaluates to 0 and not some other value? If it evaluated to 0 wouldn't it be triggered when the [vdvWeb, 0] got triggered?
    Paul
  • viningvining Posts: 4,368
    Well I guess my assumptions were all wrong! I put this code in my module and really expected it to spit out 1 line since I initialized my variable to 123 I thought when the program ran and level.input.level was = 0 it would send out a single send string 0.

    I also though that if it didn't work as expected then at least the scope would be limited to the module. That's not true either!
    DEFINE_VARIABLE //GENERAL VARS
    
    VOLATILE INTEGER 	nCurrent_L_I_L = 123 ; 
    
    
    DEFINE_PROGRAM
    
    if(LEVEL.INPUT.LEVEL != nCurrent_L_I_L)
         {
         SEND_STRING 0, "'WEB_DEBUG: Current Level.Input.Level = ',itoa(LEVEL.INPUT.LEVEL),'. Value = ',itoa(LEVEL.VALUE),'.  >-Line-<',ITOA(__LINE__),'>'" ;
         nCurrent_L_I_L = LEVEL.INPUT.LEVEL ;
         }
    


    After the program upload I turned on diagnostics and the following was received during the normal start up.
    Line     23 (07:19:58):: WEB_DEBUG: Current Level.Input.Level = 0. Value = 0.  >-Line-<3569>
    Line    256 (07:22:11):: WEB_DEBUG: Current Level.Input.Level = 1. Value = -4.  >-Line-<3569>
    Line    283 (07:22:14):: WEB_DEBUG: Current Level.Input.Level = 11. Value = 1.  >-Line-<3569>
    Line    331 (07:22:57):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 2.  >-Line-<3569>
    Line    334 (07:22:57):: WEB_DEBUG: Current Level.Input.Level = 8. Value = 1.  >-Line-<3569>
    Line    337 (07:22:57):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 2.  >-Line-<3569>
    

    After everything stopped I kept changing the value nCurrent_L_I_L to a non matching value and it consistently prints out the same value which means it does indeed hold the last value system wide.
    Line    345 (07:30:43):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 1.  >-Line-<3569>
    Line    346 (07:30:47):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 1.  >-Line-<3569>
    Line    347 (07:30:51):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 1.  >-Line-<3569>
    Line    348 (07:30:55):: WEB_DEBUG: Current Level.Input.Level = 1. Value = 1.  >-Line-<3569>
    

    And of course if you push a button which initiates a send level from any module anywhere in the code that level and value will print. Even if your code to print the line is tucked away in a completely different module.
    Line    349 (07:30:59):: WEB_DEBUG: Current Level.Input.Level = 8. Value = 100.  >-Line-<3569>
    Line    350 (07:30:59):: WEB_DEBUG: Current Level.Input.Level = 9. Value = 0.  >-Line-<3569>
    

    For some reason I always thought the Event Data Objects were essentially stack vars and their value dissapeared after the event which meant they weren't global in nature and an instance these structures were created for each event table at compile time. That surely isn't true!

    I wish I could remember which AMX modules got me doing using this method. I'll have to go through all my code now and if nothing else change the ones not using arrays to 0. Of course I can't do that in button event that use "hold" handlers but chances are those are already arrays.
  • Events

    The events are not built at run-time. They must be known when the program starts. Because level.input.level is a variable its behavior will be undefined. The program wants to know (i.e. via a constant) what the events are going to be ahead of time so it can build the event table properly. You have to be careful with rebuild_event. It will work for variables in events and rebuild the event talbe but only those variables that are *changed* within the same block of code that the rebuild_event resides in. And it only rebuilds the event table for the values that the variables hold at that time. If the variable changes the event table will no longer match. If you are going to check for a specific level then LEVEL_EVENT[dv, 123] is the right way to go about doing it. If you want to catch all levels then LEVEL_EVENT[dv,0] is the right way to do it and then you can further refine it in the block of code by keying off of level.input.level. You can also use an array of levels and then use get_last to figure out which one triggered the event.
Sign In or Register to comment.