Valid Module handle

Need to figure out how to tell if an old "Module" handle is still valid.

So I have a global "Module" handle mCurr, get its objects and store them in a searchable Skip list, then "show" the user a dialog. When the user interacts with the dialog I need to know if my mCurr handle is any good, and by inference whether my Skip list of Objects is any good.

The user may have closed the module while the dialog was displayed which I could tell using "open(Name)", but I think I have a problem when he closes and opens it again. mCurr is not null but its corrupted, the skip list is valid and contains non-null Object handles, but they are likewise corrupted.

I wonder if this is always valid:

bool   GoodModuleHandle(Module in_mod)
{      // Is the module handle still good?
    if (null in_mod) return(false)
    noError()
    string NameFull = fullName(in_mod)
    ModName_ mn = null
    mn = module(NameFull)
    string ErrMess= lastError()
 
    if (!null ErrMess or null mn)//
    then return(false)
    else return(true)
}   // end GoodModuleHandle()


There are reasons I don't want to "block" the dialog which would prevent it being closed. Am working on a suite of functions featuring a dynamic pre-close-module that can alert the code when the module closes, but its difficult to communicate the "Module" handle variable, but I'm looking closer at Aliasing it.

 

 

  • Louie

 

 


llandale - Thu Jun 30 17:03:36 EDT 2011

Re: Valid Module handle
Mathias Mamsch - Thu Jun 30 19:31:45 EDT 2011

I guess you would need to use a pre close trigger ... You can use the 'version' function to get the moduleversion to be closed and then 'data' to get the module handle:
 

Module m = current 
 
DB x = centered "My GUI"
 
DBE lab = label (x, "The module is fine!") 
 
 
bool myClose(Trigger T) {
     ModuleVersion mv = version T
     Module mod = data mv
     if (mod == m) set(lab, "Module toast!") 
     return true 
}
 
trigger (module, close(), 10, myClose) 
 
show x

 


Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Valid Module handle
llandale - Sun Jul 03 02:02:31 EDT 2011

Mathias Mamsch - Thu Jun 30 19:31:45 EDT 2011

I guess you would need to use a pre close trigger ... You can use the 'version' function to get the moduleversion to be closed and then 'data' to get the module handle:
 

Module m = current 
 
DB x = centered "My GUI"
 
DBE lab = label (x, "The module is fine!") 
 
 
bool myClose(Trigger T) {
     ModuleVersion mv = version T
     Module mod = data mv
     if (mod == m) set(lab, "Module toast!") 
     return true 
}
 
trigger (module, close(), 10, myClose) 
 
show x

 


Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

I think Module mod = module(trg) works also.

The issue is what to do with the Main program "Module" handle. If I can somehow corrupt it inside the generic trigger I will, but it looks like the trigger will be putting the name of the module in some sort of Closed Modules skip list. Main programs, when they are activated in a callback and need to know if their Module handle is still valid, can check the Closed Skip for their module name. If found, remove it from that list, re-open the module, and likely re-build the internal skips of that module, such as Object handles.

Scary. But I've got some massive scripts that cannot afford to keep re-opening modules and re-storing Object handles.

  • Louie

Re: Valid Module handle
Mathias Mamsch - Sun Jul 03 09:49:29 EDT 2011

llandale - Sun Jul 03 02:02:31 EDT 2011
I think Module mod = module(trg) works also.

The issue is what to do with the Main program "Module" handle. If I can somehow corrupt it inside the generic trigger I will, but it looks like the trigger will be putting the name of the module in some sort of Closed Modules skip list. Main programs, when they are activated in a callback and need to know if their Module handle is still valid, can check the Closed Skip for their module name. If found, remove it from that list, re-open the module, and likely re-build the internal skips of that module, such as Object handles.

Scary. But I've got some massive scripts that cannot afford to keep re-opening modules and re-storing Object handles.

  • Louie

Yeah that is problematic. I tend to not store module and object handles, just ModName_ and ModuleVersions on interactive GUIs for exactly this reason. Instead of objects I always store absolute numbers and use the object function to quickly locate an object and if this fails I try with the for obj in entire module do locate it in case filters or something hid the object. To aquire a module handle I use the data/module function to see If the module is open and open it on demand. If I run into speed problems I can always insert a cache that I can activate and deactivate in code parts where I can sure be sure that the user cannot close a module.

Another idea is to just close the dialog, if the user closes a module. This way the user will learn that he better keeps the modules open. I also was very afraid of the thought of having to keep track of open module handles. But I would like to see, if you get this to work in a stable manner.

Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: Valid Module handle
llandale - Sun Jul 03 15:36:17 EDT 2011

Mathias Mamsch - Sun Jul 03 09:49:29 EDT 2011
Yeah that is problematic. I tend to not store module and object handles, just ModName_ and ModuleVersions on interactive GUIs for exactly this reason. Instead of objects I always store absolute numbers and use the object function to quickly locate an object and if this fails I try with the for obj in entire module do locate it in case filters or something hid the object. To aquire a module handle I use the data/module function to see If the module is open and open it on demand. If I run into speed problems I can always insert a cache that I can activate and deactivate in code parts where I can sure be sure that the user cannot close a module.

Another idea is to just close the dialog, if the user closes a module. This way the user will learn that he better keeps the modules open. I also was very afraid of the thought of having to keep track of open module handles. But I would like to see, if you get this to work in a stable manner.

Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Yes I already have the notion of attaching a pre-close-module trigger for all my dialogs that are associated with a module, to close the dialog. I'm into much larger things, in this case a console associated with one module; one of the functions allows selecting and linking to another. I don't want to close the console when that other module closes, but I do need to know.

Kind of set in my ways here and it will be tough to switch from a "Module" centric approach to a "ModVers_" centric one, especially since lost of commands require a "Module".

But are you saying the "ModVer_" handle remains valid even if the module closes? I could then get the "Module" handle in the callbacks and go from there.

  • Louie

Re: Valid Module handle
Mathias Mamsch - Sun Jul 03 17:18:37 EDT 2011

llandale - Sun Jul 03 15:36:17 EDT 2011
Yes I already have the notion of attaching a pre-close-module trigger for all my dialogs that are associated with a module, to close the dialog. I'm into much larger things, in this case a console associated with one module; one of the functions allows selecting and linking to another. I don't want to close the console when that other module closes, but I do need to know.

Kind of set in my ways here and it will be tough to switch from a "Module" centric approach to a "ModVers_" centric one, especially since lost of commands require a "Module".

But are you saying the "ModVer_" handle remains valid even if the module closes? I could then get the "Module" handle in the callbacks and go from there.

  • Louie

Yes. You can obviously create a ModuleVersion or a ModName_ for a module that is not opened. So the opened/close state does not matter. And you can simply get a ModuleVersion from a Module by "moduleVersion modVar", so whenever I store handles I always store the ModuleVersion and then receive the moduleHandle by:

Module getModule (ModuleVersion modVer) {
  Module m = data modVer
  if (null m) m = load (modVer, true) 
}
 
Object byAbsNo (Module m, int iAbsNo) {
  Object o = object (iAbsNo, m) 
  if (null o) { 
    Object oSearch; 
    for oSearch in entire m do { 
         int nr = o."Absolute Number"; 
         if (nr == iAbsNo) { o = oSearch; break }
    }
  }
  return o
}

 


I think you might be able to just replace the code there you store handles and receive handles from the skip lists by storing and receiving ModuleVersions, Absolute Numbers instead, and "cast" them using something like the above functions. Then you can see what speed you will get ... Then you might introduce a cache of handles, but you can do so locally in the above functions, and then activate it and deactivate it explicitly in the problematic code parts where you can be sure that the user cannot close the module.

This technique is also useful if you store for example the modules that you opened so your GUI will close them (after you GUI quits), but in the meantime the user closes one of the modules, breaking your cleanup code. Instead of deciding to leave the modules open, just store ModuleVersions and try to receive a handle to an open module with "data", if you get none the module is already closed, so you can skip the module.

Hope this helps, Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Valid Module handle
llandale - Sun Jul 03 18:10:31 EDT 2011

Mathias Mamsch - Sun Jul 03 17:18:37 EDT 2011

Yes. You can obviously create a ModuleVersion or a ModName_ for a module that is not opened. So the opened/close state does not matter. And you can simply get a ModuleVersion from a Module by "moduleVersion modVar", so whenever I store handles I always store the ModuleVersion and then receive the moduleHandle by:

