Topic
  • 11 replies
  • Latest Post - ‏2013-07-16T14:21:27Z by Tony_Goodman
GregM_dxler
GregM_dxler
166 Posts

Pinned topic Detecting Multiple DXL Scripts

‏2013-07-02T16:23:11Z |

Greetings,

I have a dxl script that operates using a dialog box.  Is there a way I can prevent multiple instances of this from occurring?  Here is the scenerio.  Select an object in the DOORS module.  Select the script from a menu selection.  Go back to the DOORS module and select another object.  Select the script from the menu selection.  Now I have two dialog boxes, one from the first object and one from the second object.

Same thing can be done with the dxl window.  Load a dxl script and hit Run.   Go back to the dxl window and hit Run again, now there are two dialog boxes.

Thanks a bunch!

Greg

  • Mike.Scharnow
    Mike.Scharnow
    238 Posts
    ACCEPTED ANSWER

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T17:13:22Z  

    One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

     

    An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

     

    Best regards,
    Mike

  • Tony_Goodman
    Tony_Goodman
    271 Posts
    ACCEPTED ANSWER

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-03T13:36:09Z  

    The functionality you describe is used by the Object Properties dialog in doors.

    As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

    put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

    DB myDialogBoxWithALongName = null

    Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

     

    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {
    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

    Updated on 2013-07-03T13:37:09Z at 2013-07-03T13:37:09Z by Tony_Goodman
  • adevicq
    adevicq
    154 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T16:40:00Z  

    Hi,

    The only method I know is called a "semaphore" (hope it's the same term in English...). It's a kind of token that says: "hey, I'm already busy".

    When you start your code, the first thing to do is to try to take the token. You only free it at the very end.

    Then, when you try to take the token, you check if it's available. If not, it has been taken by another instance. You must stop.

    If it is available, you take it and mark it as not available.

    You can use a file to materialize the token. For example you can create a file called "semaphore" (or whatever you want) in a dedicated folder and you delete it at the end.

    The when you start your code if the file already exists you must stop at once. Else you create your semaphore, do what you have to do and at the end of your process you delete it.

    The only issue is: if your code crashes. In this case the file already exists even if your code is not running. You must have an emergency procedure that resets your semaphore.

    Hope this helps.

    Alain

     

  • Mike.Scharnow
    Mike.Scharnow
    238 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T17:13:22Z  

    One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

     

    An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

     

    Best regards,
    Mike

  • GregM_dxler
    GregM_dxler
    166 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T18:17:35Z  

    One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

     

    An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

     

    Best regards,
    Mike

    Thank you both for replying.  I didn't think about a semiphore, even though I use something similar to remember something.  Unfortunately, the script must be able to work with offsite people who work through citrix and having files on local computers is tricky since they use a different set up.

    I'm not sure how to use a global variable, such as MonitorWidth.  It is not in the dxl reference manual.

    However, this did give me an idea.  I searched through the manual and found the commands setServerMonitor() and serverMonitorIsOn.  According to the manual, setServerMonitor(on) is suppose to activate a Rational DOORS Server Monitor which monitors client server communications.  Although I don't see anything when I set it on (client side).

    I was able to make a small program that would set the monitor on when the dialog box was active and set it off when it was completed and this would prevent a second occurance (pretty slick I might add).  But I don't know if I can reliably use this.  It seemed like it was off initially, but will remember the setting when I close doors and restart.

    Is there some other type global variable I might be able to use?

    Thanks again for your replies!

    Greg

  • GregM_dxler
    GregM_dxler
    166 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T19:39:46Z  

    One alternative to creating a semaphore using a file would be to create one using a top level DXL context variable, like "MonitorWidth" (check https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014702697 for an explanation)

     

    An advantage would be that if the code crashes, you only would have to restart DOORS instead of an emergency procedure.

     

    Best regards,
    Mike

    Did a search to find the entire thread on the massive memory leak.  It can be found at https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014629839

    Turns out it is monitorWidth, not MonitorWidth....

    I was able to read the current value (20) and also to change it.

    Still have the same sort of problem, where I don't know what it will initially be set to.  Possible, I could just use a value of 0 to indicate when a dialog box is already active, since this should not be a normally valid value (maybe -1?) 

    Greg

  • Mike.Scharnow
    Mike.Scharnow
    238 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-02T21:19:09Z  

    Did a search to find the entire thread on the massive memory leak.  It can be found at https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014629839

    Turns out it is monitorWidth, not MonitorWidth....

    I was able to read the current value (20) and also to change it.

    Still have the same sort of problem, where I don't know what it will initially be set to.  Possible, I could just use a value of 0 to indicate when a dialog box is already active, since this should not be a normally valid value (maybe -1?) 

    Greg

    sorry about the typo.

    monitorWidth is set to 20 unless you changed it ( I can't tell you why I know this. Otherwise I'd have to kill you.) :-)

     

    -1 sounds ok

  • Tony_Goodman
    Tony_Goodman
    271 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-03T13:36:09Z  

    The functionality you describe is used by the Object Properties dialog in doors.

    As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

    put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

    DB myDialogBoxWithALongName = null

    Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

     

    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {
    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

    Updated on 2013-07-03T13:37:09Z at 2013-07-03T13:37:09Z by Tony_Goodman
  • GregM_dxler
    GregM_dxler
    166 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-03T14:48:05Z  

    The functionality you describe is used by the Object Properties dialog in doors.

    As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

    put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

    DB myDialogBoxWithALongName = null

    Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

     

    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {
    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

    Hi Tony,

    Thanks for the info.  This is a better solution, as it uses the normal DOORs operation instead of trying to reuse something else.  The only downside is having to have another file to keep track of, and the issue of offsite contractors where much of the drive structure is locked down from editing.

    The only thing I had to remember is to restart DOORS after I added the file to the dxl/config/baseWindowCallbacks folder!

    Greg

  • GregM_dxler
    GregM_dxler
    166 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-10T19:50:44Z  

    The functionality you describe is used by the Object Properties dialog in doors.

    As Mike has mentioned already, this is implemented using a DB variable declared in the top-context. Your code needs to check this variable to see if it is null. If it is null then create the dialog box, otherwise just raise() the existing box.

    put the following line into a dxl file in the DXL/config/baseWindowCallbacks folder. Note the long name for the DB so as not to conflict with other code.

    DB myDialogBoxWithALongName = null

    Your code should look something like this. Remember to explicitly set the DB variable to null when closing the dialog.

     

    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {
    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

    Hi Tony,

    Now I'm stumped again.  I try to update a DBE StatusField in the DB when it is raised and I get the dxl error "unassigned variable(StatusField)".  Do the DBE also need to be defined as a global variable?

    Using your code, I added the declaration DBE StatusField at the beginning,

    After the create DB, I added StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", Initial", 20) to set it.

    and then just after raise(myDialogBoxWithALongName), I added set(StatusField, "Raised")

    I can get the unassigned variable error to not be displayed if I redefine StatusField again after the raise command, but the field doesn't get updated.

    Where this would be nice is if say, I have the dialog box up, then I go to a different object and then try to relaunch the script it instead, raises the original dialog box and update it to the new object selected.

    Any help would be much appreciated,

    Thanks,
    Greg

  • Tony_Goodman
    Tony_Goodman
    271 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-12T09:47:22Z  

    Hi Tony,

    Now I'm stumped again.  I try to update a DBE StatusField in the DB when it is raised and I get the dxl error "unassigned variable(StatusField)".  Do the DBE also need to be defined as a global variable?

    Using your code, I added the declaration DBE StatusField at the beginning,

    After the create DB, I added StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", Initial", 20) to set it.

    and then just after raise(myDialogBoxWithALongName), I added set(StatusField, "Raised")

    I can get the unassigned variable error to not be displayed if I redefine StatusField again after the raise command, but the field doesn't get updated.

    Where this would be nice is if say, I have the dialog box up, then I go to a different object and then try to relaunch the script it instead, raises the original dialog box and update it to the new object selected.

    Any help would be much appreciated,

    Thanks,
    Greg

    The reason this doesn't work is that if myDialogBoxWithALongName already exists, it is not created but simply raised, thus returning control to the original instance of the script that is already running. The new instance of the script then terminates as raise() was the last statement.

    So, the logic is

    If the dialog already exists then raise() it and end.

    If the dialog doesn't exist then create it as normal.

    The following example works fine.

    DBE StatusField = null

     
    void doSetStatus(DB db)
    {
    set(StatusField, "Raised")
    }
     
    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {

        // just make this one call and end

    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", "Initial", 20)
     
    apply(myDialogBoxWithALongName, "Set Status", doSetStatus)
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

     

    Updated on 2013-07-12T09:55:24Z at 2013-07-12T09:55:24Z by Tony_Goodman
  • GregM_dxler
    GregM_dxler
    166 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-15T13:09:19Z  

    The reason this doesn't work is that if myDialogBoxWithALongName already exists, it is not created but simply raised, thus returning control to the original instance of the script that is already running. The new instance of the script then terminates as raise() was the last statement.

    So, the logic is

    If the dialog already exists then raise() it and end.

    If the dialog doesn't exist then create it as normal.

    The following example works fine.

    DBE StatusField = null

     
    void doSetStatus(DB db)
    {
    set(StatusField, "Raised")
    }
     
    void doClose(DB db)
    {
    destroy(myDialogBoxWithALongName)
    myDialogBoxWithALongName = null
    }
     
    if (!null myDialogBoxWithALongName)
    {

        // just make this one call and end

    raise(myDialogBoxWithALongName)
    }
    else
    {
    myDialogBoxWithALongName = create("My Dialog With a Long Name")
     
    StatusField = field(myDialogBoxWithALongName, "Dialog Box Status", "Initial", 20)
     
    apply(myDialogBoxWithALongName, "Set Status", doSetStatus)
    close(myDialogBoxWithALongName, true, doClose)
    realize(myDialogBoxWithALongName)
    show(myDialogBoxWithALongName)
    }

     

     

    Hi Tony,

    Thanks for the additional input.  I was thinking that since the dialog box was global, then all the elements in the dialog box would also be global.  I was able to get it to work by including the DBE declarations in with the DB declaration.  Then to help any programmer to understand the script, I commented out the "normal" declarations in the script and added a note that they are declared in the xxxdeclarations.dxl file in \DXL/config/baseWindowCallbacks folder.

    Greg 

  • Tony_Goodman
    Tony_Goodman
    271 Posts

    Re: Detecting Multiple DXL Scripts

    ‏2013-07-16T14:21:27Z  

    Hi Tony,

    Thanks for the additional input.  I was thinking that since the dialog box was global, then all the elements in the dialog box would also be global.  I was able to get it to work by including the DBE declarations in with the DB declaration.  Then to help any programmer to understand the script, I commented out the "normal" declarations in the script and added a note that they are declared in the xxxdeclarations.dxl file in \DXL/config/baseWindowCallbacks folder.

    Greg 

    I would recommend keeping the number of global variables to a minimum. Apart from your example above, I cannot envisage a situation where you would need global DBEs.