Home AMX User Forum NetLinx Studio

Timeline times as an array

I'm in a bit of a quandary on Timelines. I realize I can't do an array on the Timeline ID and that is fine. However what I'm wanting to know is can you create an array of times and put that into the timeline create. The reason I'm asking is because I'm trying to create an include file that has the capability of controlling up to 10 projectors/displays. The time array doesn't seem to be working for me. Here is some code for you to ponder.
DEFINE_CONSTANT

cDVAryIdx_1_UniversalDisplay__					= 1
cDVAryIdx_2_UniversalDisplay__					= 2
cDVAryIdx_3_UniversalDisplay__					= 3
cDVAryIdx_4_UniversalDisplay__					= 4
cDVAryIdx_5_UniversalDisplay__					= 5
cDVAryIdx_6_UniversalDisplay__					= 6
cDVAryIdx_7_UniversalDisplay__					= 7
cDVAryIdx_8_UniversalDisplay__					= 8
cDVAryIdx_9_UniversalDisplay__					= 9
cDVAryIdx_10_UniversalDisplay__					= 10

cTL_CountdownOffset_UniversalDisplay__				= 30000

cTL_Dev1_Countdown_UniversalDisplay__				= 30001
cTL_Dev2_Countdown_UniversalDisplay__				= 30002
cTL_Dev3_Countdown_UniversalDisplay__				= 30003
cTL_Dev4_Countdown_UniversalDisplay__				= 30004
cTL_Dev5_Countdown_UniversalDisplay__				= 30005
cTL_Dev6_Countdown_UniversalDisplay__				= 30006
cTL_Dev7_Countdown_UniversalDisplay__				= 30007
cTL_Dev8_Countdown_UniversalDisplay__				= 30008
cTL_Dev9_Countdown_UniversalDisplay__				= 30009
cTL_Dev10_Countdown_UniversalDisplay__				= 30010

DEFINE_VARIABLE

VOLATILE LONG nTL_CountdownTime_UniversalDisplay__[10][2] //10 Devices, 2 Times - Warmup/Cooldown

(***********************************************************)
(*              SUBROUTINE DEFINITIONS GO BELOW            *)
(***********************************************************)
DEFINE_FUNCTION fnSendPowerCmd_UniversalDisplay__(DEV __dvDev, INTEGER __nDevIdx, INTEGER __PwrCmd)
{	
	SWITCH(__PwrCmd)
	{
		CASE 0:
		{ //Execute if __PwrCmd = 0 (OFF)
			
			IF(uFdbk_UniversalDisplay__[__nDevIdx].Power)
			{ //Execute if Power State is On
				
				IF(nCountdownStatus[__nDevIdx] = cDeviceStatus_Ready_UniversalDisplay__)
				{ //Execute if Device is Ready
					
					SEND_STRING dvDEVs_UniversalDisplay__[__nDevIdx],"uCmds_UniversalDisplay__[__nDevIdx].PowerOff"
					uFdbk_UniversalDisplay__[__nDevIdx].Power = cDevicePowerState_Off
					
					IF(![dvDEVs_UniversalDisplay__[__nDevIdx],cFnChnl_DisableCountdown_UniversalDisplay__])
					{ //Change Device Status and Start Countdown if DisableCountdown Flag is not Enabled
						
						nCountdownStatus[__nDevIdx] = cDeviceStatus_Cooling_UniversalDisplay__
						[b]TIMELINE_CREATE(cTL_CountdownOffset_UniversalDisplay__+__nDevIdx,nTL_CountdownTime_UniversalDisplay__[__nDevIdx],LENGTH_STRING(nTL_CountdownTime_UniversalDisplay__[__nDevIdx]),TIMELINE_ABSOLUTE,TIMELINE_REPEAT)[/b]
					}
				}
			}
			ELSE
			{ //Execute if Power State is Off
				SEND_STRING dvDEVs_UniversalDisplay__[__nDevIdx],"uCmds_UniversalDisplay__[__nDevIdx].PowerOff"
			}
		}	
		DEFAULT:
		{ //Execute if __PwrCmd is Anything but 0 (ON)
			
			IF(!uFdbk_UniversalDisplay__[__nDevIdx].Power)
			{ //Execute if Power State is Off
				
				IF(nCountdownStatus[__nDevIdx] = cDeviceStatus_Ready_UniversalDisplay__)
				{ //Execute if Device is Ready
					
					SEND_STRING dvDEVs_UniversalDisplay__[__nDevIdx],"uCmds_UniversalDisplay__[__nDevIdx].PowerOn"
					uFdbk_UniversalDisplay__[__nDevIdx].Power = cDevicePowerState_On
					
					IF(![dvDEVs_UniversalDisplay__[__nDevIdx],cFnChnl_DisableCountdown_UniversalDisplay__])
					{ //Change Device Status and Start Countdown if DisableCountdown Flag is not Enabled
						
						nCountdownStatus[__nDevIdx] = cDeviceStatus_Warming_UniversalDisplay__
						[b]TIMELINE_CREATE(cTL_CountdownOffset_UniversalDisplay__+__nDevIdx,nTL_CountdownTime_UniversalDisplay__[__nDevIdx],LENGTH_STRING(nTL_CountdownTime_UniversalDisplay__[__nDevIdx]),TIMELINE_ABSOLUTE,TIMELINE_REPEAT)[/b]
					}
				}
			}
			ELSE
			{ //Execute if Power State is On
				SEND_STRING dvDEVs_UniversalDisplay__[__nDevIdx],"uCmds_UniversalDisplay__[__nDevIdx].PowerOn"
			}
		}
	}
}

