View previous topic :: View next topic |
Author |
Message |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Wed Jun 22, 2005 7:54 pm Post subject: Timers (Searching, killing, using time binds) |
|
|
Catching if a certain timer is running, then kill it.
There're several ways to do so, for example suppose we have a timer that should execute the proc check:voices.
Code: | timerexists check:voices |
this code returns the timer id of the timer which should execute check:voices. So to catch it and kill it, we can use:
Code: | if {[set thetimer [timerexists check:voices]]!=""} {
# if it's == "" then it doesn't exist, otherwise it returns the timerID
killtimer $thetimer
# timer is killed
} |
another way would be to use lsearch with the glob switch.
Code: | if {[set timerindex [lsearch -glob [timers] *check:voices*]] != -1} {
# if it's == -1 then it doesn't exist, otherwise it returns the index of this timer.
killtimer [lindex [lindex [timers] $timerindex] 2]
# the 3rd element of this list is the timerID which is now killed.
} |
Now the previous 2 methods will not match if there's a difference in case (i.e. Upper or Lower letters.)
So this way will match whatever case is used.
Code: | foreach thetimer [timers] {
if {[string equal -nocase check:voices [lindex $thetimer 1]]} {
# got a match
killtimer [lindex $thetimer 2]
# killed the timerID which is the 3rd element of $thetimer.
break
# stopped since no need for further checks.
}
} |
Same methods can be applied to utimers, just change timer(s) to utimer(s). _________________ Follow me on GitHub
- Opposing
Public Tcl scripts
Last edited by Sir_Fz on Mon Jul 30, 2007 4:00 pm; edited 2 times in total |
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Sat Jul 02, 2005 6:33 pm Post subject: |
|
|
You can also search for a timer independant from any cases (capital or lower letters) using lsearch.
Code: | lsearch -glob [string tolower [timers]] "* {check:voices} *" |
but note that check:voices should be in lowercase as well. so if you want to make sure that a variable is in lowercase use
Code: | string tolower $variable |
PS: After a test of which method is faster (lsearch or foreach and matching) I found out that using the foreach method is faster. _________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
sKy Op

