System Periodic Module

Viikuna

No Marlo no game.
Reaction score
265
The only limitation I see, is that you can only have one of these per struct type, which can be solved by using different structs for different things.

edit. And of course periodic timers can never replace non-periodic timers, because iterating is not accurate enough, but using some TimerStack kinda solves this problem.
 

emjlr3

Change can be a good thing
Reaction score
395
sorry, missed the setperiod at the way bottom line there, nvm then
 

Romek

Super Moderator
Reaction score
963
> Anyways, I still like my own more. Its has nicer variable names.
I actually hate the way you name your struct members. :p
integer integer, array array, unit unit.

I don't see why something like this wasn't done before either. With 'extends' instead of with modules.
 

Cohadar

master of fugue
Reaction score
209
that might actually be better IMO
Not possible, sorry.

This is not a replacement for "normal" timer systems.
I don't even plan on using this, but seeing how a lot of people seems hot for the idea I thought it is better to join Jesus4Lyf the Savior before this all goes to hell and everyone starts submitting spells with their own timer modules.

We have enought timer problems as it is.

I don't see why something like this wasn't done before either. With 'extends' instead of with modules.

It was (gy grim001 I think)

======================
@Jesus4Lyf
Would you please add some header for that module, you know the big ones I like :)
 

Viikuna

No Marlo no game.
Reaction score
265
> Anyways, I still like my own more. Its has nicer variable names.
I actually hate the way you name your struct members.
integer integer, array array, unit unit.

But I like how TheHelpers Jass tags make my code look all blue&yellow.
Makes me feel happy.

I don't see why something like this wasn't done before either. With 'extends' instead of with modules.

Im sure there is some good reason for that. I just dont know what it is..
 

emjlr3

Change can be a good thing
Reaction score
395
I cant say I am a fan of the modules name

and the thread title doesnt describe it well either
 

Cohadar

master of fugue
Reaction score
209
Any particular preferences? Personally, I think it's fine. And I thought the thread name said exactly what's here.

>add some header
Done.

Err you do realize you need to actually put this module inside of a library?
And please no short names like PM, make it PeriodicModule

In scopes you will not need to know library name but in libraries you will:
JASS:

library BlahBlah requires PeriodicModule


Someone change the thread title to Periodic Module please.

==========================================
Which of the following actually work?
JASS:

call SetUnitX(.u, GetUnitX(.u) + 100.0* Periodic_PERIOD )


JASS:

call SetUnitX(.u, GetUnitX(.u) + 100.0* this.PERIOD )


JASS:

call SetUnitX(.u, GetUnitX(.u) + 100.0* Data.PERIOD )
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Which of the following actually work?

This one? (Great, answer a question with a question! :p)

JASS:
call SetUnitX(.u, GetUnitX(.u) + 100.0* Data.PERIOD )


Nice looking timer system, very simple and efficient. You might be able to cut a little more time out by making that "local integer i" a global.
 

Viikuna

No Marlo no game.
Reaction score
265
Wouldnt StaticTimerMember be a better name? Or PeriodicActionsModule ?

Short names work nicely for systems, but not for modules..
 

Jesus4Lyf

Good Idea™
Reaction score
397
>call SetUnitX(.u, GetUnitX(.u) + 100.0* this.PERIOD )
That one should be it. (Fixed in my post.)
Added the library.

>Wouldnt StaticTimerMember be a better name? Or PeriodicActionsModule ?

Simplicity is pleasant.

As for the local i thing... Hmmmmmmm. What do you think, Cohadar? Lol... Can you actually put it in the library as a private global and have the module access it? Or would that screw up. (How textmacro are modules?)
 

Cohadar

master of fugue
Reaction score
209
Who said globals are faster than locals?

JASS:

//~~ PM ~~ Periodic Module ~~ By Jesus4Lyf & Cohadar ~~ Version 1.01 ~~

Delete that PM, PM is private name for implementation variables it has no business in header
 

