| 07-10-2005, 02:35 AM | #1 |
I have several questions and clarifications I want to make. I could probably figure several of these out myself, but I just wanted to pick some brains first. 1. Threads are cooperative, right? I mean, a thread will just keep executing until it yields with a TriggerSleepAction() call, or it gets killed by dividing by zero or some such, or spawns a new thread, or ends. Basically, I just want to be sure that if I start a thread, it won't yield until I have a chance to read from a temporary global variable, or something. Is that a safe thing to do? 2. Along the same lines: what happens with ExecuteFunc() and triggers executing? Do they interrupt the current thread and spawn a new one, or do they wait until the current thread isn't executing and then start the new thread executing? I'm just wondering if it's always safe to do something like: Code:
function CallThisFunction takes integer i returns nothing
set udg_SomeIntegerVariable = i
call ExecuteFunc("ChildFunction")
endfunction
function ChildFunction takes nothing returns nothing
local integer i = udg_SomeIntegerVariable
[i](do something with i)[/i]
endfunction3. Can you compare code variables? Such as, say: Code:
function CompareCode takes code aFunction returns boolean
return ( aFunction == function SomeOtherFunction )
endfunction4. Can you use the return bug with code variables? Does it work reliably? 5. What's a good way to test threads? I mean, to see if something runs in a new thread or in the same one, when it starts running, etc... is there a good way to yield to other threads without the forced quarter-second wait of TriggerSleepAction()? 6. Is there anything else I'd need to know to make a bullet-proof, thread-safe, not-slow-as-molasses system for executing arbitrary functions with parameters? 7. Misc. question... can you use a custom Blizzard.j or common.j in a map? I heard that they didn't load under some circumstances; what were those circumstances, and does anyone know if that's still the case? 8. Another misc. question... how fast is accessing a game cache compared to setting a global variable? Has it ever made a noticeable difference for you? I probably have more questions, but that should do for now... |
| 07-10-2005, 04:38 AM | #2 |
1,2. first of you execute a function differently by just calling it like call ChildFunction() and the chld function, since you call it from function callthisfunction has to be above. and no, i don't believe it will every mess up, it's sequential paradigm, everything is executed in order. as long as you don't call child function by itself from anywhere else, you should be fine. i think thats why there's trigger queue. events simulate interrupts, only these interrupts don't halt everything and execute right away, but wait their turn probably, that's the way I see it, otherwise there would be serious hell. But Trigger sleep function is whole different story, since you don't want to waste time waiting for wait function to finish, I think other fuctions/triggers are executed while wait takes place. and when trigger sleep is over, the function where this triggersleep took place is executed forward, maybe it even has highest priority on queue. 3. yes you can compare code by returning comparison like return a > b and it will return if its true or false. and hense you can say something like "return IntegerOne() > IntegerTwo() which will call these two function which return integer. 4. return bugs are reliable with anything 5. good way to test threads is to print messages on the screen which functions are executing (you have to identify these functions somehow and obviously know their order) 6. dunno 7. i think not, only add your own jass functions to custom script code field in front of all triggers. 8. well when storing something in cache you give it like 3 or 4 variables of different type, etc. so obviously it's slower than setting a single variable of for ex. integer. it's not noticible though as long as you don't have a loop function like even : every .1 seconds or something, then you are probably in trouble. hope i helped, feel free to correct me anyone else |
| 07-11-2005, 12:16 AM | #3 | |||||||
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
| 07-11-2005, 12:26 AM | #4 |
The only type that doesn't work correctly with return bug is string, you should never use it with string, seriously, code, real ,boolean, and all the handle family work well. The return bug It is not a bug actually, it is a Type cast method that is even used by blizzard. I will tell you my explanation for threads: Code:
function funa takes nothing returns nothing
call BJDebugMsg(I2S(globvar))
endfunction
function funb takes nothing returns nothing
set globvar=1
call ExecuteFunc("funa")
set globvar=2
call ExecuteFunc("funb")
endfunctionIt will show 1 then 2 Code:
function func takes nothing returns nothing
set globvar=3
endfunction
function fund takes nothing returns nothing
set globvar=0
call ExecuteFunc("func")
call BJDebugMsg(I2S(globvar))
endfunctionThis will show 3. The only problems will be when using waits between the ExecuteFunc and the part in the threaded func where you use the global, but that's solved by locals Code:
function DestroyEffect_Delayed takes nothing returns nothing
local effect fx=bj_lastCreatedEffect
call PolledWait(udg_EffectDur)
call DestroyEffect(fx)
set fx=null
endfunction
function Something takes nothing returns nothing
call AddSpecialEffectBJ (bla blablbl ....)
set udg_ EffectFuration=4
call ExecuteFunc("DestroyEffect_Delayed")
endfunctionThis will always destroy the effect after 4 seconds. The only things that cause problems with values of global variables are Waits AND Trigger Registrations, or actions that may cause a Trigger's event to fire, if that Trigger changes the value of the global. Otherwise it is safe |
| 07-11-2005, 12:49 AM | #5 | |
Quote:
For some reason i can't stand periodic events, they look like a desync monster, specially if used throughout whole game. i do use them, just trying not to overuse them. you are right cache shouldt cause problems with .1 periodic events, as long as it's not overused p.s. you can use executefunction("func name") ? hurrr didn't know that, learned something new i guess ^_^ |
| 07-11-2005, 12:58 AM | #6 |
I use 0.04 seconds periodic events and I don't see desyncs nor problems, of course if you mass them with gamecache usage that becomes a lag problem I've always said that blizzardd should make a hash table type, so we could use it instead of gamecache, gamecache is slow because it was designed for hard drive saving |
| 07-11-2005, 01:38 AM | #7 |
gamecashe is a hash table's retarted brother in a way. it's got similar functions, store some crap under unique id, access that crap directly, remove it, etc. . although why do you say that it's used to save hd space? How do you know it works like that, just interested in your knowledge vex |
| 07-11-2005, 02:45 AM | #8 | ||||
Quote:
But otherwise that's good to hear. So even if function SomeFunction == function SomeFunction doesn't work I can just cast them to an integer first. Quote:
Quote:
Otherwise it behaves like I hoped. Does this happen exactly the same if TriggerExecute() is used instead? Quote:
|
| 07-11-2005, 03:09 AM | #9 | |
Quote:
p.s. the only thing I don't like in wc3 is the random number generator. I needed to generate randoms in a forgroup function and it pretty much gave the same number for every time it ran the function. maybe it's using gametime or timepassed, I think it's really not that random |
| 07-11-2005, 02:01 PM | #10 |
Also be sure to check out this map http://www.wc3jass.com/files.php?mode=view&id=26 It shows quite a number of possibilities to start new threads and lists their advantages/disadvantages and characteristics. Basically a sort of benchmark. |
| 07-11-2005, 03:42 PM | #11 | |||
Quote:
i said it was designed to be used to save data on hard drive, for campaigns and that stuff , it wasn't designed to be our hash table, and it is slow because of that. Quote:
Quote:
|
| 07-11-2005, 04:17 PM | #12 | |
Quote:
Ah well, looks like ExecuteFunc's my thing. Or a timer, if it's one-way. Thanks for the map, PitzerMike. Just my question about embedded Blizzard.j left. Though my hopes aren't exactly high. |
| 07-11-2005, 04:20 PM | #13 |
I don't see what Timers have to do with this. TriggerExecute is always a bad idea because of the TriggerAction leak |
| 07-11-2005, 06:26 PM | #14 | ||
Quote:
Quote:
|
| 07-11-2005, 11:41 PM | #15 |
Well triggeractions leak. timers are not threads since you can't use waits there., they are a way to execute code after a time which is something different from a thread. |
