• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[vJass] Timer Indexing System

I dunno if this is useful to anyone - it's basically a system which does the indexing of structs, in order to make MUI spells, for you. Anyway, here it is:

JASS:
library TimerSystem
    struct TimerLoop
        boolean stop = false
        stub method Loop takes nothing returns nothing
        endmethod
    endstruct
endlibrary

//! textmacro TimerSystem takes NAME, FPS
library TimerSystem_$NAME$ uses TimerSystem

private keyword Data

globals
    private real FPS = $FPS$
    private timer tim = CreateTimer()
    private Data array dat
    private integer index = 0
endglobals

private function Execute takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen i >= index
        
        call dat[i].ac.Loop
        
        if dat[i].ac.stop then
            call dat[i].destroy()
        endif
        
        set i = i + 1
    endloop
endfunction

private struct Data
    TimerLoop ac
    
    integer ID
    
    method create takes TimerLoop ac returns Data
        local Data d = Data.allocate()
        
        set d.ac = ac
        
        set dat[index] = d
        set d.ID = index
        
        if index == 0 then
            call TimerStart(tim, 1./FPS, true, function Execute)
        endif
        
        set index = index + 1
        
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call ac.destroy()
        
        set index = index - 1
        set dat[.ID] = dat[index]
        set dat[.ID].ID = .ID
        
        if index == 0 then
            call PauseTimer(tim)
        endif
    endmethod
endstruct

function $NAME$_Start takes TimerLoop ac returns nothing
    call Data.create(ac)
endmethod
    
endlibrary
//! endtextmacro

To use it, you simply run the textmacro above your spell scope with the name of your spell and whatever FPS you want, for example:

JASS:
//60 FPS for smooth movement
//! runtextmacro TimerSystem ("StormBolt", "60")

Now you need a data struct which extends TimerLoop and contains a method called "Loop", for example:

JASS:
private struct Data extends TimerLoop
    //you can store whatever data you want in the struct
    unit missile
    real x
    real y
    //the loop method
    method Loop takes nothing returns nothing
        set .x = .x + 10.
        set .y = .y + 10.
        call SetUnitPosition(.missile, .x, .y)
        
        if .x > 1000 and .y > 1000 then
            set .stop = true //set this.stop to true to destroy the struct and stop the spell
        endif
    endmethod
    //your struct may contain any number of other methods, including static methods
    static method create takes unit missile, real x, real y returns Data
        local Data d = Data.allocate()
        set d.missile = missile
        set d.x = x
        set d.y = y
        return d
    endmethod
endstruct

To start the spell, you simply do:

JASS:
//function name is $NAME$_Start ($NAME$ is the first textmacro parameter)
call StormBolt_Start(Data.create(u, 0., 0.) //you need to pass the data to the function.

I hope this helps some people. The difference in efficiency between using this system and coding the entire indexing system yourself should be menial. I personally think that this system is by far easier to use and more logical than coding the system yourself.
 
  • This will cause massive code bloat.
  • The FPS parameter should be named something else, your system won't automatically change the FPS to the given value.
  • This is really slow compared to the popular timer indexing systems ( O(n) search ftl. )
  • Why the hell would you want to use a textmacro for this? Why not just use a timer array with the same functions -_-
  • My first and third statement already give this enough to be graveyarded.

I'm sorry if any of the above statements sound offensive, but it's constructive criticism.

+1 vote for graveyard.
 
1. Code bloat? It makes your code shorter, that's why I made it.
2. I don't see what you mean. The FPS will be changed with the textmacro. I guess it should be constant, though.
3. Give me an example of another timer indexing system - I've never heard of one. How would you make the search anything other than O(n) and still have just 1 timer?
4. The point is it's one timer per spell. Therefore everything using that timer has to have the same FPS. I need a textmacro so I can have multiple FPS's for different spells.
5. Do you think this is meant to be like TimerUtils or something similar? Well, it's not. It's the fastest known method of making MUI vJass.
 
Code bloat? It makes your code shorter, that's why I made it.

Do you know what a textmacro even does?

It copies text, basically. So for every spell or whenever you use this your adding 66 lines of code.

I don't see what you mean. The FPS will be changed with the textmacro. I guess it should be constant, though.

So If I have a shitty computer, and I ~10 fps at all times, using this will magically increase it to 60?

Probably not, thats why you should change it.

Give me an example of another timer indexing system - I've never heard of one. How would you make the search anything other than O(n) and still have just 1 timer?

Theres to oh-so popular offset subtraction. (H2I-offset)

That will give you a small enough number to fit into an array.

You can also use the hashtable functions.

call SaveInteger(hash, GetHandleId(YourTimer), 0, index)
...
...
call LoadInteger(hash, GetHandeId(GetExpiredTimer()), 0)


Do you think this is meant to be like TimerUtils or something similar? Well, it's not. It's the fastest known method of making MUI vJass.

This is defiantly not the fasted known method for attaching timers in JASS.

If thats not what you meant, sorry.
 
Do you know what a textmacro even does?

It copies text, basically. So for every spell or whenever you use this your adding 66 lines of code.
Yes, I know what a textmacro does, and that doesn't count as code bloat, as you can't ever see the code in the trigger editor. If you think 66 lines will have any noticeable impact on map size, you're wrong.

So If I have a shitty computer, and I ~10 fps at all times, using this will magically increase it to 60?

Probably not, thats why you should change it.
The FPS is merely how many times per second the timer runs.

Theres to oh-so popular offset subtraction. (H2I-offset)

That will give you a small enough number to fit into an array.

You can also use the hashtable functions.

call SaveInteger(hash, GetHandleId(YourTimer), 0, index)
...
...
call LoadInteger(hash, GetHandeId(GetExpiredTimer()), 0)
That is not a timer indexing system. It's a timer attachment system. There's a big difference. A timer attachment system is for attaching data to timers. A timer indexing system is for making spells such as missile spells which will move a dummy unit a little bit x times every second (this is where FPS comes in).

This is defiantly not the fasted known method for attaching timers in JASS.

If thats not what you meant, sorry.
That's not what I meant. It's the fastest Timer Indexing method. Timer indexing != timer attachment.

You clearly don't understand exactly what this does, so please don't comment on it any more until you know what a timer indexing system is. This tutorial might help.
 
The FPS is merely how many times per second the timer runs.

Yes I know, but the name is misleading.

That's not what I meant. It's the fastest Timer Indexing method. Timer indexing != timer attachment.

You clearly don't understand exactly what this does, so please don't comment on it any more until you know what a timer indexing system is. This tutorial might help.

I understand what it does, I just misread the thread and didn't examine the code.
 
Top