DEFINE_START

nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_1_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_2_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_3_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_4_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_5_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_6_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_7_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_8_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_9_UniversalDisplay__][1] = 65000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_10_UniversalDisplay__][1] = 65000
			
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_1_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_2_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_3_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_4_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_5_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_6_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_7_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_8_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_9_UniversalDisplay__][2] = 70000
nTL_CountdownTime_UniversalDisplay__[cDVAryIdx_10_UniversalDisplay__][2] = 70000

DEFINE_EVENT
TIMELINE_EVENT[cTL_Dev1_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev2_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev3_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev4_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev5_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev6_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev7_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev8_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev9_Countdown_UniversalDisplay__]
TIMELINE_EVENT[cTL_Dev10_Countdown_UniversalDisplay__]
{
	LOCAL_VAR INTEGER __nID
	LOCAL_VAR INTEGER __nSequence
	__nID = TIMELINE.ID - cTL_CountdownOffset_UniversalDisplay__
	__nSequence = TIMELINE.SEQUENCE
	
	SWITCH(TIMELINE.SEQUENCE)
	{
		CASE 1:
		{
			IF(nCountdownStatus[__nID] = cDeviceStatus_Warming_UniversalDisplay__ ||
			   nCountdownStatus[__nID] = cDeviceStatus_NotReady_UniversalDisplay__)
			{
				TIMELINE_KILL(__nID+cTL_CountdownOffset_UniversalDisplay__)
				nCountdownStatus[__nID] = cDeviceStatus_Ready_UniversalDisplay__
			}
		}
		CASE 2:
		{
			IF(nCountdownStatus[__nID] = cDeviceStatus_Cooling_UniversalDisplay__ ||
			   nCountdownStatus[__nID] = cDeviceStatus_NotReady_UniversalDisplay__)
					nCountdownStatus[__nID] = cDeviceStatus_Ready_UniversalDisplay__
		}
	}
}

The nTL_CountdownTime_UniversalDisplay array propogates the two times perfectly, however when the function is called the timelines do not start. If I change nTL_CountdownTime_UniversalDisplay to this:
VOLATILE LONG nTL_CountdownTime_UniversalDisplay__[] = {65000,70000}

And change the timeline_create to this:
TIMELINE_CREATE(cTL_CountdownOffset_UniversalDisplay__+__nDevIdx,nTL_CountdownTime_UniversalDisplay__,LENGTH_STRING(nTL_CountdownTime_UniversalDisplay__),TIMELINE_ABSOLUTE,TIMELINE_REPEAT)

The code works beautifully and as expected. The problem is the warmup and cooldown times will be the same for all 10 devices and I may not want them to be. I want to be able to set different warmup and cooldown times for any of the 10 devices if need be.

Is this even possible?