SerraAvenger

Cuz I can
Reaction score
234
> Anyways, I still like my own more. Its has nicer variable names.
I actually hate the way you name your struct members. :p
integer integer, array array, unit unit.

I don't see why something like this wasn't done before either. With 'extends' instead of with modules.

I did it. And yes, before this. But not that long, by the time I uploaded my first (and quite simple) spell template I didn't have the new JassHelper, which meant my map would not compile using stub methods. I coded one free hand, which didn't work as intended as I learnt after patching. Thus I fixed the way a couple of things work, but seeing the spell template as graveyarded I didn't upload a new version.

Here is a map that uses it - look in the spells folder.
It is a fixed version of the spell template I uploaded to th.
 

Attachments

  • Krusade.w3x
    274.5 KB · Views: 256

Jesus4Lyf

Good Idea™
Reaction score
397
In your map...
JASS:
static method getIndex takes timer t returns integer
    return ModuloInteger( H2I( t ) - 0x01000000, 8000 )
endmethod

I lol'd. That's a dodgey indexing method for so many reasons.

But you use one timer per instance. I'm pretty sure that's not what Romek meant. The problem with extending structs with a timer loop like PeriodicModule, I believe, is I'm pretty sure it would compile to TriggerExecute or TriggerEvaluate, whichever it is that it does. Which defeats the purpose.

>Who said globals are faster than locals?
Actually, I did. Not that they're faster once declared, but I found that "local integer i=2" takes twice as long as "set I=2". Other people may feel free to benchmark this too... It's a stupid optimisation as I always say, but it's there...
 

Cohadar

master of fugue
Reaction score
209
"local integer i=2" takes twice as long as "set I=2". Other people may feel free to benchmark this too... It's a stupid optimisation as I always say, but it's there...

Did you perhaps test this speed diff in multiplayer? mhhhhm.
 

Viikuna

No Marlo no game.
Reaction score
265
Local variables dont take any syncing and net traffic? Thats might indeed change the situation..
 

SerraAvenger

Cuz I can
Reaction score
234
In your map...
JASS:
static method getIndex takes timer t returns integer
    return ModuloInteger( H2I( t ) - 0x01000000, 8000 )
endmethod

I lol'd. That's a dodgey indexing method for so many reasons.
Usually, I don't do that - but as the timer never gets destroyed, I think it was okay.

But you use one timer per instance. I'm pretty sure that's not what Romek meant. The problem with extending structs with a timer loop like PeriodicModule, I believe, is I'm pretty sure it would compile to TriggerExecute or TriggerEvaluate, whichever it is that it does. Which defeats the purpose.

Ouch, that might be true.

>Who said globals are faster than locals?
Actually, I did. Not that they're faster once declared, but I found that "local integer i=2" takes twice as long as "set I=2". Other people may feel free to benchmark this too... It's a stupid optimisation as I always say, but it's there...

um...
no?

I think whether locals are faster than globals depends on how they're implemented.
If I remember correctly, locals are created on the stack (sloooow for huge n) while globals are created on the heap (much faster).

If blizz did it that way, globals will be really faster - given that you the same number of locals. You can (in the worst case and given a weak heap tree) gave const * 10^(n) global variables for n local variables and it would still be somewhat equal.
 

Romek

Super Moderator
Reaction score
963
There's no need to prefix your members in the module. IIRC, private struct members within modules can only be accessed within the module, not in the struct that implemented the module.
Also, PERIOD could be constant. I don't see a reason why anybody would change that to anything else. Especially as it has to be high frequency.

> thistype(.PM_Data).periodic()
.PM_Data is already of type 'thistype', so there's no need to typecast.

And you're not using index 0. :)
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Did you perhaps test this speed diff in multiplayer? mhhhhm.
Nup. Did you?

>Local variables dont take any syncing and net traffic? Thats might indeed change the situation..
Global variables don't either. Your point? (I hear you can even store GetLocalPlayer() in a global just for an optimisation. But I know for sure in my maps I've had globals with different values for each player...)