Joined: 14 Apr 2005 Posts: 194 Location: Germany
|
Posted: Tue Jul 12, 2005 4:17 pm Post subject: |
|
|
i might add:
example: set timer [timer 1 [list putserv "..."]]
same for utimer.
this timer-id can you put in a variable (perhaps a global variable) and use later.
some less important procs:
Code: | proc isutimer { id } {
foreach utimer [utimers] {
set isid [lindex $utimer 2]
if { $id == $isid } {
return 1
}
}
return 0
}
proc istimer { id } {
foreach timer [timers] {
set isid [lindex $timer 2]
if { $id == $isid } {
return 1
}
}
return 0
} |
Ex:
Quote: |
if { [istimer $timerid] } { killtimer $timerid }
|
|
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Mon Aug 08, 2005 6:43 pm Post subject: |
|
|
Incase you have a timer which has more than 1 element in it and some of these elements always vary (i.e. $nick $uhost...etc) then you can use string match instead of string equal to be able to use wildcards. Suppose we have:
Quote: | {12 {check:voices #bla} timer1} |
We can use this code to find and kill this timer:
Code: | foreach thetimer [timers] {
if {[string match -nocase "check:voices *" [lindex $thetimer 1]]} {
# got a match
killtimer [lindex $thetimer 2]
# killed the timerID which is the 3rd element of $thetimer.
break
# stopped since no need for further checks.
}
} |
And ofcourse you can also use "lsearch -glob"
Code: | if {[set timerindex [lsearch -glob [timers] "* {check:voices *} *"]] != -1} {
# if it's == -1 then it doesn't exist, otherwise it returns the index of this timer.
killtimer [lindex [lindex [timers] $timerindex] 2]
# the 3rd element of this list is the timerID which is now killed.
} |
but the first method is faster. _________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Thu Sep 08, 2005 10:26 am Post subject: |
|
|
Btw, [timerexists] and [utimerexists] are alltools.tcl commands. Incase you're not loading it:
Code: | proc timerexists {command} {
foreach i [timers] {
if {![string compare $command [lindex $i 1]]} then {
return [lindex $i 2]
}
}
return
}
proc utimerexists {command} {
foreach i [utimers] {
if {![string compare $command [lindex $i 1]]} then {
return [lindex $i 2]
}
}
return
} |
_________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
awyeah Revered One

Joined: 26 Apr 2004 Posts: 1580 Location: Switzerland
|
Posted: Tue May 08, 2007 9:49 pm Post subject: |
|
|
Since we are dealing with timers here, some info regarding the minute, hour, day, month, year masks for bind time and how they are used for specific intervals would be appreciated. _________________ ·awyeah·
==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
================================== |
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Thu May 10, 2007 4:51 pm Post subject: |
|
|
Quote: | TIME (stackable)
bind time <flags> <mask> <proc>
proc-name <minute> <hour> <day> <month> <year>
Description: allows you to schedule procedure calls at certain
times. mask matches 5 space separated integers of the form:
"minute hour day month year". minute, hour, day, month have a
zero padding so they are exactly two characters long; year is
four characters. Flags are ignored. |
What's also worth mentioning about the time bind is that the first day is 01 and the first month is 00 (this is not documented).
If you want to trigger an operation every x minutes without using the (u)timer command, then bind time is what you need. Example:
Code: | bind time - * operation
# This proc (operation) is called every minute (00, 01, 02, 03,...59)
proc operation {min hour day mon year} {
# We want to trigger our command every 3 minutes for example
if {[scan $min %d] % 3 == 0} {
# Perform the needed operation here
}
} |
[scan %d] is applied over $min in order to convert it from an octal to a decimal number (since 08 & 09 are invalid octals) to be divided over the number of minutes (the interval of your choice which is 3 in our example). If the remainder is not 0 (greater than 0) then $min is not divisible by 3 and thus 3 minutes did not pass. This means that the "needed operation" is triggered at minutes 00, 03, 06, 09, ..., 57 (all divisible by 3). _________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Sun May 13, 2007 5:24 pm Post subject: |
|
|
In case you are worried about minute intervals which are not divisible by 60, there is a solution. What I mean by "not divisible by 60" are intervals like 7 for example: 00, 07, 14, 21, 28, 35, 42, 49, 56 - now the operation should be performed at minute 03 but instead it triggers at minute 00 which is not after 7 minutes. To solve this, you can use:
Code: | bind time - * operation
# This proc (operation) is called every minute (00, 01, 02, 03,...59)
proc operation {min hour day mon year} {
# We want to trigger our command every 7 minutes
if {([scan $min %d]+([scan $hour %d]*60)) % 7 == 0} {
# Perform the needed operation here
}
} |
What's happening here is that the hour is being converted into its minutes equivalent, added to the minute, and then divided by the interval to check if the remainder is 0. This way the difference between every call of the needed operation is always 7 minutes.
This, of course, can be applied on all intervals (divisible or not divisible by 60) so I recommend using it as default. _________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
awyeah Revered One

Joined: 26 Apr 2004 Posts: 1580 Location: Switzerland
|
Posted: Tue Jul 24, 2007 1:27 am Post subject: |
|
|
The mask is "MM HH dd mm yyyy" and can have wildcards (MM=minute, HH=hour, dd=day, mm=month(-1), yyyy=year)
The month comes with -1. So, january is 00 and december is 11.
Examples:
Code: |
bind time - * procname ; # is called every minute
bind time - "?5 *" procname ; # is called every 10 minutes, 05,15,25,35,45,55
bind time - "30 *" procname ; # is called every hour, 30 mins after full
bind time - "30 1? * 200?" procname ; # work from 10:30 - 19:30 every hour, but only in the year 2000-2009
|
Code: |
proc procname {minute hour day month year} { .. } ; # full var support
proc procname {min hour args} { .. } ; # args is special var for a list
proc procname args { .. } ; # you dont need the time, only proc called
|
Hint:
To trim the minutes (or other vars) it is best to use:
Code: |
set minutes [string trimleft $minutes 0]; if {$minutes==""} {set minutes 0}
|
_________________ ·awyeah·
==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
==================================
Last edited by awyeah on Tue Jul 24, 2007 10:56 am; edited 1 time in total |
|
Back to top |
|
 |
Sir_Fz Revered One

Joined: 27 Apr 2003 Posts: 3793 Location: Lebanon
|
Posted: Tue Jul 24, 2007 6:32 am Post subject: |
|
|
awyeah wrote: | Hint:
To trim the minutes (or other vars) best use:
Code: |
set minutes [string trimleft $minutes 0]; if {$minutes==""} {set minutes 0}
|
|
Or simply convert it to decimal as done in my code above:
Code: | set minutes [scan $minutes %d] |
_________________ Follow me on GitHub
- Opposing
Public Tcl scripts |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|