Module getModule (ModuleVersion modVer) {
  Module m = data modVer
  if (null m) m = load (modVer, true) 
}
 
Object byAbsNo (Module m, int iAbsNo) {
  Object o = object (iAbsNo, m) 
  if (null o) { 
    Object oSearch; 
    for oSearch in entire m do { 
         int nr = o."Absolute Number"; 
         if (nr == iAbsNo) { o = oSearch; break }
    }
  }
  return o
}

 


I think you might be able to just replace the code there you store handles and receive handles from the skip lists by storing and receiving ModuleVersions, Absolute Numbers instead, and "cast" them using something like the above functions. Then you can see what speed you will get ... Then you might introduce a cache of handles, but you can do so locally in the above functions, and then activate it and deactivate it explicitly in the problematic code parts where you can be sure that the user cannot close the module.

This technique is also useful if you store for example the modules that you opened so your GUI will close them (after you GUI quits), but in the meantime the user closes one of the modules, breaking your cleanup code. Instead of deciding to leave the modules open, just store ModuleVersions and try to receive a handle to an open module with "data", if you get none the module is already closed, so you can skip the module.

Hope this helps, Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

May be a long time ago but I determined the various object searches were hopelessly slow; storing in Skip was far faster. I also need to search for things other than absolute numbers. If so, then I still need to determine when my ModuleVersion has been closed and re-opened, thus corrupting the stored 'Object' handles.

So far I see a couple variants of dynamic-pre-close triggers.
o It stores the ModVer in Skip "skpClosedModules". When the main program cares about the module, it checks that skip and if found, removes it from the list, deletes and re-creates its needed structures, and in any event re-deploys the trigger.
o Trigger does nothing. When the main program cares, it looks for the trigger. If not found it knows the module was closed and re-opened.

Doubt its worth playing with the notion of doing something else to the module and checking that when we care, perhaps selecting a specific set of objects or inserting some weird column.

Back to Mathias approach: If I figure to search for Objects with a specific attribute value, then create a skip list with that value and the corresponding AbsNo. Lookup the AbsNo in that skip, then use the code below.

  • Louie

Re: Valid Module handle
llandale - Sun Jul 03 18:12:25 EDT 2011

llandale - Sun Jul 03 18:10:31 EDT 2011
May be a long time ago but I determined the various object searches were hopelessly slow; storing in Skip was far faster. I also need to search for things other than absolute numbers. If so, then I still need to determine when my ModuleVersion has been closed and re-opened, thus corrupting the stored 'Object' handles.

So far I see a couple variants of dynamic-pre-close triggers.
o It stores the ModVer in Skip "skpClosedModules". When the main program cares about the module, it checks that skip and if found, removes it from the list, deletes and re-creates its needed structures, and in any event re-deploys the trigger.
o Trigger does nothing. When the main program cares, it looks for the trigger. If not found it knows the module was closed and re-opened.

Doubt its worth playing with the notion of doing something else to the module and checking that when we care, perhaps selecting a specific set of objects or inserting some weird column.

Back to Mathias approach: If I figure to search for Objects with a specific attribute value, then create a skip list with that value and the corresponding AbsNo. Lookup the AbsNo in that skip, then use the code below.

  • Louie

<3> Dynamic-Pre-Close Trigger prevents the module from closing.

I must say that we can defeat this approach by turning the running of triggers off. The "Trigger does nothing" approach is starting to look good.

Re: Valid Module handle
jsarkic - Mon Jul 04 12:41:37 EDT 2011

Try
 

bool GoodModuleHandle(Module in_mod)
{    // Is the module handle still good?
        Module openedModule
 
        for openedModule in database do
                if (in_mod == openedModule)
                        return true
 
        return false
}     // end GoodModuleHandle()

Re: Valid Module handle
Mathias Mamsch - Mon Jul 04 14:00:16 EDT 2011

llandale - Sun Jul 03 18:12:25 EDT 2011
<3> Dynamic-Pre-Close Trigger prevents the module from closing.

I must say that we can defeat this approach by turning the running of triggers off. The "Trigger does nothing" approach is starting to look good.

