| 10-19-2004, 08:03 PM | #1 |
For the last several months I have been coding over 16k lines of jass for a project. I have run into a MAJOR issue and need some suggestions/help. Basically I use ExecuteFunc ALOT. I have the name of the function stored in the game cache and then when I want to call a particular function I just use ExecuteFunc( "funcname") and it works great. However I started to add functions that had WAITs in them and ran into major issues with the functions executing in the wrong order. Basically If you have a function a that calls functions b and c and function b contains a wait, then function b will stop temporarily and function c will continue and finish THEN return to function b. For what i need, ie functions executing in the CORRECT order all the time, this doesnt work. I have made a test map to show this, anyone that thinks they have solutions PLEASE DL and see if you can find a work around. Any help would GREATLY be appreciated. Thanks Rod ![]() |
| 10-19-2004, 09:54 PM | #2 |
Guest | Thank you for the map that shows the differences between call <function> and run <trigger>! I've been too lazy to test for it myself. Are there really so many functions that you can't use call statements directly? (/me would understand more if you were to elaborate.) Failing that... you could create a trigger out of each function and store that. (maybe have one cache or category for the string values, and another for the handle reference (H2I) for that trigger.) Then queue those. (much later... after spending half an hour looking for `append code to trigger actions' function in the trigger queue code!) Yep, the only reason the trigger queue works is because you HAVE to put that `clear this trigger from the queue' bit at the end of a trigger (apart from a failsafe 3 minute timer). So each trigger causes the next trigger in the queued array to execute. It shouldn't be too hard to duplicate this with "executefunction" instead, just copy the code from blizzard.j. (oops, I think I deleted part of a previous edit. sth about creating your own "execute function" queue, I don't know if it is required to understand previous paragraph.) |
| 10-20-2004, 12:31 AM | #3 |
Don't use waits? I think it was known that waits were generally a no-no. Since you use a function based system instead of using function names use the function pointer value and then use a timer with whatever time duration to run this peice of code or whatever. |
| 10-20-2004, 03:43 PM | #4 |
Well the weird thing is that I use ExecuteFunc in my Templates system, and overuse waits with no problems, have to research way more on this. And what was this doing in the trigger haven, moved to siberia err the JASS vault forum |
| 10-20-2004, 07:14 PM | #5 |
Hmm yes i have literally a 1000 different functions. Don't use waits? LOL i have cinematics. Once again 1000 eventually. Not using waits would be not worth the effort. Vex: test my map it shows very clearly what works and what doesnt. If you THINK your executefuncs are working with waits well your just getting lucky that you dont care what order shit executes in :> |
| 10-20-2004, 09:46 PM | #6 |
So far this is what I have come up with: function WaitEF takes nothing returns nothing loop call TriggerSleepAction( 0.25) exitwhen execfuncdone[ execfuncdonecount] endloop set execfuncdonecount = execfuncdonecount - 1 endfunction // function DoneEF takes integer val returns nothing loop call TriggerSleepAction( 0.25) exitwhen execfuncdonecount == val endloop set execfuncdone[ execfuncdonecount] = true endfunction function PushEF takes nothing returns integer set execfuncdonecount = execfuncdonecount + 1 set execfuncdone[ execfuncdonecount] = false return execfuncdonecount endfunction // function SetEF takes nothing returns integer return execfuncdonecount endfunction // OK and THESE are sample functions: function test takes nothing returns nothing local integer EF = SetEF() ..... DO SOME SHIT that contains a WAIT call DoneEF() endfunction function doit takes nothing returns nothing call PushEF() call ExecuteFunc( "test") call WaitEF() endfunction It appears to work but what a pain. About to test it with a ton of waits in one call. |
| 10-21-2004, 07:40 AM | #7 |
Guest | Store the name of each <function you want to run in order> as a string in an array, with the first to execute at index zero. Use an index to keep track of the highest index actively in use, just like blizzard did with their queue. Add to the end of each function you use `call AttemptRunNextExecFunc()'. Make `AttemptRunNextExecFunc()' check to see if there are any more functions to be run (and if so, run the first one), and if not, call <whatever you want to happen after all the ExecFuncs are finished>, possibly by storing it in a hardcoded string variable and using ExecFunc again. YW >.> |
| 10-21-2004, 07:58 AM | #8 |
Well 2 things misaki.. First off i have lots of functions that are not in any particular order so putting them into an array would be very very hard. Second I THINK what i pasted above is very similar to what you are saying. However you say "just like blizzard did with their queue. " do you have any links explaining what they did exactly? Thanks |
| 10-21-2004, 10:20 AM | #9 |
Guest | meh.. you're not making sense. Either you want them to run in a particular order, or you don't want them to run in a particular order. (just like the trigger queue, you would add functions to the queue dynamically...) The trigger queue functions start here. The difference between what you do and the queue (the way blizzard does it) is for the queue, the next function in line is executed automatically, not after .25 seconds or more (wait is unreliable). Also, why is it necessary to use ExecuteFunction() instead of calling them directly? If you're desperate, you could always make up a huge CallFunctionByString() function, that does an if/then search to call the appropriate function. Is the `code' variable type useful for anything? Code:
function experiment takes nothing returns nothing
local code c = function experiment
local trigger t
// call ExecuteFunc("c") // I don't think this would work.
call TriggerAddAction(t, c)
endfunctionOi, what's the TriggerExecuteWait() function do? o.0 |
| 10-21-2004, 07:46 PM | #10 |
Thanks for the link. I didnt realize they were BJ functions. I am using game cache to store my function names. YES i could make a HUGE if then. While I could make it so it never checked more than a small group at a time there would still LITERALLY be over 1000 if then statements. My map needs are THAT huge. The problem with the queue is that if u call another executefunc inside it will have the same problem.. ie func a calls EF B then does some stuff an inside EF B there is ANOTHER EF - Execute Func call then it causes major havoc. I appear to have solved this now but what a pain. There is no ExecuteCode( c) which would be great but there is a workaround. http://kattana.users.whitehat.dk/viewfunc.php?id=23 which has the same issue. Its threaded :( FOLLOWUP: function WaitEF takes nothing returns nothing loop exitwhen execfuncdone[ execfuncdonecount] call TriggerSleepAction( 0.0) endloop set execfuncdonecount = execfuncdonecount - 1 endfunction // function DoneEF takes integer val returns nothing loop exitwhen execfuncdonecount == val call TriggerSleepAction( 0.0) endloop set execfuncdone[ execfuncdonecount] = true endfunction swapping the order of the wait and putting it after appears to make it run faster and not cause any other issues! I had tried this before but think I had another unrelated bug so this had FIXED it. Basically the problem is simple. If you have a function "a" that call the function "b" with executefunc and "b" calls a wait then it will continue with function "a"s execution before returning to "b". To prevent this i have the waitEF loop. The next problem is what if function "b" calls using executefunc "c" and "c" uses a wait? Thats why I have to have the PushEF / WaitEF combo at EVERY LEVEL otherwise it will restart when I don't want to. If I used something like the trigger queue then the problem would be this. Add trigger "a" to queue. it starts to execute and inside of "a" is an Add trigger "b" to queue. Well it CANT start "b" and YET i NEED it to start "b" before finishing with "a". It appears what my functions do is solve this nasty problem. Thanks for the comments any followup is appreciated. |
| 10-21-2004, 08:07 PM | #11 | |
Quote:
function DoSomething takes nothing returns nothing call ExecuteFunc("sss") endfunction function sss takes nothing returns nothing call BJDebugMsg("sss") endfunction Won't give errors |
| 10-22-2004, 06:51 AM | #12 |
Guest | I got it. ^ ^ Do the turn-functions-into-triggers-before-storing-them thing, then call TriggerWaitOnSleeps() for all of them. (tested on your example map and it worked.) Again, does anyone know what TriggerExecuteWait() does? It doesn't make the calling trigger or the called trigger wait on sleeps; I can't find any difference between normal TriggerExecute(). |
