- Joined
- Apr 30, 2011
- Messages
- 359
The System + Documentation:
JASS:
/*
/\ /\
][======================================================================][
|| I. TABLE OF CONTENTS ||
][======================================================================][
\/ \/
// Talking about the system
I.,,,,,,Table of Contents
II.,,,,,Introduction
III.,,,,Description
A.,,,,,,Requirements
B.,,,,,,Pros
C.,,,,,,Cons
D.,,,,,,Executables and Constants
E.,,,,,,How the System Works
IV.,,,,,Usages (Using TimedFunc)
A.,,,,,,Simple Usages
B.,,,,,,Complex Usage
// The system itself
V.,,,,,,The System
A.,,,,,,Calibration Section
B.,,,,,,Module TimedStruct
a.,,,,,,Variables
b.,,,,,,Contents
C.,,,,,,Premade Struct: TimedFunc
a.,,,,,,The Functions Format
b.,,,,,,The Struct
VI.,,,,,Conclusion and Final Notes
*/
/*
/\ /\
][======================================================================][
|| II. INTRODUCTION ||
][======================================================================][
\/ \/
// Timed Object
// -*- overcold_ice -*-
//
// This system enables users to bring their timed struct (either
// delayed, or looping) in an accurate time. Normally they would use
// timers for those things, but those will end up confusing or something
// else. The worst case is using TriggerSleepActions, 100% inaccurate,
// but in exchange, making the code easier to read and write.
// The best case is using structs. Mostly, looping structs use only
// one timer, which end up in a bad, inaccurate codes. Let's see this
// example:
struct example
timer t = CreateTimer()
real a = 0
example array index [8190]
integer total = 0
method onLoop takes nothing returns nothing
local integer i = 1
local integer m = .total
loop
exitwhen i == m
set .index [i].a = .index [i].a * 2
set i = i + 1
endloop
endmethod
method start takes real inita returns nothing
local thistype that = thistype.create()
set that.a = inita
set .total = .total + 1
set .index [.total] = that
if .total == 1 and TimerGetRemaining(.t) == 0 then
call TimerStart(.t, 0.5, true, function thistype.onLoop)
endif
call that.destroy()
endmethod
endstruct
// That struct above let us to increase a real every 0.5 sec, the
// increments are equal to the real itself (in other way, the value
// doubles for every 0.5 sec). If we look closer, the struct isn't
// accurate, look at this example:
struct multipled extends example
method doubled takes real r1, r2 returns nothing
call .start(r1)
call TriggerSleepAction(0.25) // no more complication
// for the sake of example
call .start(r2)
endmethod
endstruct
// The struct runs the effect twice, once after another, but within
// a 0.25 sec delay, but they will both have their values doubled at the
// same time (no 'almost', just in an order), rather with a 0.25 sec
// delay. This is an inaccurate example.
// Because of those inaccurations, here comes the Timed Object
// System. This system lets you to do delayed, or even looping functions
// with so much ease. It even has some sort of index (thanks to TimerUtils),
// allowing you to index structs with it.
*/
/*
/\ /\
][======================================================================][
|| II. DESCRIPTION ||
][======================================================================][
\/ \/
]||[===------
|A.| //Requirements
]||[===------
This System requires the following systems:
* TimerUtils (by Vexorian)
]||[===------
|B.| //Pros
]||[===------
// Both TimedStruct and TimedFunc
* 100% Accurate
* Useful for both Simple and Complex Usages
]||[===------
|C.| //Cons
]||[===------
// Both
* Can use too much timers, with a maximum of 8190
// TimedFunc
* Can heavily increases your Map Size, because of the use of
function interface
* Slow, because the use of .evaluate()
]||[===------
|D.| //Executables and Constants
]||[===------
// globals
* private boolean ENABLE_ONRUN = false
* private boolean ENABLE_TIMEDFUNC = true
// the name already self-explanatory, ENABLE_ONRUN lets you enable/disable
// the use of onRun method (it runs right when the timer started, seldomly
// used, I think). ENABLE_TIMEDFUNC allows you to enable/disable the Timed
// Function, since it has many cons
// module TimedStruct
* call YourStruct.Run(real time) (returns nothing)
// used to start the timer, use onExpire(takes nothing returns boolean)
// method to specify the action runt on expiration. If it returns false,
// the timer will stop, otherwise it will restart
* call YourStruct.IndexStruct (takes nothing) (returns nothing)
// used to assign current running struct (.Struct) into the index, saving it
// needed in YourStruct (else it'll pop ups an error)
* private static method onExpire (takes nothing) (returns boolean)
// this method runs when the system's timer expire, it returns false
// by default
* private static method onRun (takes nothing) (returns nothing)
// this method runs when the system's timer started (only at the beginning,
// not during restarts), this method can be disabled (see above)
* readonly static timer YourStruct.Expired = GetExpiredTimer()
* readonly static integer YourStruct.Value = GetTimerData(timer)
* readonly static YourStruct YourStruct.Struct = Running Struct
// those are the event responses, .Expired = GetExpiredTimer(), self-
// explanatory. .Value is the unique number of current running struct,
// .Struct is the current struct running. .Value and .Struct can be gotten
// right after YourStruct.Run method. All of them can be gotten during
// onExpire methods
// premade struct TimedFunc
* public function interface TimedFunction takes nothing returns boolean defaults false
// this is the functions format used by the system
* call TimedFunc.Start(real time, TimedFunction func) (returns nothing)
// real time = real timeout in timers
// TimedFunction func = your function that will be runt
// when the timer expire, you can
// set this to null, to make the
// system do nothing when the timer
// expire
// doing this will set TimedFunc.Value to whatever
// the timer value in this new one. use that to specify
// struct indexes
* TimedStruct constants
// explained above
]||[===------
|E.| //How the System Works
]||[===------
// Basically, it works like this:
* First, it checks all available spaces,
- if there are an empty space (the timer are not running), then do
- use that timer for the next actions
- if there are no empty spaces (whether the timers are all running, or not created at all), then do
- create a new timer for the next actions
* Second, it starts the timer and set TimedFunc.Value to whatever the current timer's value is
* Finally, when the timer expires, do
- static method onExpire(),
- if, it returns true, then restart the timer, otherwise, destroy it
*/
/*
/\ /\
][======================================================================][
|| IV. USAGES (USING TIMEDFUNC) ||
][======================================================================][
\/ \/
]||[===------
|A.| //Simple Usages
]||[===------
* Example 1:
library Initialization initializer Init requires TimedObject
function FOWDisable takes nothing returns boolean
call FogEnable(false)
return false
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(5, FOWDisable)
endfunction
endlibrary
// that library disables fog of war 5 seconds after initialization
library FreeGold initializer Init requires TimedObject
function Looping takes nothing returns boolean
local integer i = 0
local integer m = 11
loop
exitwhen i == m
call SetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD) + 1)
set i = i +1
endloop
return true
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(1, Looping)
endfunction
endlibrary
// this one adds one gold to player 1 - player 12 for every 1 second
]||[===------
|B.| //Complex Usage
]||[===------
* Example:
library MoveUnit requires TimedObject
globals
private Variables array V [8190]
endglobals
struct Variables
unit Moved
real x
real y
endstruct
private function Move takes nothing returns boolean
local integer i = TimedFunc.Value
call SetUnitX(V [i].Moved, V [i].x)
call SetUnitY(V [i].Moved, V [i].y)
return false
endfunction
function MoveUnit takes unit u, real x, real y, real delay returns nothing
local integer i
call TimedFunc.Start(delay, Move)
set i = TimedFunc.Value
set V [i].Moved = u
set V [i].x = x
set V [i].y = y
endfunction
endlibrary
// that one move the unit 'instantly' to X, Y after a delay
*/
/*
/\ /\
][======================================================================][
|| V. THE SYSTEM ||
][======================================================================][
\/ \/
*/
// Do Not Edit
// If you know what you are doing, do it
library TimedObject requires TimerUtils
/*=\
]||[===------
|A.| //Calibration Section
]||[===------
\=*/
globals
public constant boolean ENABLE_ONRUN = false
public constant boolean ENABLE_TIMEDFUNC = false
endglobals
/*=\
]||[===------
|B.| //Module TimedStruct
]||[===------
\=*/
module TimedStruct
/*=///===---
|a.| Variables
\=*///===---
// the timer
private static timer TS_t
// struct indexing system
private static thistype array Index [8190]
private static integer Total = 0
// event responses variables
readonly static timer Expired
readonly static integer Value
readonly static thistype Struct
/*=///===---
|b.| Contents
\=*///===---
private static method TS_onExpire takes nothing returns nothing
set .Expired = GetExpiredTimer()
set .Value = GetTimerData(.Expired)
set .Struct = .Index [.Value]
if not .Struct.onExpire() then
call ReleaseTimer(.Expired)
call .Index [.Value].destroy()
else
set .Index [.Value] = .Struct
endif
set .Struct = 0
set .Expired = null
set .Value = 0
endmethod
static method Run takes real time returns nothing
local integer a = 1
local integer b = .Total + 1
local integer i = 0
loop
exitwhen a == b
if .Index [a] == 0 then
set i = a
set a = b
endif
set a = a + 1
endloop
if i == 0 then
set .Total = .Total + 1
set i = .Total
endif
set .Index [i] = .create()
set .Index [i].TS_t = NewTimerEx(i)
call TimerStart(.Index [i].TS_t, time, true, function thistype.TS_onExpire)
set .Value = i
set .Struct = .Index [i]
static if ENABLE_ONRUN then
call .Struct.onRun()
endif
endmethod
static method IndexStruct takes nothing returns nothing
set .Index [.Value] = .Struct
endmethod
endmodule
/*=\
]||[===------
|C.| //Premade Struct: TimedFunc
]||[===------
\=*/
static if ENABLE_TIMEDFUNC then
/*=///===---
|a.| The Functions Format
\=*///===---
public function interface TimedFunction takes nothing returns boolean defaults false
/*=///===---
|b.| The Struct
\=*///===---
struct TimedFunc
implement TimedStruct
private static integer f
private static method onExpire takes nothing returns boolean
if TimedFunction(.Struct.f).evaluate() then
return true
endif
return false
endmethod
static method Start takes real time, TimedFunction func returns nothing
call .Run(time)
set .Struct.f = func
call .IndexStruct()
endmethod
endstruct
endif
endlibrary
/*
/\ /\
][======================================================================][
|| VI. CONCLUSION AND FINAL NOTES ||
][======================================================================][
\/ \/
// Timed Object
// -*- overcold_ice -*-
//
// Please apologize me if there are mistakes, or something else that make
// you hurt. We have reached the end of the page, I hope you understand my
// really long documentation. Don't forget to put me in your Credits list
// if you use this system. If you want to edit this system, feel free to do
// that. But don't publish it without my permission, okay?
// You can remove these whole documentation. Enjoy and happy coding ^.^!
*/
v1:
v2:
JASS:
/*
/\ /\
][======================================================================][
|| I. TABLE OF CONTENTS ||
][======================================================================][
\/ \/
// Talking about the system
I.,,,,,,Table of Contents
II.,,,,,General Description
III.,,,,Specific Description
A.,,,,,,Requirements
B.,,,,,,Pros
C.,,,,,,Cons
D.,,,,,,Executables and Constants
E.,,,,,,How the System Works
IV.,,,,,Usage
A.,,,,,,Simple Usages
B.,,,,,,Complex Usages
// The system itself
V.,,,,,,The System
A.,,,,,,The Function Format (function interface)
B.,,,,,,The Struct (struct TimedFunc)
a.,,,,,,Variables
b.,,,,,,UC - Storage (UC: User-Customizeable)
c.,,,,,,Contents
VI.,,,,,Conclusion and Final Notes
*/
/*
/\ /\
][======================================================================][
|| II. GENERAL DESCRIPTION ||
][======================================================================][
\/ \/
// Timed Function
// -*- overcold_ice -*-
//
// This system enables users to bring their timed function (either
// delayed, or looping) in an accurate time. Normally they would use
// timers for those things, but those will end up confusing or something
// else. The worst case is using TriggerSleepActions, 100% inaccurate,
// but in exchange, making the code easier to read and write.
// The best case is using structs. Mostly, looping structs use only
// one timer, which end up in a bad, inaccurate codes. Let's see this
// example:
struct example
timer t = CreateTimer()
real a = 0
example array index [8190]
integer total = 0
method onLoop takes nothing returns nothing
local integer i = 1
local integer m = .total
loop
exitwhen i == m
set .index [i].a = .index [i].a * 2
set i = i + 1
endloop
endmethod
method start takes real inita returns nothing
local thistype that = thistype.create()
set that.a = inita
set .total = .total + 1
set .index [.total] = that
if .total == 1 and TimerGetRemaining(.t) == 0 then
call TimerStart(.t, 0.5, true, function thistype.onLoop)
endif
call that.destroy()
endmethod
endstruct
// That struct above let us to increase a real every 0.5 sec, the
// increments are equal to the real itself (in other way, the value
// doubles for every 0.5 sec). If we look closer, the struct isn't
// accurate, look at this example:
struct multipled extends example
method doubled takes real r1, r2 returns nothing
call .start(r1)
call TriggerSleepAction(0.25) // no more complication
// for the sake of example
call .start(r2)
endmethod
endstruct
// The struct runs the effect twice, once after another, but within
// a 0.25 sec delay, but they will both have their values doubled at the
// same time (no 'almost', just in an order), rather with a 0.25 sec
// delay. This is an inaccurate example.
// Because of those inaccurations, here comes the Timed Function
// System. This system lets you to do delayed, or even looping functions
// with so much ease. It even let you to store things within it, and
// it has some sort of index, allowing you to index structs with it.
*/
/*
/\ /\
][======================================================================][
|| II. SPECIFIC DESCRIPTION ||
][======================================================================][
\/ \/
]||[===------
|A.| //Requirements
]||[===------
This System requires the following systems:
* TimerUtils (by Vexorian)
]||[===------
|B.| //Pros
]||[===------
* Easy to use
* Useful for both Simple and Complex Usages
]||[===------
|C.| //Cons
]||[===------
* Missing some flexibility
]||[===------
|D.| //Executables and Constants
]||[===------
* function interface TimedFunc_TimedFunction takes nothing returns boolean defaults false
// this is the function format used by the system
* call TimedFunc.Start(real time, TimedFunction func) (returns nothing)
// real time = real timeout in timers
// TimedFunction func = your function that will be runt
// when the timer expire, you can
// set this to null, to make the
// system do nothing when the timer
// expire
// doing this will set TimedFunc.Value to whatever
// the timer value in this new one. use that to specify
// struct indexes
// Variable Storage system
* call TimedFunc.S$VariableType$(integer index, $Type$ data) (returns nothing)
// integer index = the index you want the data stored to
// $Type$ data = the value of a $Type$
// replace the $VariableType$ with a variable type, but with
// its first letter Capitalized, $Type$ is a variable type, not with
// any changes. Example:
//
// TimedFunc.SBoolean(integer index, boolean data) (returns nothing)
// it would be self explanatory
* call TimedFunc.L$VariableType$(integer index) (returns $Type$)
// integer index = the index you want the data loaded from
// a reversed version of above method, this one load it
* TimedFunc.Expired
// this constant is equal to GetExpiredTimer()
* TimedFunc.Value
// this constant is the unique number of the timer/system
// that currently runs. use this variable to index your structs
]||[===------
|E.| //How the System Works
]||[===------
// Basically, it works like this:
* First, it checks all available spaces,
- if there are an empty space (the timer are not running), then do
- use that timer for the next actions
- if there are no empty spaces (whether the timers are all running, or not created at all), then do
- create a new timer for the next actions
* Second, it starts the timer and set TimedFunc.Value to whatever the current timer's value is
* Finally, when the timer expires, do
- the function specified by the user,
- if, it returns true, then restart the timer, otherwise, destroy it
*/
/*
/\ /\
][======================================================================][
|| IV. USAGE ||
][======================================================================][
\/ \/
]||[===------
|A.| //Simple Usages
]||[===------
* Example 1:
library Initialization initializer Init requires TimedFunc
function FOWDisable takes nothing returns boolean
call FogEnable(false)
return false
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(5, FOWDisable)
endfunction
endlibrary
// that library disables fog of war 5 seconds after initialization
library FreeGold initializer Init requires TimedFunc
function Looping takes nothing returns boolean
local integer i = 0
local integer m = 11
loop
exitwhen i == m
call SetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD) + 1)
set i = i +1
endloop
return true
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(1, Looping)
endfunction
endlibrary
// this one adds one gold to player 1 - player 12 for every 1 second
]||[===------
|B.| //Complex Usages
]||[===------
* Example 1:
library MoveUnit requires TimedFunc
globals
private Variables array V [8190]
endglobals
struct Variables
unit Moved
real x
real y
endstruct
private function Move takes nothing returns boolean
local integer i = TimedFunc.Value
call SetUnitX(V [i].Moved, V [i].x)
call SetUnitY(V [i].Moved, V [i].y)
return false
endfunction
function MoveUnit takes unit u, real x, real y, real delay returns nothing
local integer i
call TimedFunc.Start(delay, Move)
set i = TimedFunc.Value
set V [i].Moved = u
set V [i].x = x
set V [i].y = y
endfunction
endlibrary
// that one move the unit 'instantly' to X, Y after a delay
* Example 2:
library Messaging requires TimedFunc
private function Display takes nothing returns boolean
call DisplayTimedTextToPlayer(LPlayer [1], 0, 0, 10, LString [1])
return false
endfunction
function DistantM takes unit s, unit t, string message, real speedfactor returns nothing
local real delay = DistanceBetweenPoints(GetUnitLoc(s), GetUnitLoc(t)) / 1000 * speedfactor
local string msg = "You Got a Message from " + GetPlayerName(GetOwningPlayer(s)) + ":\n" + message
call TimedFunc.Start(delay, Display)
call TimedFunc.SPlayer(1, GetOwningPlayer(t))
call TimedFunc.SString(1, msg)
endfunction
endlibrary
// a more complex library, it displays a game message to owner of unit t
// after a delay, the delay is based on how far the distance from unit s
// and unit t
*/
/*
/\ /\
][======================================================================][
|| V. THE SYSTEM ||
][======================================================================][
\/ \/
*/
library TimedFunc requires TimerUtils
/*=\
]||[===------
|A.| //The Function Format
]||[===------
\=*/
public function interface TimedFunction takes nothing returns boolean defaults false
/*=\
]||[===------
|B.| //The Struct
]||[===------
\=*/
struct TimedFunc
/*=///===---
|a.| Variables
\=*///===---
// timer + what it runs
private static timer t
private static integer f
// indexer system
private static TimedFunc array Index [8190]
private static integer Total = 0
// the constants
readonly static timer Expired
readonly static integer Value
/*=///===---
|b.| User Customizeable - Storage
\=*///===---
// the textmacro to make a storage
//! textmacro MAKE_STORAGE takes NAME, TYPE, VAR
private static $TYPE$ array $VAR$ [8190]
static method S$NAME$ takes integer index, $TYPE$ data returns nothing
set Index [.Value].$VAR$ [index] = data
endmethod
static method L$NAME$ takes integer index returns $TYPE$
return Index [.Value].$VAR$ [index]
endmethod
//! endtextmacro
// non-handle storages, shouldn't be removed
//! runtextmacro MAKE_STORAGE ("Boolean", "boolean", "b")
//! runtextmacro MAKE_STORAGE ("Integer", "integer", "i")
//! runtextmacro MAKE_STORAGE ("Real", "real", "r")
//! runtextmacro MAKE_STORAGE ("String", "string", "s")
// handle storages, can be removed/added
//! runtextmacro MAKE_STORAGE ("Effect", "effect", "haEFF")
//! runtextmacro MAKE_STORAGE ("Force", "force", "haFOR")
//! runtextmacro MAKE_STORAGE ("Group", "group", "haGRO")
//! runtextmacro MAKE_STORAGE ("Location", "location", "haLOC")
//! runtextmacro MAKE_STORAGE ("Player", "player", "haPLA")
//! runtextmacro MAKE_STORAGE ("Destructable", "destructable", "hawDES")
//! runtextmacro MAKE_STORAGE ("Unit", "unit", "hawUNI")
//! runtextmacro MAKE_STORAGE ("Item", "item", "hawITE")
//! runtextmacro MAKE_STORAGE ("Lightning", "lightning", "hLIG")
/*=///===---
|c.| Contents
\=*///===---
// Do Not Edit
// If you know what you are doing, do it
private static method onExpire takes nothing returns nothing
set .Expired = GetExpiredTimer()
set .Value = GetTimerData(.Expired)
if not TimedFunction(.Index [.Value].f).evaluate() then
call DestroyTimer(.Expired)
call .Index[.Value].destroy()
endif
set .Expired = null
set .Value = 0
endmethod
static method Start takes real time, TimedFunction func returns nothing
local integer a = 1
local integer b = .Total + 1
local integer i = 0
loop
exitwhen a == b
if .Index [a] == 0 then
set i = a
set a = b
endif
set a = a + 1
endloop
if i == 0 then
set .Total = .Total + 1
set i = .Total
endif
set .Index [i] = .create()
set .Index [i].f = func
set .Index [i].t = NewTimerEx(i)
call TimerStart(.Index [i].t, time, true, function thistype.onExpire)
set .Value = i
endmethod
endstruct
endlibrary
/*
/\ /\
][======================================================================][
|| VI. CONCLUSION AND FINAL NOTES ||
][======================================================================][
\/ \/
// Timed Function
// -*- overcold_ice -*-
//
// Please apologize me if there are mistakes, or something else that make
// you hurt. We have reached the end of the page, I hope you understand my
// really long documentation. Don't forget to put me in your Credits list
// if you use this system. If you want to edit this system, feel free to do
// that. But don't publish it without my permission, okay?
// You can remove these whole documentation. Enjoy and happy coding ^.^!
*/
v2:
JASS:
/*
/\ /\
][======================================================================][
|| I. TABLE OF CONTENTS ||
][======================================================================][
\/ \/
// Talking about the system
I.,,,,,,Table of Contents
II.,,,,,General Description
III.,,,,Specific Description
A.,,,,,,Requirements
B.,,,,,,Pros
C.,,,,,,Cons
D.,,,,,,Executables and Constants
E.,,,,,,How the System Works
IV.,,,,,Usage
A.,,,,,,Simple Usages
B.,,,,,,Complex Usages
// The system itself
V.,,,,,,The System
A.,,,,,,The Function Format (function interface)
B.,,,,,,The Struct (struct TimedFunc)
a.,,,,,,Variables
b.,,,,,,Contents
VI.,,,,,Conclusion and Final Notes
*/
/*
/\ /\
][======================================================================][
|| II. GENERAL DESCRIPTION ||
][======================================================================][
\/ \/
// Timed Function
// -*- overcold_ice -*-
//
// This system enables users to bring their timed function (either
// delayed, or looping) in an accurate time. Normally they would use
// timers for those things, but those will end up confusing or something
// else. The worst case is using TriggerSleepActions, 100% inaccurate,
// but in exchange, making the code easier to read and write.
// The best case is using structs. Mostly, looping structs use only
// one timer, which end up in a bad, inaccurate codes. Let's see this
// example:
struct example
timer t = CreateTimer()
real a = 0
example array index [8190]
integer total = 0
method onLoop takes nothing returns nothing
local integer i = 1
local integer m = .total
loop
exitwhen i == m
set .index [i].a = .index [i].a * 2
set i = i + 1
endloop
endmethod
method start takes real inita returns nothing
local thistype that = thistype.create()
set that.a = inita
set .total = .total + 1
set .index [.total] = that
if .total == 1 and TimerGetRemaining(.t) == 0 then
call TimerStart(.t, 0.5, true, function thistype.onLoop)
endif
call that.destroy()
endmethod
endstruct
// That struct above let us to increase a real every 0.5 sec, the
// increments are equal to the real itself (in other way, the value
// doubles for every 0.5 sec). If we look closer, the struct isn't
// accurate, look at this example:
struct multipled extends example
method doubled takes real r1, r2 returns nothing
call .start(r1)
call TriggerSleepAction(0.25) // no more complication
// for the sake of example
call .start(r2)
endmethod
endstruct
// The struct runs the effect twice, once after another, but within
// a 0.25 sec delay, but they will both have their values doubled at the
// same time (no 'almost', just in an order), rather with a 0.25 sec
// delay. This is an inaccurate example.
// Because of those inaccurations, here comes the Timed Function
// System. This system lets you to do delayed, or even looping functions
// with so much ease. It even let you to store things within it, and
// it has some sort of index, allowing you to index structs with it.
*/
/*
/\ /\
][======================================================================][
|| II. SPECIFIC DESCRIPTION ||
][======================================================================][
\/ \/
]||[===------
|A.| //Requirements
]||[===------
This System requires the following systems:
* TimerUtils (by Vexorian)
]||[===------
|B.| //Pros
]||[===------
* Easy to use
* Useful for both Simple and Complex Usages
]||[===------
|C.| //Cons
]||[===------
* Missing some flexibility
]||[===------
|D.| //Executables and Constants
]||[===------
* function interface TimedFunc_TimedFunction takes nothing returns boolean defaults false
// this is the function format used by the system
* call TimedFunc.Start(real time, TimedFunction func) (returns nothing)
// real time = real timeout in timers
// TimedFunction func = your function that will be runt
// when the timer expire, you can
// set this to null, to make the
// system do nothing when the timer
// expire
// doing this will set TimedFunc.Value to whatever
// the timer value in this new one. use that to specify
// struct indexes
* TimedFunc.Expired
// this constant is equal to GetExpiredTimer()
* TimedFunc.Value
// this constant is the unique number of the timer/system
// that currently runs. use this variable to index your structs
]||[===------
|E.| //How the System Works
]||[===------
// Basically, it works like this:
* First, it checks all available spaces,
- if there are an empty space (the timer are not running), then do
- use that timer for the next actions
- if there are no empty spaces (whether the timers are all running, or not created at all), then do
- create a new timer for the next actions
* Second, it starts the timer and set TimedFunc.Value to whatever the current timer's value is
* Finally, when the timer expires, do
- the function specified by the user,
- if, it returns true, then restart the timer, otherwise, destroy it
*/
/*
/\ /\
][======================================================================][
|| IV. USAGE ||
][======================================================================][
\/ \/
]||[===------
|A.| //Simple Usages
]||[===------
* Example 1:
library Initialization initializer Init requires TimedFunc
function FOWDisable takes nothing returns boolean
call FogEnable(false)
return false
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(5, FOWDisable)
endfunction
endlibrary
// that library disables fog of war 5 seconds after initialization
library FreeGold initializer Init requires TimedFunc
function Looping takes nothing returns boolean
local integer i = 0
local integer m = 11
loop
exitwhen i == m
call SetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(Player(i), PLAYER_STATE_RESOURCE_GOLD) + 1)
set i = i +1
endloop
return true
endfunction
function Init takes nothing returns nothing
call TimedFunc.Start(1, Looping)
endfunction
endlibrary
// this one adds one gold to player 1 - player 12 for every 1 second
]||[===------
|B.| //Complex Usages
]||[===------
* Example:
library MoveUnit requires TimedFunc
globals
private Variables array V [8190]
endglobals
struct Variables
unit Moved
real x
real y
endstruct
private function Move takes nothing returns boolean
local integer i = TimedFunc.Value
call SetUnitX(V [i].Moved, V [i].x)
call SetUnitY(V [i].Moved, V [i].y)
return false
endfunction
function MoveUnit takes unit u, real x, real y, real delay returns nothing
local integer i
call TimedFunc.Start(delay, Move)
set i = TimedFunc.Value
set V [i].Moved = u
set V [i].x = x
set V [i].y = y
endfunction
endlibrary
// that one move the unit 'instantly' to X, Y after a delay
*/
/*
/\ /\
][======================================================================][
|| V. THE SYSTEM ||
][======================================================================][
\/ \/
*/
library TimedFunc requires TimerUtils
/*=\
]||[===------
|A.| //The Function Format
]||[===------
\=*/
public function interface TimedFunction takes nothing returns boolean defaults false
/*=\
]||[===------
|B.| //The Struct
]||[===------
\=*/
struct TimedFunc
/*=///===---
|a.| Variables
\=*///===---
// timer + what it runs
private static timer t
private static integer f
// indexer system
private static TimedFunc array Index [8190]
private static integer Total = 0
// the constants
readonly static timer Expired
readonly static integer Value
/*=///===---
|b.| Contents
\=*///===---
// Do Not Edit
// If you know what you are doing, do it
private static method onExpire takes nothing returns nothing
set .Expired = GetExpiredTimer()
set .Value = GetTimerData(.Expired)
if not TimedFunction(.Index [.Value].f).evaluate() then
call ReleaseTimer(.Expired)
call .Index[.Value].destroy()
endif
set .Expired = null
set .Value = 0
endmethod
static method Start takes real time, TimedFunction func returns nothing
local integer a = 1
local integer b = .Total + 1
local integer i = 0
loop
exitwhen a == b
if .Index [a] == 0 then
set i = a
set a = b
endif
set a = a + 1
endloop
if i == 0 then
set .Total = .Total + 1
set i = .Total
endif
set .Index [i] = .create()
set .Index [i].f = func
set .Index [i].t = NewTimerEx(i)
call TimerStart(.Index [i].t, time, true, function thistype.onExpire)
set .Value = i
endmethod
endstruct
endlibrary
/*
/\ /\
][======================================================================][
|| VI. CONCLUSION AND FINAL NOTES ||
][======================================================================][
\/ \/
// Timed Function
// -*- overcold_ice -*-
//
// Please apologize me if there are mistakes, or something else that make
// you hurt. We have reached the end of the page, I hope you understand my
// really long documentation. Don't forget to put me in your Credits list
// if you use this system. If you want to edit this system, feel free to do
// that. But don't publish it without my permission, okay?
// You can remove these whole documentation. Enjoy and happy coding ^.^!
*/
Last edited: