GFreak45
I didnt slap you, i high 5'd your face.
- Reaction score
- 130
DISCLAIMER: I have not completed this yet and have not yet had a chance to compile check it, that will be done tonight when i get home from work, till then if it does not compile there isnt much i can do 
I will update the code tonight when i compile check it and adjust it accordingly
I will update the code tonight when i compile check it and adjust it accordingly
JASS:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* TimerCompressor - v1.00 *
* by G_Freak45/GFreak45 *
* *
* Requires: *
* Jass Newgen/Jass Helper *
* *
* http://www.thehelper.net/forums/showthread.php/169675-TimerCompressor *
* -Library?p=1389329#post1389329 (sorry about the cut up link) *
* *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Implementation: *
* Create a new trigger named StrategicTimer *
* Edit -> Convert to custom text *
* Delete the inside and replace with this code *
* *
* *
* Positives: *
* *
* Replaces timer handle/timer variables with integers so no leaks *
* ie: local integer t = StartTimer(5.0, null) *
* *
* Combines all timers into a single one by starting it with *
* varying times depending on the next timer to finish *
* *
* Replaces common.j functions with slight variations so no major *
* changes to the game other than efficiency *
* *
* Allows you to create periodic timers that expire after X times *
* of running the code *
* *
* *
* Negatives: *
* *
* Trigger Evaluation is required to run the code *
* *
* Is not made for high frequency timers repeating timers (anything *
* under 0.5 seconds, Timer32 is recommended for that) *
* *
* Functions used as code MUST NOT take arguments because they are *
* saved as boolexpr's seeing as code variables can not be arrays *
* *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* API: *
* *
* function GetLastExpiredTimer takes nothing returns integer *
* -pretty self explanatory *
* *
* *
* function GetLastDestroyedTimer takes nothing returns integer *
* -also pretty self explanatory *
* *
* *
* function StartTimer takes real timeout, code c returns integer *
* -used to start a basic timer, the integer return is the ID of the *
* timer *
* *
* *
* function StartPeriodicTimer takes real timeout, integer periodcount, *
* code c, returns integer *
* -used to start a periodic timer, if you want it to be a constant *
* periodic (never ending) use 0 as periodcount, otherwise it will *
* countdown from that number running c every time, this does not *
* run on 0 so use the exact count you want *
* *
* *
* function TimerDestroy takes integer t returns nothing *
* -destroys the timer using the timer's id, there should be almost *
* no need for this, thats an almost. *
* *
* *
* function TimerPause takes integer t returns nothing *
* -pauses the timer, this replaces the PauseTimer function *
* *
* *
* function TimerUnpause takes integer t returns nothing *
* -unpauses a paused timer *
* *
* *
* function TimerPauseAll takes nothing returns nothing *
* -pauses all timers, just for completeness *
* *
* *
* function TimerChangeCode takes integer t, code c returns nothing *
* -replaces the current code for the timer with a new one *
* *
* *
* function FinishTimer takes integer t returns nothing *
* -completes whatever duration is left on the timer, replaces call *
* TimerStart(timer, 0, false, code) *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
library TimerCompressor
private struct TC extends array
real totalTime
real startTime
real timeLeft
boolean periodic
boolean paused
conditionfunc func
integer periodcount
integer next
integer previous
static integer array recycleList
static integer lastRecycled
private static integer listSize
static integer lastExpiredTimer
static integer lastDestroyedTimer
private static trigger tcTrig = CreateTrigger()
static timer tcTimer = CreateTimer()
private static method allocation takes nothing return thistype
local thistype this = .recycleList[0]
if this == 0 then
debug if .listSize >= 8190 then
debug call BJDebugMsg("TimerCompressor Error: You have attempted to create too many timers at one time.")
debug return 0
debug endif
set .listSize = .listSize + 1
return .listSize
endif
set .recycleList[0] = .recycleList[this]
set .recycleList[this] = 0
return this
endmethod
method deallocate takes nothing returns nothing
set thistype(this.previous).next = this.next
set thistype(this.next).previous = this.previous
set lastDestroyedTimer = this
set .recycleList[.lastRecycled] = this
set .lastRecycled = this
endmethod
method callCondition takes nothing returns nothing
call TriggerClearConditions(tcTrig)
call TriggerAddCondition(tcTrig, this.func)
call TriggerEvaluate(tcTrig)
endmethod
method startTimer takes real timeout, boolean periodic, integer periodcount, conditionfunc c returns integer
local thistype i = thistype(thistype(0).next).next
local real time = TimerGetRemaining(.tcTimer)
if thistype(0).next != 0 and timeout >= time then
loop
exitwhen time + i.startTime >= timeout
set time = time + i.startTime
exitwhen i.next = 0
set i = i.next
endloop
set this.next = i.next
set this.previous = i
set thistype(i.next).startTime = thistype(i.next).startTime - (timeout - time)
set this.startTime = timeout - time
set i.next = this
set thistype(this.next).previous = this
set this.periodic = periodic
set this.totalTime = timeout
set this.func = c
elseif thistype(0).next != 0 then
call TimerStart(.tcTimer, timeout, false, function thistype.timerExpire)
set i = thistype(0).next
set i.startTime = time - timeout
set i.previous = this
set this.next = thistype(0).next
set this.previous = 0
set thistype(0).next = this
set this.startTime = timeout
set this.totalTime = timeout
set this.periodic = periodic
set this.func = c
else
call TimerStart(.tcTimer, timeout, false, function thistype.timerExpire)
set this.next = 0
set this.previous = 0
set thistype(0).next = this
set thistype(0).previous = this
set this.startTime = timeout
set this.totalTime = timeout
set this.periodic = periodic
set this.func = c
endif
endmethod
static method timerExpire takes nothing returns nothing
local thistype this = thistype(0).next
set lastExpiredTimer = this
call TimerStart(.tcTimer, thistype(this.next).startTime, false thistype.timerExpire)
call this.callCondition
set thistype(this.next).previous = this.previous
set thistype(0).next = this.next
if this.periodic and this.periodCount - 1 != 0 then
if this.periodCount - 1 < 0 then
call this.startTimer(this.totalTime, this.periodic, 0, this.func)
else
call this.startTimer(this.totalTime, this.periodic, this.periodCount - 1, this.func)
endif
else
call this.deallocate()
endif
endmethod
method pauseTimer takes nothing returns nothing
local real time = TimerGetRemaining(.tcTimer)
local thistype i = thistype(0).next
if thistype(0).next != this then
loop
exitwhen i == 0
set time = time + i.startTime
exitwhen i == this
set i = i.next
endloop
set this.timeLeft = time
set thistype(this.next).startTime = thistype(this.next).startTime + this.startTime
set thistype(this.next).previous = this.previous
set thistype(this.previous).next = this.next
else
set this.timeLeft = time
set thistype(0).next = 0
set thistype(0).previous = 0
call PauseTimer(.tcTimer)
endif
endmethod
endstruct
function GetLastExpiredTimer takes nothing returns integer
return TC.lastExpiredTimer
endfunction
function GetLastDestroyedTimer takes nothing returns integer
return TC.lastDestroyedTimer
endfunction
function StartTimer takes real timeout, code c returns integer
local TC this = TC.allocation
call this.startTimer(timeout, false, 0, Filter(c))
return this
endfunction
function StartPeriodicTimer takes real timeout, integer periodcount, code c returns integer
local TC this = TC.allocation
call this.startTimer(timeout, true, periodcount, Filter(c))
return this
endfunction
function TimerDestroy takes integer t returns nothing
if t != TC(0).next then
set TC(TC(t).next).startTime = TC(TC(t).next).startTime + TC(t).startTime
call TC(t).deallocate()
else
call StartTimer(TC.tcTimer, TimerGetRemaining(TC.tcTimer) + TC(TC(t).next).startTime, false, function TC.timerExpire)
call TC(t).deallocate()
endif
endfunction
function TimerPause takes integer t returns nothing
call TC(t).pauseTimer()
set TC(t).paused = true
endfunction
function TimerUnpause takes integer t returns nothing
if TC(t).paused then
call TC(t).startTimer(TC(t).timeLeft, TC(t).periodic, TC(t).func)
set TC(t).paused = false
debug else
debug call BJDebugMsg("TimerCompressor Error: You have attempted to unpause a timer that is not paused.")
endif
endfunction
function TimerPauseAll takes nothing returns nothing
call PauseTimer(TC.tcTimer)
endfunction
function TimerChangeCode takes integer t, code c returns nothing
set TC(t).func = Filter(c)
endfunction
function FinishTimer takes integer t returns nothing
if TC(0).next = t
call TimerStart(TC.tcTimer, 0, false, TC.timerExpire)
else
call TC(t).callCondition()
set TC(TC(t).next).startTime = TC(TC(t).next).startTime + TC(t).startTime
if TC(t).periodic then
call TC(t).startTimer(TC(t).totalTime, TC(t).periodic, TC(t).func)
else
call TC(t).deallocate()
endif
endif
endfunction
endlibrary