System Key Timers 2

Cohadar

master of fugue
A few advices for KT2:

You can optimize your load function by preloading triggerExecCount

Since triggers are never destroyed, you can create them all on Init
and set exec count to be the same as index of trigger in an array.

GetTriggerExecCount(Trigger) == i should always be true.

When you need to remove a trigger from place you do not swap it with the one on max[id] but only pass conditions
JASS:

if TriggerEvaluate(trig<i>) then
	call TriggerClearConditions(trig<i>)
        call TriggerAddCondition(trig<i>, Conditionz[max[id]])
        call TriggerClearConditions(trig[max[id]])
	set max[id]=max[id]-1
endif
</i></i></i>
 

Jesus4Lyf

Good Idea™
Flare>what exactly is different between this and key timers 1, and is it as easy to use?
Yes. Very, very easy to use. For you, and what you need to understand, it equates to this... Exactly the same as Key Timers 1 but with a significantly easier interface. If you want to compare with TT, then it's the same to use but you can specify period.

Basically, instead of calling the textmacro, you use function calls. See the KeyTimers2.w3x example map for details on similarities/differences. Should help. :D

Now that this system is established, I may start releasing some spells for it myself... :shades:

If people want to ask a request or two for different spells, I may give it a shot and post them as examples. :D


>preloading triggerExecCount
Preload as in call it on map init, or is there a call to make to preload the function for something (unfamiliar terminology)?

>GetTriggerExecCount(Trigger) == i should always be true.
In a perfect world. The whole point is to eliminate the array call. Of course, giving triggers unique integers would be fine, if only structs allowed you to specify their id... :banghead:

You have a good idea there, but I would just use your attachment method if I was going to involve arrays anyway. =/

I can't create the triggers on map init btw, because the system won't know what periods are in use or how many triggers to make.
 

Cohadar

master of fugue
Actually you can but never mind.
It is true that using attaching would be more sane.
 

Jesus4Lyf

Good Idea™
And more efficient for loading, which is what the whole point is - to exclude the array call and just use natives. :shades:

The real way to do it all is have the Add function return an integer (the trigger's unique id which means you'd never have to change the execcount again) which you use as the struct to attach things to, and you just forget all about using struct.create() and struct.destroy(). But that's terrible coding practise, even though it would work and be unbeatable in efficiency.

Edit instead of double post: New example spell created, demonstrating the full power of Key Timers 2: Sandman.
 

Flare

Stops copies me!
Staff member
got a question about using KT with unit groups. im trying to make a spell that knocks back units as a dummy unit encounters them so im gonna add them to a unit group and bla bla bla. if i pick every unit within the group, and do the actions like so

JASS:
//However I pick every unit within unit group
set i.pushunit=(GetUnit ())//that should be GetEnumUnit i think but not totally sure ^^
call Do&lt;insert something here&gt;
//dont have WE open and i forget where my WC disc is so everythings a little unknown


would that (under the assumption that it works with one unit) work so that every unit that should be pushed, will be pushed at the same time, or will it wait until the timer ends before moving the next unit?

also, if it didnt wait until the timer was finished, would the variable overlap within the timer loop, making units stop for no apparent reason?
 

Jesus4Lyf

Good Idea™
Just got back from holidays...

Sorry your code is a bit vague. I explained elsewhere how to to something to all units within a certain radius... I'd use that method:
JASS:
local group g=CreateGroup()
local unit t
call GroupEnumUnitsInRange(g,GetUnitX(unit),GetUnitY(unit),distance,null)
	loop
		set t=FirstOfGroup(g)
		exitwhen t==null
		call GroupRemoveUnit(g,t)
		if &lt;CONDITIONS INVOLVING T WHICH IS ENUM UNIT&gt; then
			&lt;DO STUFF TO T WHICH IS ENUM UNIT&gt;
		endif
	endloop
call DestroyGroup(g)
set g=null

Note that these groups aren't reusable as they must remove all units from the group as it is used. However, since I assume you'll pause the units that are sliding, and that they'll slide with the dummy unit (which is not needed, you can just store an x and y in a variable) that they will not leave the radius anyway, and so will be included every time it loops. Using ForGroup is generally a bad idea in my opinion. Sometimes it's the best way though... But I tend to use this instead. Hope that helps, if it doesn't, ask for further help... Sorry that I've been on holidays and stuff, chances are this is out of date for you anyway. :p
 

