updating lines
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
updating lines
Hey,
So we have a program that allows users to map various concepts and the main components are fields and line graphics (users connect the fields with lines, basically). The lines automatically update so that when users move fields around, the lines associated with the those fields move with them. The problem is that once we start getting more than 10 or 12 fields on the card for users to map, the update lines runs extremely slowly and sometimes causes the program to crash.
Any tips on how to make something like this work more effectively?
Thanks,
Laurel
So we have a program that allows users to map various concepts and the main components are fields and line graphics (users connect the fields with lines, basically). The lines automatically update so that when users move fields around, the lines associated with the those fields move with them. The problem is that once we start getting more than 10 or 12 fields on the card for users to map, the update lines runs extremely slowly and sometimes causes the program to crash.
Any tips on how to make something like this work more effectively?
Thanks,
Laurel
Re: updating lines
Hi Laurel,
we need to take a look at your script(s)!
Best
Klaus
we need to take a look at your script(s)!
Best
Klaus
Re: updating lines
Laurel-
I did something like that a while back. I'd have to dig up the stack from the archives again, but a few things come to mind:
1. Lock the screen before any visual updates and unlock it afterwards. Locks nest well, so you can lock the screen even if it's already locked - the unlock won't actually happen until you work your way out of the nest.
2. Use the "repeat for each" form of repeat loop wherever possible - it's an order of magnitude faster than "repeat for".
3. If necessary, move the stack offscreen to do the updates, then move it back to the original location.
I did something like that a while back. I'd have to dig up the stack from the archives again, but a few things come to mind:
1. Lock the screen before any visual updates and unlock it afterwards. Locks nest well, so you can lock the screen even if it's already locked - the unlock won't actually happen until you work your way out of the nest.
2. Use the "repeat for each" form of repeat loop wherever possible - it's an order of magnitude faster than "repeat for".
3. If necessary, move the stack offscreen to do the updates, then move it back to the original location.
PowerDebug http://powerdebug.ahsoftware.net
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
PowerTools http://www.ahsoftware.net/PowerTools/PowerTools.irev
Re: updating lines
Here is the updatelines handler:
on updateLines pRepeat
set the recursionlimit to 1000000000000000000
if gInMotion is true then
repeat with x = 1 to the number of lines in gCurrentLinks
set the points of graphic line x of gCurrentLinks to the loc of field item 1 of line x of gCurrentLinks &cr& the loc of field item 2 of line x of gCurrentLinks
set the layer of graphic line x of gCurrentLinks to 1
end repeat
--for updating node positions if multiple objects are selected
if the number of items in gSelectedNodes > 1 then
global gRelativeLoc, gObjectInMotion
repeat with x = 1 to the number of items in gSelectedNodes
if the moveable of field item x of gSelectedNodes is true then
put item 1 of the location of field gObjectInMotion + item 1 of gRelativeLoc[item x of gSelectedNodes] into XPos
put item 2 of the location of field gObjectInMotion + item 2 of gRelativeLoc[item x of gSelectedNodes] into YPos
set the location of field item x of gSelectedNodes to XPos&comma&Ypos
end if
end repeat
end if
wait 1 milliseconds with messages
if pRepeat <> "NoRepeat" then
updateLines
end if
else
put empty into gObjectInMotion
put empty into gRelativeLoc
end if
end updateLines[/code]
on updateLines pRepeat
set the recursionlimit to 1000000000000000000
if gInMotion is true then
repeat with x = 1 to the number of lines in gCurrentLinks
set the points of graphic line x of gCurrentLinks to the loc of field item 1 of line x of gCurrentLinks &cr& the loc of field item 2 of line x of gCurrentLinks
set the layer of graphic line x of gCurrentLinks to 1
end repeat
--for updating node positions if multiple objects are selected
if the number of items in gSelectedNodes > 1 then
global gRelativeLoc, gObjectInMotion
repeat with x = 1 to the number of items in gSelectedNodes
if the moveable of field item x of gSelectedNodes is true then
put item 1 of the location of field gObjectInMotion + item 1 of gRelativeLoc[item x of gSelectedNodes] into XPos
put item 2 of the location of field gObjectInMotion + item 2 of gRelativeLoc[item x of gSelectedNodes] into YPos
set the location of field item x of gSelectedNodes to XPos&comma&Ypos
end if
end repeat
end if
wait 1 milliseconds with messages
if pRepeat <> "NoRepeat" then
updateLines
end if
else
put empty into gObjectInMotion
put empty into gRelativeLoc
end if
end updateLines[/code]
Re: updating lines
Also, I can't figure out how to apply the "repeat for each" command to the above code. Sorry--I am just a little confused by the syntax for that.
Re: updating lines
Hi.
I have not looked at your main issue, but:
repeat for each item tItem in gSelectedNotes
"Repeat with y=1..." is essential when a running numerical index is used for other purposes, and this is very common. But if you just need to cycle through all the chunks of an object or variable, use "repeat for each...". This is much faster.
In your case, you never needed to actually know, at any one time, which item you were looping through, you just needed to loop through them all.
Craig Newman
I have not looked at your main issue, but:
repeat for each item tItem in gSelectedNotes
"Repeat with y=1..." is essential when a running numerical index is used for other purposes, and this is very common. But if you just need to cycle through all the chunks of an object or variable, use "repeat for each...". This is much faster.
In your case, you never needed to actually know, at any one time, which item you were looping through, you just needed to loop through them all.
Craig Newman
Re: updating lines
Hi,
important hint: Use PARENTHESIS to avoid unneccessary "engine parsing" trouble!
Bad:
...
set the points of graphic line x of gCurrentLinks to the loc of field item 1 of line x of gCurrentLinks &cr& the loc of field item 2 of line x of gCurrentLinks
set the layer of graphic line x of gCurrentLinks to 1
...
if the moveable of field item x of gSelectedNodes is true then
Good:
...
set the points of graphic (line x of gCurrentLinks) to the loc of field (item 1 of line x of gCurrentLinks) &cr& the loc of field (item 2 of line x of gCurrentLinks)
set the layer of graphic (line x of gCurrentLinks) to 1
...
if the moveable of field (item x of gSelectedNodes) is true then
The former one might fail when you least exspect it!
Best
Klaus
important hint: Use PARENTHESIS to avoid unneccessary "engine parsing" trouble!
Bad:
...
set the points of graphic line x of gCurrentLinks to the loc of field item 1 of line x of gCurrentLinks &cr& the loc of field item 2 of line x of gCurrentLinks
set the layer of graphic line x of gCurrentLinks to 1
...
if the moveable of field item x of gSelectedNodes is true then
Good:
...
set the points of graphic (line x of gCurrentLinks) to the loc of field (item 1 of line x of gCurrentLinks) &cr& the loc of field (item 2 of line x of gCurrentLinks)
set the layer of graphic (line x of gCurrentLinks) to 1
...
if the moveable of field (item x of gSelectedNodes) is true then
The former one might fail when you least exspect it!

Best
Klaus