A good idea. Only leaves the question, how you will differentiate between your trigger and another dynamic trigger that has been installed? To change a name of a dynamic trigger you could use the following code:
 

// This function will set the trigger name ...
void setTriggerName (Trigger T, string newName) {
        int *ptr = addr_ T; ptr += 4; *ptr = (addr_ newName) int
}

 


In addition you should look out for the following:

 

 

  • I noticed a bug in the for Trigger in module loop ... As soon as you close the current version of a module the loop will find no triggers in the module, even though they are there. As soon as you reopen the current version the loop will find the triggers again. Very strange ... Just in case you deal with baselines ...
  • Sometimes the DXL interpreter will ignore a 'return' while in the for Trigger in Module loop ... Even stranger bug ...
  • When you install dynamic triggers then the memory allocated by your DXL will stay alive until the module closes. If your program caches a lot of data make sure you explicitly free all your stuff.


Maybe this helps, Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Valid Module handle
Mathias Mamsch - Mon Jul 04 14:13:02 EDT 2011

jsarkic - Mon Jul 04 12:41:37 EDT 2011

Try
 

bool GoodModuleHandle(Module in_mod)
{    // Is the module handle still good?
        Module openedModule
 
        for openedModule in database do
                if (in_mod == openedModule)
                        return true
 
        return false
}     // end GoodModuleHandle()

This code will not work reliably. When the module handle is reused when you close and open your module, your object handles will still be toast. Try running the following code a couple of times. Eventuelly you will get a crash! Regards, Mathias
 

bool GoodModuleHandle(Module in_mod)
{    // Is the module handle still good?
        Module openedModule
 
        for openedModule in database do
                if (in_mod == openedModule)
                        return true
 
        return false
}     // end GoodModuleHandle()
 
Item I = item "/Playground/Speedtest"
 
Object o = null
 
Module mOrig = read(fullName I, false)  
Module     m = mOrig
 
o = object (1, mOrig) 
 
for i in 0:20 do {
   print "mOrig still good??" 
   if (GoodModuleHandle mOrig) {
      print "YES! So our object should be fine too: " 
      print (number o) "\n"
   } else {
      print "Oh noes!\n"
   }
   // close and reopen the module 
   close m; m = read (fullName I, false) 
}

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

 

Re: Valid Module handle
jsarkic - Tue Jul 05 12:02:00 EDT 2011

Mathias Mamsch - Mon Jul 04 14:13:02 EDT 2011

This code will not work reliably. When the module handle is reused when you close and open your module, your object handles will still be toast. Try running the following code a couple of times. Eventuelly you will get a crash! Regards, Mathias
 

bool GoodModuleHandle(Module in_mod)
{    // Is the module handle still good?
        Module openedModule
 
        for openedModule in database do
                if (in_mod == openedModule)
                        return true
 
        return false
}     // end GoodModuleHandle()
 
Item I = item "/Playground/Speedtest"
 
Object o = null
 
Module mOrig = read(fullName I, false)  
Module     m = mOrig
 
o = object (1, mOrig) 
 
for i in 0:20 do {
   print "mOrig still good??" 
   if (GoodModuleHandle mOrig) {
      print "YES! So our object should be fine too: " 
      print (number o) "\n"
   } else {
      print "Oh noes!\n"
   }
   // close and reopen the module 
   close m; m = read (fullName I, false) 
}

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

 

Thanks Mathias.

So much for thinking out loud...should have run the code.

It seems once you close a module the original handle is no longer valid, and neither are the Objects. Rather than store the objects and the module handle, I would prefer to store the object absolute numbers and the module unique ID.
 

Item it = item "/Playground/Speedtest"
Module m = read(fullName it, false)  
 
Skip sk = create()
put(sk, 1, uniqueID(m))
put(sk, 2, uniqueID(m))
put(sk, 3, uniqueID(m))
 
bool moduleIsOpen(string mID)
{
    Module openedModule
 
        for openedModule in database do
                if (uniqueID(openedModule) == mID)
                {
                        current = openedModule // Can make sure the module is currrent at this point
                        return true
                }
 
        return false
}     // end moduleIsOpen()
 