Hatebreeder

So many apples
Just got back from holidays...

Sorry your code is a bit vague. I explained elsewhere how to to something to all units withing a certain radius... I'd use that method:
JASS:
local group g=CreateGroup()
local unit t
call GroupEnumUnitsInRange(g,GetUnitX(unit),GetUnitY(unit),distance,null)
	loop
		set t=FirstOfGroup(g)
		exitwhen t==null
		call GroupRemoveUnit(g,t)
		if &lt;CONDITIONS INVOLVING T WHICH IS ENUM UNIT&gt; then
			&lt;DO STUFF TO T WHICH IS ENUM UNIT&gt;
		endif
	endloop
call DestroyGroup(g)
set g=null

Note that these groups aren't reusable as they must remove all units from the group as it is used. However, since I assume you'll pause the units that are sliding, and that they'll slide with the dummy unit (which is not needed, you can just store an x and y in a variable) that they will not leave the radius anyway, and so will be included every time it loops. Using ForGroup is generally a bad idea in my opinion. Sometimes it's the best way though... But I tend to use this instead. Hope that helps, if it doesn't, ask for further help... Sorry that I've been on holidays and stuff, chances are this is out of date for you anyway. :p
Actually, I use that method for Stuff like "IsUnitEnemy(...) == true" in an If then else statement in the loop.
Since (At least of my knowledge) there is no System, where I can pass though Data from one struct, to a non-timer, non-dialog, non-trigger function (In this case, some Condition Function).
 

0zaru

Learning vJASS ;)
Instead use a ForGroup call (Use a global variable,It must work if there are no waits (And you must not have waits since you use timers :p)). You can get a struct from a ForGroup callback with a get from GetTriggeringTrigger().
 

Jesus4Lyf

Good Idea™
... That's a really good point. You'll be able to load the struct from the ForGroup call just like from the timer trigger, using the GetTriggerExecCount thing. I still prefer using the FirstOfGroup loop over the ForGroup call though. It's just nicer in my opinion to keep everything in one chunk of code. More linear.
 

Jesus4Lyf

Good Idea™
I'd like to inform people of a not-so-important discovery.

Calling a function that returns a value from an array is FASTER than calling GetTriggerExecCount(GetTriggeringTrigger()).

That's right. It turns out my method was slower all along. I have updated KT2 accordingly. Additionally, I have done two other efficiency updates (the first of which can be applied to nearly all systems for efficiency gains). Instead of using local variables, use globals and pretend they're locals.

Bench tests have concluded that:

JASS:
local integer j=2

takes twice as long to execute as
JASS:
globals
integer J
endglobals
...
set J=2


Additionally, when reading the same value from an array 4 times, it is more efficient to store that value temporarily in a global, and refence that instead. If you read it 3 times, it is much the same, but slightly less efficient with the global (within 5% speed, off memory). If you read it 2 times, it is less efficient to store it first. I've applied this to optimize also.

KT2 is now significantly faster than it was before. If you apply the new version to Sharl and Sandman (keeping in mind to change GetExec(trig) thingie to KT_GetData()) then they don't lag at all. Which is amazing, imho. They're both full 3D MUI spells which micro manage between 40 and 400 pieces.

Anyway, KT2 Version 1.1 released. :)
 

Sim

Forum Administrator
Staff member
Wow, that is impressive Jesus. :)

Ungraveyarded. I'm using keytimers2 in my new spell and must say it is really efficient. Setting your own period is really a great feature, along with this system's efficiency brings it pretty high on my useful systems list. This system is really neat.

Plus, I was using the old version...

Any comments before I move this into the systems section?
 

Sim

Forum Administrator
Staff member
.

Any comments before I move this into the systems section?
As I said, this timer system is really neat.

> bench tested them, explained how they work, and written a report on them. Here it is:

That's a first! And you might want to write a tutorial on that, too. ;)

Impressive work. Definitely.

Approved.

EDIT: merged posts.
 

Jesus4Lyf

Good Idea™
Benchmarked! Timer Systems in Warcraft III.

Took a year (originally released Christmas, 2007) and went through the graveyard and back to get approved, but it's back and now comes with detailed documentation.