>... const * 10^(n) global variables for n local variables...
*Shrugs* Lost me good. :D
Lol, you're only gonna ever have about 5 locals anyway.

>PERIOD could be constant
Pretty sure you wouldn't be able to set it on init then, which means every struct type would be forced to have the same period...

>I don't see a reason why anybody would change that to anything else.
Some people don't like 0.03125. I know, I call them crazy too. :p

>.PM_Data is already of type 'thistype', so there's no need to typecast.
Whilst I'm fully aware of that, I found that if I excluded that I got compile errors (although I'm not actually using .G.x yet). It should inline anyway.

>And you're not using index 0.
Personal preference is not to, for various reasons. Does this particularly annoy you (or anyone)?

PS.
>Usually, I don't do that - but as the timer never gets destroyed, I think it was okay.
Allow me to explain a little further.
JASS:
return ModuloInteger( H2I( t ) - 0x01000000, 8000 )

Aside from the instability you'll hear me constantly warning people about...
  • 0x01000000 should be 0x100000?
  • 0x100000 shouldn't even be in there as you take modulo anyway, making it redundant.
  • 8000 should be 8190, and I really would want to extend to 8190 to give this every chance of stability its got going for it.
  • ModuloInteger could be inlined. This stops the function from inlining, but it's still more efficient than the BJ because it doesn't check negative.
And then you have the usual "Unstable! Unstable!" cries because there's no collision detection in your hash. :p
 

SerraAvenger

Cuz I can
Reaction score
234
>Did you perhaps test this speed diff in multiplayer? mhhhhm.
Nup. Did you?

>Local variables dont take any syncing and net traffic? Thats might indeed change the situation..
Global variables don't either. Your point? (I hear you can even store GetLocalPlayer() in a global just for an optimisation. But I know for sure in my maps I've had globals with different values for each player...)

Ummmm....
Yes, that's true. I use a global LOCAL_PLAYER.
Globals, just like locals, are on the local memory, not on the shared memory, it seems :D

>... const * 10^(n) global variables for n local variables...
*Shrugs* Lost me good. :D
Lol, you're only gonna ever have about 5 locals anyway.
5 locals = about const*10000 globals.
heap search does log(n) at worst case, iterative stack search does n at worst case.
And if Blizz was clever, they used a fibonacci tree, which means CONSTANT look-up time.
And even if the implementation is so wierd that const = 0.1, that's still 1000 globals.

>Usually, I don't do that - but as the timer never gets destroyed, I think it was okay.
Allow me to explain a little further.
JASS:
return ModuloInteger( H2I( t ) - 0x01000000, 8000 )

Aside from the instability you'll hear me constantly warning people about...
  • 0x01000000 should be 0x100000?
  • 0x100000 shouldn't even be in there as you take modulo anyway, making it redundant.
  • 8000 should be 8190, and I really would want to extend to 8190 to give this every chance of stability its got going for it.
  • ModuloInteger could be inlined. This stops the function from inlining, but it's still more efficient than the BJ because it doesn't check negative.
And then you have the usual "Unstable! Unstable!" cries because there's no collision detection in your hash. :p
Thanks for that list :)
  • 0x01000000 should be 0x100000? I like it more when it are 2³ symbols after the 0x instead of 7. It just looks better to me :/
  • 0x100000 shouldn't even be in there as you take modulo anyway, making it redundant. That's true.
  • 8000 should be 8190, and I really would want to extend to 8190 to give this every chance of stability its got going for it. I will change the hashing method then. Perhaps using my attacher (doublehashing)
  • ModuloInteger could be inlined. This stops the function from inlining, but it's still more efficient than the BJ because it doesn't check negative. Using the stupid -0x01000000, this was necessary. I'll change the whole thing though.
What was important to me in that situation, though, was that the system worked : )
 
General chit-chat
Help Users

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top