UpdtDisplay: recursion attempted printed in Command Window
ctmckee
Here is the code:
Function GraphNow()
setwindow graph1 hook=updateFakeBand
end
Function updateFakeBand(infostr)
string infostr
string event=StringByKey("EVENT",infostr)
strswitch(event)
case"modified":
SVar TW=root:LaneName
wave w=$TW
createimageframe(w)
break
endswitch
return 0
end
setwindow graph1 hook=updateFakeBand
end
Function updateFakeBand(infostr)
string infostr
string event=StringByKey("EVENT",infostr)
strswitch(event)
case"modified":
SVar TW=root:LaneName
wave w=$TW
createimageframe(w)
break
endswitch
return 0
end
If so, use a global variable to control recursion, something like this:
setwindow graph1 hook=updateFakeBand
Variable/G updateFakeBandRunning = 0
end
Function updateFakeBand(infostr)
string infostr
NVAR updateFakeBandRunning
if (updateFakeBandRunning)
return 0 // avoid re-entrant call
endif
updateFakeBandRunning = 1
string event=StringByKey("EVENT",infostr)
strswitch(event)
case"modified":
SVar TW=root:LaneName
wave w=$TW
createimageframe(w)
break
endswitch
updateFakeBandRunning = 0
return 0
end
You could put the recursion block into createimageframe(), but I don't have the code for it, so I put it into updateFakeBand(). This is one of the few reasons to use a global variable!
On a side note, in new code you should really use named hook functions that take a structure as input. They are more reliable and are more likely to get new features.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 6, 2015 at 05:11 pm - Permalink
Thanks for the reply. I tried your code and still have problem. I'm attaching a screen shot of what I'm doing, as well as the additional code (createimageframe).
wave w
wave pfl=root:packages:wmimprocess:lineprofile:profile
variable n, framelength
nVar GS=root:greyscalevalue
framelength=dimsize(w,0)
make/o/n=(framelength,5) FalseBandImage
duplicate/o pfl, LaneProfile
LaneProfile=-LaneProfile
do
FalseBandImage[][n]=pfl[p]
n+=1
while(n<5)
dowindow/R/K Fake
Display/n=Fake/w=(150,50,415,600); appendimage FalseBandImage
Modifygraph/w=Fake swapxy=1, tick=3,noLabel=2,margin(left)=216
ModifyImage FalseBandImage ctab= {*,GS,Grays,1}
SetAxis/A/R left
Display/FG=(FL,FT,FR,FB)/HOST=#/VERT LaneProfile
SetAxis/A/R left
ModifyGraph tick(left)=3,axisEnab(bottom)={0,0.8},nolabel(left)=2,mode=7,rgb=(0,39168,0),hbFill=5
label bottom "Signal Intensity"
end
Function GraphNow()
setwindow graph0 hook=updateFakeBand
Variable/G updateFakeBandRunning = 0
end
Function updateFakeBand(infostr)
string infostr
NVAR updateFakeBandRunning
if (updateFakeBandRunning)
return 0 // avoid re-entrant call
endif
updateFakeBandRunning = 1
string event=StringByKey("EVENT",infostr)
strswitch(event)
case"modified":
SVar TW=root:LaneName
wave w=$TW
createimageframe(w)
break
endswitch
updateFakeBandRunning = 0
return 0
end
January 7, 2015 at 09:17 am - Permalink
And don't forget, named hook functions should return 1 not 0 to indicate they have accomplished something.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
January 7, 2015 at 09:17 am - Permalink
wave w=$TW
createimageframe(w)
do this:
Execute/P "createimageframe("+TW+")"
You'll find that this litters your history with calls to createimageframe. But you'll see what it's doing that way. To get rid of the litter, add /Q after /P.
But really, you don't want to do it this way. Destroying and re-making the graph is time-consuming, and as you see, fraught with difficulties. I would note the documentation for DoWindow/R, where it says:
"However, /R does nothing if a macro or function is running." I think all you want is the action of /K, so that's really not an issue, but still...
I would use the GraphNow() function to create the Fake graph, then in updateFakeBand() just modify the waves being displayed in Fake.
OK- I just ran Igor under a debugger so I could figure out why your code triggers that message. It should have been obvious (to me)... The Modified event comes during a display update, when Igor notices that your graph has been modified. But your Display command also triggers a display update, when Igor is already in the middle of a display update. And that's why Execute/P fixes it: it puts off the destruction and creation of a graph until after the window hook function is finished, which will be after the original display update is finished.
I still recommend doing the job differently!
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 7, 2015 at 01:53 pm - Permalink
Yeah, generally that's true. In this case, he's just trying to respond to an event and doesn't want to modify Igor's actions. If you only want to know when to do something, returning zero is correct- it lets Igor do its thing, and you can do your thing.
If you're responding to key presses or mouse clicks, on the other hand, you probably want to return 1 to prevent Igor from, say, launching a dialog or entering text when you want to use the mouse click or character.
In this particular case, returning 1 won't do anything- Igor is just informing you that a graph has already been modified and you can't keep Igor from doing anything in this case.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 7, 2015 at 01:57 pm - Permalink
Thanks for the details. I will implement your correction as well as try to achieve the same result by other means.
Cheers,
Clayton
January 8, 2015 at 12:56 pm - Permalink
January 8, 2015 at 05:21 pm - Permalink