I've gone through the trouble of downloading a selection of timer systems, analysed how they work, bench tested them, explained how they work, and written a report on them. I sincerely recommend that everyone goes and takes a look at it. The documentation is on the second post on the first page.

Go to that post

Note by Daxtreme - Message to users replying in this thread: Please DO NOT reduce this thread into any kind of flamewar over benchtests. Thanks.

Better preventing than reacting!
 

emjlr3

Change can be a good thing
would like to see some benchmarks comparing TimerUtils, and perhaps HSAS or one of the other more popular attachment methods.
 

Jesus4Lyf

Good Idea™
Then benchmarks you will see.

I didn't bother bench testing the attaching method, for obvious reasons.
But in case those reasons aren't obvious, it's basically because it's insignificant compared to how fast the loop executes (100 to 1 kind of thing). More on the theory of that in my report; Timer Systems in Warcraft III.

The computer I tested them on had a reboot since the first tests, obviously, so I also re-benched KT2 for comparison, but even KT2's first result beats them all...

Anyway, using the same test as in my report (and I intend to update the report with these soon enough):

KT2 <3: ~32,000 executions per second.
TimerUtils Red: ~30,100 executions per second.
TimerUtils Blue: ~26,500 executions per second.
HSAS (used on a timer): ~24,800 executions per second.
I swear it's the fastest!: ~31,400 executions per second.

Ok. I want you all to note something. The "I swear it's the fastest!" test. That was me using:
JASS:
set FastFood[H2I(t)-0x100000]=Data

and
JASS:
local integer i=FastFood[H2I(GetExpiredTimer())-0x100000]


Key Timers 2 is faster. :nuts:
Key Timers 1 is in the vacinity of twice as fast.
Not to mention both are far, far more stable.
At this point in time, I can't imagine ever suggesting anyone use anything else. Except for 0.0 period timers.

There is a version 1.2 of KT2 coming some time, by the way. It won't improve the loop speed, just needs a little cleanup. :)

Edited: Version 1.01 of Timer Systems in Warcraft III has been released, including these results and their original test maps.

Edited again: Did another bench of TT, too. It averaged 31,900. Consistent with previous results. It's not just margin of error.
 
You'd better go an post this at wc3c.net, to increase popularity that is. ^^
Seems a decent system, though I have no idea how it would be faster than 0x100000 substraction since that is supposed to be the fastest...
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Blackveiled Blackveiled:
    count on it then cause you don't live that far from me hah
  • The Helper The Helper:
    really that is cool!
  • The Helper The Helper:
    Hey Tom I added a new Weird tag to the News Prefixes
  • The Helper The Helper:
    What is up Blackveiled?
  • Blackveiled Blackveiled:
    Chillin', lurkin'. :D
  • The Helper The Helper:
    I am working on a bunch of site projects right now doing a bunch of behind the scenes stuff and trying to clean up some stuff that I let slide when I got lazy with the site for a few years...
  • The Helper The Helper:
    Are you in Houston Blackveiled or just in Texas?
  • Blackveiled Blackveiled:
    Houston
  • Blackveiled Blackveiled:
    I've been living here since 2014.
  • The Helper The Helper:
    OK banlord we need to get together soon! The only other member of the site I know in Houston is XXX Conan
  • The Helper The Helper:
    and he does not want none lol
  • The Helper The Helper:
    he put up a picture of his mom one time and she was HOT!
  • The Helper The Helper:
    I wish we still had that
  • Blackveiled Blackveiled:
    Lmao you scared him off I see.
  • The Helper The Helper:
    he will be back
  • The Helper The Helper:
    Conan was like 12 when he started here
  • The Helper The Helper:
    I literally think I was his male role model
  • Blackveiled Blackveiled:
    Yeah I was 12 when I started here as well.
  • The Helper The Helper:
    you guys were just kids
  • The Helper The Helper:
    I was in my 30s when i got the Blizzard MVP
  • The Helper The Helper:
    I am 53
  • Wizard Wizard:
    Happy Birthday!
  • The Helper The Helper:
    not my birthday
  • The Helper The Helper:
    but thanks lol
  • Blackveiled Blackveiled:
    and I'll be 30 in January lmao

    Members online

    No members online now.

    Affiliates

    Hive Workshop NUON Dome World Editor Tutorials

    Network Sponsors

    Apex Steel Pipe - Buys and sells Steel Pipe.
    Top