for i in 0 : 20 do
{
        print "Is Module open??\n" 
        
        string mID
 
        for mID in sk do
        {
                if (moduleIsOpen(mID))
                {
                        Object o = object ((int key(sk)))  // Use the object absolute number to get a valid object
                        
                        if (!null o)
                        {
                                print "\tModule open and Object is valid: " 
                                print (number o) "\n"
                        }
                }
                else
                {
                          print "Oh noes!\n"
                }
        }
        
        // Close and reopen the module 
        
        close m; m = read (fullName it, false)
}
 
if (!null m)  close m
if (!null sk) delete sk

 


This is a simple solution that does not need the use of triggers.

 

Re: Valid Module handle
jsarkic - Tue Jul 05 13:02:07 EDT 2011

jsarkic - Tue Jul 05 12:02:00 EDT 2011

Thanks Mathias.

So much for thinking out loud...should have run the code.

It seems once you close a module the original handle is no longer valid, and neither are the Objects. Rather than store the objects and the module handle, I would prefer to store the object absolute numbers and the module unique ID.
 

Item it = item "/Playground/Speedtest"
Module m = read(fullName it, false)  
 
Skip sk = create()
put(sk, 1, uniqueID(m))
put(sk, 2, uniqueID(m))
put(sk, 3, uniqueID(m))
 
bool moduleIsOpen(string mID)
{
    Module openedModule
 
        for openedModule in database do
                if (uniqueID(openedModule) == mID)
                {
                        current = openedModule // Can make sure the module is currrent at this point
                        return true
                }
 
        return false
}     // end moduleIsOpen()
 
for i in 0 : 20 do
{
        print "Is Module open??\n" 
        
        string mID
 
        for mID in sk do
        {
                if (moduleIsOpen(mID))
                {
                        Object o = object ((int key(sk)))  // Use the object absolute number to get a valid object
                        
                        if (!null o)
                        {
                                print "\tModule open and Object is valid: " 
                                print (number o) "\n"
                        }
                }
                else
                {
                          print "Oh noes!\n"
                }
        }
        
        // Close and reopen the module 
        
        close m; m = read (fullName it, false)
}
 
if (!null m)  close m
if (!null sk) delete sk

 


This is a simple solution that does not need the use of triggers.

 

Using this approach, you can ensure that the source module is accessible whenever you need to access the objects.
 

Item it = item "/Playground/Speedtest"
Module m = read(fullName it, false)  
 
Skip sk = create()
put(sk, 1, uniqueID(m))
put(sk, 2, uniqueID(m))
put(sk, 3, uniqueID(m))
 
bool moduleIsOpen(string mID)
{
    Module openedModule
 
        for openedModule in database do
                if (uniqueID(openedModule) == mID)
                {
                        current = openedModule // Can make sure the module is currrent at this point
                        return true
                }
 
        return false
}     // end moduleIsOpen()
 
void processObject(int absNo)
{
        Object o = object(absNo)
                        
        if (!null o)
        {
                print "\tModule open and Object is valid: " 
                print (number o) "\n"
        }
}
 
print "Is Module open??\n" 
 
string mID
 
for mID in sk do
{
        if (!moduleIsOpen(mID)) // Open the module if it is closed
                m = read(fullName itemFromID(mID), false)  
 
        if (!null current Module)               
                processObject((int key(sk)))
                
        if (!null m) close m
}
 
if (!null sk) delete sk

Re: Valid Module handle
Mathias Mamsch - Tue Jul 05 15:48:49 EDT 2011

jsarkic - Tue Jul 05 13:02:07 EDT 2011

Using this approach, you can ensure that the source module is accessible whenever you need to access the objects.
 

Item it = item "/Playground/Speedtest"
Module m = read(fullName it, false)  
 
Skip sk = create()
put(sk, 1, uniqueID(m))
put(sk, 2, uniqueID(m))
put(sk, 3, uniqueID(m))
 
bool moduleIsOpen(string mID)
{
    Module openedModule
 
        for openedModule in database do
                if (uniqueID(openedModule) == mID)
                {
                        current = openedModule // Can make sure the module is currrent at this point
                        return true
                }
 
        return false
}     // end moduleIsOpen()
 
void processObject(int absNo)
{
        Object o = object(absNo)
                        
        if (!null o)
        {
                print "\tModule open and Object is valid: " 
                print (number o) "\n"
        }
}
 
print "Is Module open??\n" 
 
