Need to figure out how to tell if an old "Module" handle is still 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()
llandale - Thu Jun 30 17:03:36 EDT 2011 |
Re: Valid Module handle
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
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
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
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
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.
|
Re: Valid Module handle llandale - Sun Jul 03 02:02:31 EDT 2011
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 Mathias Mamsch - Sun Jul 03 09:49:29 EDT 2011 Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS 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.
|
Re: Valid Module handle llandale - Sun Jul 03 15:36:17 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
}
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Valid Module handle 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
}
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
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.
|
Re: Valid Module handle llandale - Sun Jul 03 18:10:31 EDT 2011
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
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 llandale - Sun Jul 03 18:12:25 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
}
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
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()
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 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.
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
|
Re: Valid Module handle jsarkic - Tue Jul 05 12:02:00 EDT 2011
Thanks Mathias.
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
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 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
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS |
Re: Valid Module handle 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
}
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Seems to work. Forgive ignorance, please explain the "int" part of this line:
//************************************
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 llandale - Tue Jul 05 16:56:31 EDT 2011
Seems to work. Forgive ignorance, please explain the "int" part of this line:
//************************************
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"
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
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Valid Module handle 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"
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
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
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
|