Hey all,
In a unit loop if you wanted to call another function with the parameters of the unit, ex: UnitKill(u), but have the rest of the script run regardless of if this latest call has finished?
What's happening is I have a pretty large unit loop going on and calling a lengthy function on each unit. It causes the error that means that the function is taking too long to complete.
Is this happening because it has to wait for every function to run on every unit? If so, how would I get around this?
Galaxy has an internal limit for how many instructions can be executed by a single thread in a single frame. If you get the Taking Too Long error, youve exceeded the limit.
Yes, splitting the work up into multiple threads (triggers usually start a new thread, but maybe there are other ways as well, someone with more experience should know) would solve the issue. But maybe you can optimize the function that gets called for every unit, so that it doesnt take as long to execute.
Think about how your algorithm is structured. Maybe sacrifice some memory for speed (caching or indexing results). If you provide your code, we can be more specific about how you could improve your code.
You can use action definitions with the "Create Thread" option checked, then just put the actions that you want to run inside the loop into the def and make the loop only run the def. This could potentially create a crapton of threads though and cause a "too many threads" error - I don't know how high the limit is for threads. Another option is to use a Wait 0.0 seconds (Which will wait for 0.03125 or so seconds) every x times the loop is run (Use an integer, increase it by 1 at the end of every loop, then check whether the integer is at like 100 or 1k or whatever is closest to reaching the execution time limit, use a wait if true and reset the integer to 0). I'm fairly certain waits reset most limits, might be wrong though. Worth a shot at least.
I don't think you can pass parameters if you decide to use the call trigger functions, or can you?
Sadly wait() won't work in my situation because even waiting for 0 seconds puts things out of cycle.
I'll go ahead and post this script of where it's being caused:
What this code does is it's given two units that have been detected within each others' radius and finds the point where the two roughly meet. Then splits them apart. My guess would be that sometimes the velocities are acted on by another force unexpectedly and now the two are within each others' radius without having the same velocities as they got there.
Maybe I should make a minimum velocity that each component can check for?
Since I posted this script with a ton a variables declared, is it better to do that or to just have each line in the while loop do UnitGetPosition etc.?
Galaxy doesnt allow locals to be declared after the first non-declaration statement.
The variables uh and ch are not read inside the function. But anyway, how often do you call this function? How many units are active? Unless you can get high values for i, this function shouldnt be that costly for a single pair of units.
It isn't ran too often, and the i value should never exceed 3 if it were running as it were supposed to.
I ran a test where the error occured and the i value was exceeding 25,000. hahaha.
I think I'll just have to either make a lowest limit for the vz, etc. or find why this is happening.
How is DistanceZ implemented on your end? Maybe there are some possible implementations that cause an overflow (thank Blizzard for that) for stationary objects that are very far apart.
EDIT: Or, of course, there really are stationary objects that somehow overlap.
pretty simple, i doubt that's causing the error unless blizzard really made a mistake.
My guess is on that friction (another function i have running) is being applied as soon as the unit is moved within range of the other unit, and that's when the function i posted runs and errors. Maybe I can rearrange them so friction can't be applied during the inbetween.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Hey all, In a unit loop if you wanted to call another function with the parameters of the unit, ex: UnitKill(u), but have the rest of the script run regardless of if this latest call has finished?
What's happening is I have a pretty large unit loop going on and calling a lengthy function on each unit. It causes the error that means that the function is taking too long to complete. Is this happening because it has to wait for every function to run on every unit? If so, how would I get around this?
Galaxy has an internal limit for how many instructions can be executed by a single thread in a single frame. If you get the Taking Too Long error, youve exceeded the limit.
Yes, splitting the work up into multiple threads (triggers usually start a new thread, but maybe there are other ways as well, someone with more experience should know) would solve the issue. But maybe you can optimize the function that gets called for every unit, so that it doesnt take as long to execute.
Think about how your algorithm is structured. Maybe sacrifice some memory for speed (caching or indexing results). If you provide your code, we can be more specific about how you could improve your code.
I decided to restructure the majority of the thread, just to work around it for now. But if anyone knows how to split a thread that would help a lot.
You can use action definitions with the "Create Thread" option checked, then just put the actions that you want to run inside the loop into the def and make the loop only run the def. This could potentially create a crapton of threads though and cause a "too many threads" error - I don't know how high the limit is for threads. Another option is to use a Wait 0.0 seconds (Which will wait for 0.03125 or so seconds) every x times the loop is run (Use an integer, increase it by 1 at the end of every loop, then check whether the integer is at like 100 or 1k or whatever is closest to reaching the execution time limit, use a wait if true and reset the integer to 0). I'm fairly certain waits reset most limits, might be wrong though. Worth a shot at least.
I don't think you can pass parameters if you decide to use the call trigger functions, or can you?
Sadly wait() won't work in my situation because even waiting for 0 seconds puts things out of cycle.
I'll go ahead and post this script of where it's being caused:
What this code does is it's given two units that have been detected within each others' radius and finds the point where the two roughly meet. Then splits them apart. My guess would be that sometimes the velocities are acted on by another force unexpectedly and now the two are within each others' radius without having the same velocities as they got there.
Maybe I should make a minimum velocity that each component can check for?
Since I posted this script with a ton a variables declared, is it better to do that or to just have each line in the while loop do UnitGetPosition etc.?
Galaxy doesnt allow locals to be declared after the first non-declaration statement.
The variables uh and ch are not read inside the function. But anyway, how often do you call this function? How many units are active? Unless you can get high values for i, this function shouldnt be that costly for a single pair of units.
It isn't ran too often, and the i value should never exceed 3 if it were running as it were supposed to.
I ran a test where the error occured and the i value was exceeding 25,000. hahaha.
I think I'll just have to either make a lowest limit for the vz, etc. or find why this is happening.
How is DistanceZ implemented on your end? Maybe there are some possible implementations that cause an overflow (thank Blizzard for that) for stationary objects that are very far apart.
EDIT: Or, of course, there really are stationary objects that somehow overlap.
pretty simple, i doubt that's causing the error unless blizzard really made a mistake.
My guess is on that friction (another function i have running) is being applied as soon as the unit is moved within range of the other unit, and that's when the function i posted runs and errors. Maybe I can rearrange them so friction can't be applied during the inbetween.