string mID
 
for mID in sk do
{
        if (!moduleIsOpen(mID)) // Open the module if it is closed
                m = read(fullName itemFromID(mID), false)  
 
        if (!null current Module)               
                processObject((int key(sk)))
                
        if (!null m) close m
}
 
if (!null sk) delete sk

If you now replace the module ID by the ModuleVersion (think about the user opening a baseline of the module which has the same ID!), then you will have about the code I posted above ;-) Additionally if 'object' does not find the object (because it is filtered or it is a table object or something) you should for safety reasons search for the object with 'for o in entire Module do ...'. Regards, Mathias


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

Re: Valid Module handle
llandale - Tue Jul 05 16:56:31 EDT 2011

Mathias Mamsch - Mon Jul 04 14:00:16 EDT 2011

A good idea. Only leaves the question, how you will differentiate between your trigger and another dynamic trigger that has been installed? To change a name of a dynamic trigger you could use the following code:
 

// This function will set the trigger name ...
void setTriggerName (Trigger T, string newName) {
        int *ptr = addr_ T; ptr += 4; *ptr = (addr_ newName) int
}

 


In addition you should look out for the following:

 

 

  • I noticed a bug in the for Trigger in module loop ... As soon as you close the current version of a module the loop will find no triggers in the module, even though they are there. As soon as you reopen the current version the loop will find the triggers again. Very strange ... Just in case you deal with baselines ...
  • Sometimes the DXL interpreter will ignore a 'return' while in the for Trigger in Module loop ... Even stranger bug ...
  • When you install dynamic triggers then the memory allocated by your DXL will stay alive until the module closes. If your program caches a lot of data make sure you explicitly free all your stuff.


Maybe this helps, Regards, Mathias

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Seems to work. Forgive ignorance, please explain the "int" part of this line:
... *ptr = (addr_ in_NameTrig) int
That is the same as this, yes?
... *ptr = (int addr_ in_NameTrig)
I see this gives diagnostic errors:
... *ptr = (addr_ in_NameTrig)
No doubt it cannot deduce it wants the "int" form of "addr_" when storing into an integer variable.

I was figuring to use a combination of the supplied name, "Dynamic 3" and the priority, to determine when I've found the trigger. This makes is cleaner, thanks.

I notice, however, changing the name of the Dyanmic trigger, from perhaps "dynamic 3" does NOT change the name (of course) of the corresponding Built In trigger "B:specific close for dynamic 3 5". I cannot think of a reason that I care about that now, but I wonder if in the future I will.

Here's the code I'll use:

//************************************
void    fTrigger_SetName(Trigger in_trg, string in_NameTrig) 
{     // Change the name of the trigger to have the specified Name.
        // Works for Stored/Dynamic/BuiltIn triggers.
        //      Simple tests found no problems changing the name of Dynamic nor BuiltIn triggers,
        //      although more testing should be done.
        // You CAN change the name to null but that is ill recomended.
        // Orignal Posted Mathias Mamsch 2011-Jul-04 here:
        //      http://www.ibm.com/developerworks/forums/thread.jspa?threadID=376273&tstart=0
 
        if (null in_trg)                        return
        int     *ptr = addr_(in_trg)
        ptr += 4
        *ptr = (int addr_ in_NameTrig)
}     // end fTrigger_SetName()

Re: Valid Module handle
Mathias Mamsch - Tue Jul 05 18:00:16 EDT 2011

llandale - Tue Jul 05 16:56:31 EDT 2011

Seems to work. Forgive ignorance, please explain the "int" part of this line:
... *ptr = (addr_ in_NameTrig) int
That is the same as this, yes?
... *ptr = (int addr_ in_NameTrig)
I see this gives diagnostic errors:
... *ptr = (addr_ in_NameTrig)
No doubt it cannot deduce it wants the "int" form of "addr_" when storing into an integer variable.

I was figuring to use a combination of the supplied name, "Dynamic 3" and the priority, to determine when I've found the trigger. This makes is cleaner, thanks.

I notice, however, changing the name of the Dyanmic trigger, from perhaps "dynamic 3" does NOT change the name (of course) of the corresponding Built In trigger "B:specific close for dynamic 3 5". I cannot think of a reason that I care about that now, but I wonder if in the future I will.