Comments

  • TIMELINE_EVENT[1]
    TIMELINE_EVENT[2]
    TIMELINE_EVENT[3]
    TIMELINE_EVENT[4]
    TIMELINE_EVENT[5]
    TIMELINE_EVENT[6]
    TIMELINE_EVENT[7]
    TIMELINE_EVENT[8]
    TIMELINE_EVENT[9]
    TIMELINE_EVENT[10]
    {
    nNumber=TIMELINE.ID
    //Do what you need to do
    }
    

    Here is a pseudo-timeline array.

    You can do a timeline create numbering the timelines 1-10 as devices require. The above event will trigger from any of the timelines. nNumber will tell you which one.
  • ericmedleyericmedley Posts: 4,177
    TIMELINE_EVENT[1]
    TIMELINE_EVENT[2]
    TIMELINE_EVENT[3]
    TIMELINE_EVENT[4]
    TIMELINE_EVENT[5]
    TIMELINE_EVENT[6]
    TIMELINE_EVENT[7]
    TIMELINE_EVENT[8]
    TIMELINE_EVENT[9]
    TIMELINE_EVENT[10]
    {
    nNumber=TIMELINE.ID
    //Do what you need to do
    }
    

    Here is a pseudo-timeline array.

    You can do a timeline create numbering the timelines 1-10 as devices require. The above event will trigger from any of the timelines. nNumber will tell you which one.

    I did a little experiment like this as well. My main concern was: will triggering a second event while the first one is running cancel or goof up the variables of the currently running timeline(s). To my joy, it did not. So, in a sense, it is truly a timeline array. I imagine it's just a matter of rewriting the complier to allow for it in the source code.
  • ericmedley wrote: »
    I did a little experiment like this as well. My main concern was: will triggering a second event while the first one is running cancel or goof up the variables of the currently running timeline(s). To my joy, it did not. So, in a sense, it is truly a timeline array. I imagine it's just a matter of rewriting the complier to allow for it in the source code.

    Right, and I have that in my code but that is not what I'm asking. I'm wanting to know why I can't create a multidimensional array for the times or if I can what am I doing wrong. Below is simpler example of what I'm trying to accomplish using only 3 devices:
    DEFINE_DEVICE
    dvTP = 10002:1:0
    
    DEFINE_CONSTANT
    
    TL_1 = 1
    TL_2 = 2
    TL_3 = 3
    
    DEFINE_VARIABLE
    
    VOLATILE LONG TL_Times[3][2] //3 devices, 2 times per device - warmup and cooldown
    
    DEFINE_START
    
    
    //Set Warmup Times for Device
    TL_Times[TL_1][1] = 65000
    TL_Times[TL_2][1] = 35000
    TL_Times[TL_3][1] = 10000
    
    //Set Cooldown Times for Device
    TL_Times[TL_1][2] = 70000
    TL_Times[TL_2][2] = 40000
    TL_Times[TL_3][2] = 15000
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP,1] //Power On Device 1
    BUTTON_EVENT[dvTP,2] //Power On Device 2
    BUTTON_EVENT[dvTP,3] //Power On Device 3
    {
        PUSH:
        {
    		SWITCH(BUTTON.INPUT.CHANNEL)
            {
                CASE 1:{TIMELINE_CREATE(TL_1,TL_Times[TL_1],LENGTH_STRING(TL_Times[TL_1]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 2:{TIMELINE_CREATE(TL_2,TL_Times[TL_2],LENGTH_STRING(TL_Times[TL_2]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 3:{TIMELINE_CREATE(TL_3,TL_Times[TL_3],LENGTH_STRING(TL_Times[TL_3]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
            }
        }
    }
    
    TIMELINE_EVENT[TL_1]
    TIMELINE_EVENT[TL_2]
    TIMELINE_EVENT[TL_3]
    {
    	STACK_VAR INTEGER nNumber
    	nNumber = TIMELINE.ID
    	//Do what I need to do
    }
    

    With the code above the timelines never become active. However if I change my code to this:
    DEFINE_DEVICE
    dvTP = 10002:1:0
    
    DEFINE_CONSTANT
    
    TL_1 = 1
    TL_2 = 2
    TL_3 = 3
    
    DEFINE_VARIABLE
    
    VOLATILE LONG TL_Times[] = {65000,75000}
    
    DEFINE_START
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP,1] //Power On Device 1
    BUTTON_EVENT[dvTP,2] //Power On Device 2
    BUTTON_EVENT[dvTP,3] //Power On Device 3
    {
        PUSH:
        {
    		SWITCH(BUTTON.INPUT.CHANNEL)
            {
                CASE 1:{TIMELINE_CREATE(TL_1,TL_Times,LENGTH_STRING(TL_Times),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 2:{TIMELINE_CREATE(TL_2,TL_Times,LENGTH_STRING(TL_Times),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 3:{TIMELINE_CREATE(TL_3,TL_Times,LENGTH_STRING(TL_Times),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
            }
        }
    }
    
    TIMELINE_EVENT[TL_1]
    TIMELINE_EVENT[TL_2]
    TIMELINE_EVENT[TL_3]
    {
    	STACK_VAR INTEGER nNumber
    	nNumber = TIMELINE.ID
    	//Do what I need to do
    }
    

    All three timelines become active when they are supposed to. The problem with the second example is that I have to have the same warmup and cooldown times for all three displays. 95% of the jobs that I program for there is at least 1 projector and 1 or more plasma/LCD displays. It wouldn't be practical for me to have 65 seconds of warmup/cooldown time on the plasma/LCD.

    Sorry about the mess of code I posted previously. It's been a long week and didn't think about creating something simpler. :)
  • Joe HebertJoe Hebert Posts: 2,159
    undrtkr wrote: »
    DEFINE_DEVICE
    dvTP = 10002:1:0
    
    DEFINE_CONSTANT
    
    TL_1 = 1
    TL_2 = 2
    TL_3 = 3
    
    DEFINE_VARIABLE
    
    VOLATILE LONG TL_Times[3][2] //3 devices, 2 times per device - warmup and cooldown
    
    DEFINE_START
    
    
    //Set Warmup Times for Device
    TL_Times[TL_1][1] = 65000
    TL_Times[TL_2][1] = 35000
    TL_Times[TL_3][1] = 10000
    
    //Set Cooldown Times for Device
    TL_Times[TL_1][2] = 70000
    TL_Times[TL_2][2] = 40000
    TL_Times[TL_3][2] = 15000
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP,1] //Power On Device 1
    BUTTON_EVENT[dvTP,2] //Power On Device 2
    BUTTON_EVENT[dvTP,3] //Power On Device 3
    {
        PUSH:
        {
    		SWITCH(BUTTON.INPUT.CHANNEL)
            {
                CASE 1:{TIMELINE_CREATE(TL_1,TL_Times[TL_1],LENGTH_STRING(TL_Times[TL_1]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 2:{TIMELINE_CREATE(TL_2,TL_Times[TL_2],LENGTH_STRING(TL_Times[TL_2]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
                CASE 3:{TIMELINE_CREATE(TL_3,TL_Times[TL_3],LENGTH_STRING(TL_Times[TL_3]),TIMELINE_ABSOLUTE,TIMELINE_ONCE)}
            }
        }
    }
    
    TIMELINE_EVENT[TL_1]
    TIMELINE_EVENT[TL_2]
    TIMELINE_EVENT[TL_3]
    {
    	STACK_VAR INTEGER nNumber
    	nNumber = TIMELINE.ID
    	//Do what I need to do
    }
    

    With the code above the timelines never become active.
    That?s because LENGTH_STRING(TL_Times[TL_1]) returns 0 as no length is set since you assigned values by poking individual elements of the array in startup. There are a couple of different ways to fix this.

    1) Remove your DEFINE_START code and change this:
    VOLATILE LONG TL_Times[3][2]
    
    To this:
    VOLATILE LONG TL_Times[3][2] = {
       {65000,70000},
       {35000,40000},
       {10000,15000}
    }
    

    Or:

    2) Leave everything as is and add these three lines to the end of DEFINE_START:
    SET_LENGTH_ARRAY(TL_Times[1],2)
    SET_LENGTH_ARRAY(TL_Times[2],2)
    SET_LENGTH_ARRAY(TL_Times[3],2)
    
  • VOLATILE LONG TL_Times[3][2] = {
       {65000,70000},
       {35000,40000},
       {10000,15000}
    }
    

    Wow, didn't even know you could do that. It did the trick though, thanks.
Sign In or Register to comment.