Home AMX User Forum AMX General Discussion

Multiple instances of same timeline ID?

Hi all,

In our company we have a module template that we use when we want to create a module for a new device. We used to have the button feedback in the define_program, so in the last few months we replaced it for a timeline_event.

So now, all our modules have inside a timeline with the same ID (always 1), so we can have in a single project 4 or 5 modules made by our own running timelines with the same ID.

Is that a problem? I've just read in a P2 Evaluation Sheet that it is considered a bad practice, why? do the timeline events ID have a global scope and it doesn't matter if they are inside a module? I've never seen a problem or any strange behaviour since we program that way, so I don't understand that statement from the exam reviewer (and I feel bad because I tell all my students to do it in that way:( ) .

What do you think?

Comments

  • ericmedleyericmedley Posts: 4,177
    that's a good question actually. I always thought that what happened in a module stayed in a module. But, a Timeline_Event is one of those things that kinda bends my brains a bit. Is a timeline ID a "thing" If I create a device inside a module (which I never do by the way) that device shows up in the outside world and I can do stuff with it, watch it, even create a separte event outside the module and the device will trigger events in obth worlds.

    I do know that constants and variables live only in the module. You 'can' leave the source code in and wathc them in debug but they don't work outside the module.

    I will say that I came up with my own scheme to keep my timelines unique even inside modules but this doesn't cover AMX created modules where I have no idea what's going on.

    I suppose one could test this by creating a timeline in a module, then creating a separtate timeline event of the same ID outside it and watcching it for activity. Even better yet, you could run a TIMELINE_ACTIVE(my_Moudle_Timeline__ID) outside the module during its running to see if what it kicks back.
  • GregGGregG Posts: 251
    I'm certain the timelines inside a module have their own scope and do not influence or affect the timeline constants chosen inside the main code.
  • ericmedleyericmedley Posts: 4,177
    Yep - confirmed. here's the test code:
    PROGRAM_NAME='proc_01'
    
    DEFINE_DEVICE
    
    dv_device_01    =    5001:01:01
    
    vdv_device_01 = 33001:01:01
    
    DEFINE_CONSTANT
    
    
    long My_Outside_TL=11;
    
    
    DEFINE_MODULE 'timeline_module' module_01(vdv_device_01,dv_device_01)
    
    DEFINE_EVENT
    
    timeline_event[My_Outside_TL]{
        send_string 0,'Timeline Outside Fired'
        }
    
    

    and inside module
    MODULE_NAME='timeline_module' ( dev vdv_myDevice, dev dv_device)
    
    DEFINE_CONSTANT
    
    long My_iNside_TL=11;
    
    DEFINE_VARIABLE
    
    volatile long  My_iNside_TL_times[]={1000}
    
    
    define_event
    
    data_event[vdv_myDevice]{
        online:{
            wait 200{
                timeline_create(My_iNside_TL,
                                    My_iNside_TL_times,
                                    length_array(My_iNside_TL_times),
                                    timeline_absolute,
                                    timeline_repeat )
        send_string 0,'timeline has started.'
                } // wait 200
            }
        }
    
    timeline_event[My_iNside_TL]{
        send_string 0,'Timeline Inside Fired'
        }
    

    result in terminal:
    (0000041983) timeline has started.
    (0000042977) Timeline Inside Fired
    (0000043971) Timeline Inside Fired
    (0000044965) Timeline Inside Fired

  • ericmedleyericmedley Posts: 4,177
    And here's where to me the rules get bent a bit. When I add channel events and button events inside and out those things do traverse the barrier of the module.

    (0000038282) timeline has started.
    (0000039276) Timeline Inside Fired
    (0000039278) Channel 12 Outside Fired
    (0000039278) Channel 12 Inside Fired
    (0000039279) Button 13 Inside Pushedd
    (0000039279) Button 13 Inside Pushedd
    (0000040270) Timeline Inside Fired
    (0000040272) Channel 12 Outside Fired
    (0000040273) Channel 12 Inside Fired
    (0000040273) Button 13 Inside Pushedd
    (0000040274) Button 13 Inside Pushedd
    Don't get me wrong - I understand how it works and it doesn't confuse me. It's just one of those things where the rules don't seem to me to be followed consistently. In my mind an event is a "thing that happened" and it should traverse the scope of the system. Other events do.

    The other little one that's always not quite followed what my pea brain senses as the logic is how button/channel feedback and button pushes are not the same thing and one doesn't cause the other. but levels do if the level feedback being sent is an active fader. sending a level (which is supposed to be feedback) to an active fader produces an incoming level event.

    There are lots of these kinds of things in netlinx.
  • AvargasAvargas Posts: 57
    Thank you very much guys, It's clear now.

    I also tested it and it works perfectly with all functions (pause, restart, kill, etc.)

    Here the code:

    OUTSIDE:
    PROGRAM_NAME='Main'
    
    DEFINE_DEVICE
    
        vdvTimelines = 33001:1:0
        
    DEFINE_CONSTANT
    
        volatile long lTimelineID = 1
    
    DEFINE_VARIABLE
    
        volatile long lTimes[1] = {200}
    
        volatile integer anTimelineOptions[] = {11, // Create
                                                             12, // Pause
                                                             13, // Restart
                                                             14} // Kill
    
    DEFINE_START
    
        define_module 'TimelineModule' TLModule(vdvTimelines)
    
    DEFINE_EVENT
    
        channel_event[vdvTimelines,anTimelineOptions]
        {
            on:
            {
                stack_var integer nOption
                nOption = get_last(anTimelineOptions)
                switch(nOption)
                {
                    case 1:
                    {
                        send_string 0,'OUTSIDE TL: We create the timeline'
                        timeline_create(lTimelineID,lTimes,1,timeline_relative,timeline_repeat)
                    }
                    case 2:
                    {
                        send_string 0,'OUTSIDE TL: We pause the timeline'
                        timeline_pause(lTimelineID)
                    }
                    case 3:
                    {
                        send_string 0,'OUTSIDE TL: We pause the timeline'
                        timeline_restart(lTimelineID)
                    }
                    case 4:
                    {
                        send_string 0,'OUTSIDE TL: We kill the timeline'
                        timeline_kill(lTimelineID)
                    }
                }
            }
        }
    
        timeline_event[lTimelineID]
        {
            send_string 0,'OUTSIDE: enters into the timeline'
        }
    

    INSIDE:
    MODULE_NAME='TimelineModule' (dev vdvTimelines)
    
    DEFINE_CONSTANT
    
        volatile long lTimelineID = 1
    
    DEFINE_VARIABLE
    
        volatile long lTimes[] = {200}
    
        volatile integer anTimelineOptions[] = {21, // Create
                                                             22, // Pause
                                                             23, // Restart
                                                             24} // Kill
    
    DEFINE_EVENT
    
        channel_event[vdvTimelines,anTimelineOptions]
        {
            on:
            {
                stack_var integer nOption
                nOption = get_last(anTimelineOptions)
                switch(nOption)
                {
                    case 1:
                    {
                        send_string 0,'INSIDE TL: We create the timeline'
                        timeline_create(lTimelineID,lTimes,1,timeline_relative,timeline_repeat)
                    }
                    case 2:
                    {
                        send_string 0,'INSIDE TL: We pause the timeline'
                        timeline_pause(lTimelineID)
                    }
                    case 3:
                    {
                        send_string 0,'INSIDE TL: We pause the timeline'
                        timeline_restart(lTimelineID)
                    }
                    case 4:
                    {
                        send_string 0,'INSIDE TL: We kill the timeline'
                        timeline_kill(lTimelineID)
                    }
                }
            }
        }
    
        timeline_event[lTimelineID]
        {
            send_string 0,'INSIDE: enters into the timeline'
        }
    
  • DHawthorneDHawthorne Posts: 4,584
    My understanding of modules is that they create a copy of all the constants and variables defined within them, and tag them with an instance ID so they are all different constants and variables than what is named the same either in other modules or the main program. But when it comes to devices, they create a virtual device that is combined with the real one, so it's possible to get overlap there. That last conclusion I came to because I had a module that was very heavy on level events and feedback (trying to do something slicker than it needed to be, to be honest), and I noticed all the levels above 8 didn't work even though I was passing a real device to the module. But when I added the SET_VIRTUAL_LEVEL_COUNT statement, all was fine. Panels in the main program don't need it. So I think some of the oddities about event and devices come from that - it is creating a virtual device and linking it to the real one.
Sign In or Register to comment.