Here's the code I'll use:

//************************************
void    fTrigger_SetName(Trigger in_trg, string in_NameTrig) 
{     // Change the name of the trigger to have the specified Name.
        // Works for Stored/Dynamic/BuiltIn triggers.
        //      Simple tests found no problems changing the name of Dynamic nor BuiltIn triggers,
        //      although more testing should be done.
        // You CAN change the name to null but that is ill recomended.
        // Orignal Posted Mathias Mamsch 2011-Jul-04 here:
        //      http://www.ibm.com/developerworks/forums/thread.jspa?threadID=376273&tstart=0
 
        if (null in_trg)                        return
        int     *ptr = addr_(in_trg)
        ptr += 4
        *ptr = (int addr_ in_NameTrig)
}     // end fTrigger_SetName()

All DOORS Types (except of int, bool, date and real) are pointers to a structure (a block of memory that stores the properties of the objects). So if you do
 

string s = "hallo"

 


then DXL will put a pointer on the stack, that contains the address of the constant 'Hallo' that the DXL interpreter put somewhere into memory when interpreting the DXL. The addr_ function is really only a type conversion function that allows you to interpret a variable as another type. Example:

 

 

 

bool x = true 
print ((addr_ x) int) "\n"  // interpret 'true' as an integer
x = false
print ((addr_ x) int) "\n"  // interpret 'false' as an integer



So what the line of code does: It will interpret the Trigger variable as an integer which will give the memory address of the trigger property struct. I add 4 (that is where the string pointer to the name of the trigger resides) and initialize a reference variable to this address. Then I replace the pointer to the old name, by the pointer to the new name, i.e. the variable in_NameTrig.

There might be a problem with this code. The string variable will only be alive as long as the memory for its context exists. Luckily DOORS will keep the memory alive (as I hinted above) as long as the module is open, therefore there is no problem normally. But it might be the case that for special trigger types or if the user activated noTriggers DOORS might free the memory earlier trashing the name variable. I did only test that code thoroughly for on close triggers.

Regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

Re: Valid Module handle
llandale - Wed Jul 06 13:22:27 EDT 2011

Mathias Mamsch - Tue Jul 05 18:00:16 EDT 2011

All DOORS Types (except of int, bool, date and real) are pointers to a structure (a block of memory that stores the properties of the objects). So if you do
 

string s = "hallo"

 


then DXL will put a pointer on the stack, that contains the address of the constant 'Hallo' that the DXL interpreter put somewhere into memory when interpreting the DXL. The addr_ function is really only a type conversion function that allows you to interpret a variable as another type. Example:

 

 

 

bool x = true 
print ((addr_ x) int) "\n"  // interpret 'true' as an integer
x = false
print ((addr_ x) int) "\n"  // interpret 'false' as an integer



So what the line of code does: It will interpret the Trigger variable as an integer which will give the memory address of the trigger property struct. I add 4 (that is where the string pointer to the name of the trigger resides) and initialize a reference variable to this address. Then I replace the pointer to the old name, by the pointer to the new name, i.e. the variable in_NameTrig.

There might be a problem with this code. The string variable will only be alive as long as the memory for its context exists. Luckily DOORS will keep the memory alive (as I hinted above) as long as the module is open, therefore there is no problem normally. But it might be the case that for special trigger types or if the user activated noTriggers DOORS might free the memory earlier trashing the name variable. I did only test that code thoroughly for on close triggers.

Regards, Mathias



 

 

 


Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

 

... and type 'char'...
char c = 'a'
print (intOf(c)) "\t" ((addr_ c) int) "\n"
... and I wonder about type 'void'.

I wonder what happens if you do or do not save the module after renaming a persistent trigger. Also, renaming a Project trigger won't actually rename it permanantly, I presume.

I notice that Dynamic triggers are given a unique name for the current DOORS session; "dymanic 1", "dynamic 2", "B:specific for dynamic 2 3", "dynamic 4". The Builtin ones seem to be post-module-close triggers that remove the corresponding dynamic trigger "stored" in the module.

Anyway, I'll go ahead and use the unique bland names "dynamic 2"; and withdraw the function to rename the trigger since we don't really know what will happen in all cases.

Thanks for the help

  • Louie