- Joined
- Apr 27, 2008
- Messages
- 2,455
WARNING : THIS IS NOT
FOR SPEEDFREAKS
In jass, the only way to have an accurate and not "random" wait is to play with timers, but then it splits your code and it's quite boring.
Nowadays, we have tools which can play nicely with the JNGP including pre and post script processing.
I come with this idea, create a tool that will convert your waits in timers calls for you.
It will convert local variables in struct/table.
Because a script example is better than words, let's write one :
should be converted in :
In the first step, you should import and requires this library when you want to use a custom wait :
This way, we let pjass check if the code is valid and then we do the script post-processing with some tool.
Limitations and cons :
- a thread crash will cause leaks, because struct instances, Table and timer won't be released.
However we still can do some safety check to release lost struct instances and its Table and timer.
Because there is a timer linked to a struct instance and we could check if it's in use or not.
But i don't think it does worth it, because you already have a problem if there is a thread crash in your code.
- you can't use local array variable types that can't be store inside an hashtable, because of Table usage.
Like code array, oh wait, well ... xD
- you can't use it inside a function that returns something, for an obvious reason.
But maybe i suppose we could make an exception for a function that returns a boolean since trigger conditions are often used as a trigger action.
So, what do you think about that ?
FOR SPEEDFREAKS
In jass, the only way to have an accurate and not "random" wait is to play with timers, but then it splits your code and it's quite boring.
Nowadays, we have tools which can play nicely with the JNGP including pre and post script processing.
I come with this idea, create a tool that will convert your waits in timers calls for you.
It will convert local variables in struct/table.
Because a script example is better than words, let's write one :
JASS:
library Test requires Wait
private function Test takes nothing returns nothing
local integer i = 9
local string array s
local boolean array b
set s[0]="10"
set s[1]="20"
set i = 1
set b[0] = false
return
call BJDebugMsg("wait1")
call Wait(1)
call BJDebugMsg("end of wait1")
set i = 0
set s[0]="100"
set s[1]="200"
loop
call BJDebugMsg("wait2")
call Wait(2)
call BJDebugMsg("end of wait2")
set s[1]="42"
exitwhen i == 10
set i = i+1
call BJDebugMsg("wait3")
call Wait(3)
call BJDebugMsg("end of wait3")
set s[0]="1337"
exitwhen b[0]
call BJDebugMsg("end of loop")
endloop
call BJDebugMsg("end of function")
endfunction
endlibrary
JASS:
library Test requires Wait
private struct s_wait
static thistype last
timer tim
integer i
Table s
Table b
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set this.tim = NewTimerEx(this)
set this.s = Table.create()
set this.b = Table.create()
return this
endmethod
method destroy takes nothing returns nothing
call ReleaseTimer(this.tim)
call this.s.destroy()
call this.b.destroy()
call this.deallocate()
endmethod
endstruct
private function Test__loop1_end takes nothing returns nothing
call BJDebugMsg("end of function")
call s_wait.last.destroy()
endfunction
private function Test__loop1_2 takes nothing returns nothing
set s_wait.last = s_wait(GetTimerData(GetExpiredTimer()))
call BJDebugMsg("end of wait3")
set s_wait.last.tab.s.string[0]="1337"
if s_wait.last.b.boolean[0] then
call Test__loop1_end()
return
endif
call BJDebugMsg("end of loop")
call Test__loop1_end()
endfunction
private function Test__loop1_1 takes nothing returns nothing
set s_wait.last = s_wait(GetTimerData(GetExpiredTimer()))
call BJDebugMsg("end of wait2")
set s_wait.last.s.string[1]="42"
if s_wait.last.i == 10 then
call Test__loop1_end()
return
endif
set s_wait.last.i = s_wait.last.i+1
call BJDebugMsg("wait3")
call TimerStart(s_wait.last.tim,3,false,function Test__loop1_2)
endfunction
private function Test__loop1_begin takes nothing returns nothing
call BJDebugMsg("wait2")
call TimerStart(s_wait.last.tim,2,false,function Test__loop1_1)
endfunction
private function Test__1 takes nothing returns nothing
set s_wait.last = s_wait(GetTimerData(GetExpiredTimer()))
call BJDebugMsg("end of wait1")
set s_wait.last.i = 0
set s_wait.last.s.string[0]="100"
set s_wait.last.s.string[1]="200"
// split the loop in several functions, begin, end and each time there is a wait
call Test__loop1_begin()
endfunction
private function Test takes nothing returns nothing
call s_wait.create() //creation of the struct, the timer, the table
set s_wait.last.s.string[0]="10"
set s_wait.last.s.string[1]="20"
set s_wait.last.i = 1
set s_wait.last.b.boolean[0]=false
// return so destroy
call s_wait.last.destroy()
return
call BJDebugMsg("wait1")
// first wait
call TimerStart(s_wait.last.tim,1,false,function Test__1)
endfunction
endlibrary
JASS:
library Wait requires Table,TimerUtils
function Wait takes real whichTime returns nothing
endfunction
endlibrary
Limitations and cons :
- a thread crash will cause leaks, because struct instances, Table and timer won't be released.
However we still can do some safety check to release lost struct instances and its Table and timer.
Because there is a timer linked to a struct instance and we could check if it's in use or not.
But i don't think it does worth it, because you already have a problem if there is a thread crash in your code.
- you can't use local array variable types that can't be store inside an hashtable, because of Table usage.
Like code array, oh wait, well ... xD
- you can't use it inside a function that returns something, for an obvious reason.
But maybe i suppose we could make an exception for a function that returns a boolean since trigger conditions are often used as a trigger action.
So, what do you think about that ?
Last edited: