Jesus4Lyf
Good Idea™
- Reaction score
- 397
A standard timer loop module. Written by Cohadar and myself.
Here's a well optimised and standardised timer loop module.
Demonstration:
Here's a well optimised and standardised timer loop module.
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Periodic Module ~~ By Jesus4Lyf & Cohadar ~~ Version 1.01 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Periodic Module?
// - Periodic Module is a module that implements a fully optimised timer
// loop for a struct.
// - Instances can be added to the loop, which will call .periodic every
// PERIOD until it returns true.
//
// =Pros=
// - Efficient.
// - Standardised.
//
// =Cons=
// - Only allows one period and periodic function per struct type.
// - Inaccurate for higher periods.
// - The called method must be named ".periodic".
//
// Methods:
// - struct.startPeriodic()
// - structtype.setPeriod(real period)
// Only call setPeriod on initialisation.
//
// - private method periodic takes nothing returns boolean
//
// This must be defined in structs that implement Periodic Module.
// It will be executed by the module every PERIOD until it returns true.
//
// Details:
// - Uses one timer per struct type that iterates through all "started" instances.
//
// - While .periodic() returns false the timer will continue to call it each period
// Once .periodic() returns true the instance will be excluded from iteration.
//
// - When there are no active instances, the timer for that struct type will
// pause itself.
//
// How to import:
// - Create a trigger named PM.
// - Convert it to custom text and replace the whole trigger text with this.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library PeriodicModule
module Periodic
private static timer PM_Timer=CreateTimer()
private static integer PM_DataMax=0
private static thistype array PM_Data
static real PERIOD=0.03125
private static method PM_PeriodicLoop takes nothing returns nothing
local integer i=.PM_DataMax
loop
exitwhen i==0
if thistype(.PM_Data<i>).periodic() then
set .PM_Data<i>=.PM_Data[.PM_DataMax]
set .PM_DataMax=.PM_DataMax-1
endif
set i=i-1
endloop
if .PM_DataMax==0 then
call PauseTimer(.PM_Timer)
endif
endmethod
method startPeriodic takes nothing returns nothing
set .PM_DataMax=.PM_DataMax+1
set .PM_Data[.PM_DataMax]=this
if .PM_DataMax==1 then
call TimerStart(.PM_Timer,.PERIOD,true,function thistype.PM_PeriodicLoop)
endif
endmethod
static method setPeriod takes real period returns nothing // Only call on intialisation.
set .PERIOD=period
endmethod
endmodule
endlibrary
</i></i>
Demonstration:
JASS:
scope Test initializer Init
//===========================================================================
struct Data
unit u
// lowercase
private method periodic takes nothing returns boolean // <-------<<
call SetUnitX(.u, GetUnitX(.u) + 100.0* this.PERIOD )
if ( GetUnitX(.u) >= 5000) then
call this.destroy()
return true
endif
return false
endmethod
implement Periodic // <-------<<
static method create takes unit u returns Data
local Data data= Data.allocate()
set data.u = u
call data.startPeriodic() // <-------<<
return data
endmethod
endstruct
//===========================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trig, Condition( function Conditions ) )
call TriggerAddAction( trig, function Actions )
// optional
call Data.setPeriod(0.04) // <-------<<
endfunction
endscope