AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How do I create new timers on the fly?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Rhijaen
Guest





PostPosted: Tue Jan 22, 2008 8:38 am    Post subject: How do I create new timers on the fly? Reply with quote

Hi

I'm working on a script and in part of it I need to be able to create new timers.

One solution I thought of was to create a new script with the new timer in it and when that timer is finished, delete the script.

Is there some easier way to do this?

If not, here is my current code.. The problem I'm having is it doesn't literally write %duration% to the file. It adds the contents of duration.

How do I literally write something with % around it to a file?

This is how it's coming out:

Code:
timer:

timetilspawn := (10-(*(120000/60000)))

if timetilspawn < 1
{
settimer, timer, off
sendinput {raw};
SendInput test is ready for spawn.{enter}
return
}

sendinput {raw};
sendinput test will spawn in  minutes.{enter}
timer1 := timer1 + 1


return


When I need it to be:

Code:
      timer:

timetilspawn := (%duration%-(%timer1%*(%increment%/60000)))

if timetilspawn < 1
{
settimer, timer, off
sendinput {raw};
SendInput %itemspawn% is ready for spawn.{enter}
return
}

sendinput {raw};
sendinput %itemspawn% will spawn in %timetilspawn% minutes.{enter}
timer1 := timer1 + 1


return


Code:
      else if substr(Text,1,6) = ".timer"
      {
      stringtrimleft,text,text,7
      StringGetPos, firstdot, Text, %Needle2%
      stringgetpos, seconddot, Text, %Needle2%, , firstdot+1
      itemspawn := substr(Text,1,firstdot)
      duration := substr(Text,firstdot+2,seconddot-firstdot-1)
      increment := substr(Text,seconddot+2,strlen(Text)-seconddot) * 60000
     
      FileAppend,
      (
      timer:

timetilspawn := (%duration%-(%timer1%*(%increment%/60000)))

if timetilspawn < 1
{
settimer, timer, off
sendinput {raw};
SendInput %itemspawn% is ready for spawn.{enter}
return
}

sendinput {raw};
sendinput %itemspawn% will spawn in %timetilspawn% minutes.{enter}
timer1 := timer1 + 1


return
), %CharName%1.ahk
     

      SetTimer, timer1, %increment%
      timer1 := 1
      Text := ";" charname " set timer: " itemspawn " will spawn in " duration " minutes. Reminder interval of " increment/60000 " minutes."
}



Thanks for any and all help. This is my first time scripting with AHK and am loving it. Cool
Back to top
ManaUser



Joined: 24 May 2007
Posts: 906

PostPosted: Tue Jan 22, 2008 8:59 am    Post subject: Reply with quote

To write a literal % "escape" it with a `, like so: `%
Back to top
View user's profile Send private message
Rhijaen
Guest





PostPosted: Tue Jan 22, 2008 9:37 am    Post subject: Reply with quote

Thanks..

Is there an easier way to create new timers on the fly?
Back to top
ManaUser



Joined: 24 May 2007
Posts: 906

PostPosted: Tue Jan 22, 2008 5:30 pm    Post subject: Reply with quote

You know, I'm not sure there is. As far as I know, each label can only have one timer, and there's no way to create more labels.
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Wed Jan 23, 2008 12:28 am    Post subject: Reply with quote

Each label can have as many timers as you want. The problem is that there is no way to determine which timer just fired. Instead, you could implement a "dispatch" timer. A quick example follows:
Code:
#Persistent

timer1end := A_TickCount +  5000  ; run once in 5 seconds
timer2end := A_TickCount +  1000  ; run once in 1 second
timer3int := 3000                 ; run every 3 seconds
timer3end := A_TickCount +  3000
timer4end := A_TickCount + 10000  ; run once in 10 seconds
timers = 4

SetTimer, dispatch, 100
return

dispatch:
    Loop %timers%
        if (timer%A_Index%end && timer%A_Index%end <= A_TickCount)
        {
            ToolTip, Timer %A_Index% ran.

            if timer%A_Index%int
                timer%A_Index%end += timer%A_Index%int
            else
                timer%A_Index%end =
        }
return
Back to top
View user's profile Send private message
ManaUser



Joined: 24 May 2007
Posts: 906

PostPosted: Wed Jan 23, 2008 2:22 am    Post subject: Reply with quote

lexikos wrote:
Each label can have as many timers as you want.

You sure about that?

Code:
#Persistent
SetTimer DoBeep, 1000
SetTimer DoBeep, 5000
return

DoBeep:
SoundBeep
return

(Not that this helps you any, Rhijaen. The rest of what lexikos said is good advice.)
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Wed Jan 23, 2008 3:07 am    Post subject: Reply with quote

Laughing, not sure what I was thinking there. Of course you can't, since timers are identified by label name. Maybe I was thinking of hotkeys.
Back to top
View user's profile Send private message
Rhijaen
Guest





PostPosted: Fri Feb 01, 2008 5:44 pm    Post subject: Reply with quote

Thanks guys for the replies..

I don't completely understand it all but I am trying.

Maybe you can help me out a little further.

Basically what I need it to do is any time it catches .timer, it will start a new timer.

So .timer Vampire.10.1 will set a timer reminding you that the Vampire will spawn in 10 minutes with a reminder interval of 1 minute.

The problem is that everytime you start a new timer, the last one gets overwritten.

Help me out here guys..I've tried messing around with your code lexikos but I'm just not experienced enough to understand it.

Code:
      else if substr(Text,1,6) = ".timer"
      {
     
      stringtrimleft,text,text,7
      StringGetPos, firstdot, Text, %Needle2%
      stringgetpos, seconddot, Text, %Needle2%, , firstdot+1
      itemspawn := substr(Text,1,firstdot)
      duration := substr(Text,firstdot+2,seconddot-firstdot-1)
      increment := substr(Text,seconddot+2,strlen(Text)-seconddot)
     
      transform, duration, round, %duration%
      increment := increment * 60000
      SetTimer, timer1, %increment%
      increment := increment / 60000
      transform, increment, round, %increment%
      timer1 := 1
      Text := ";" charname " set timer: " itemspawn " will spawn in " duration " minutes. Reminder interval of " increment " minutes."
      }

...

timer1:
timetilspawn := (duration-(timer1*(increment)))

if timetilspawn < 1
{
settimer, timer1, off
sendinput {raw};
SendInput %itemspawn% is ready for spawn.{enter}
return
}
transform, timetilspawn, round, %timetilspawn%
sendinput {raw};
sendinput %itemspawn% will spawn in %timetilspawn% minutes.{enter}
timer1 := timer1 + 1
return
Back to top
Rhijaen
Guest





PostPosted: Sat Feb 02, 2008 3:24 pm    Post subject: Reply with quote

Bump..

I've tried and I just don't understand how to implement the code into my script.
Back to top
Lexikos



Joined: 17 Oct 2006
Posts: 2739
Location: Australia, Qld

PostPosted: Sat Feb 02, 2008 11:59 pm    Post subject: Reply with quote

This should make it easier: [Dispatch Timer - Create new timers on the fly.]
Back to top
View user's profile Send private message
Guest






PostPosted: Sun Feb 03, 2008 12:15 am    Post subject: Reply with quote

Okay, so, what you want to do is every minute it will say "The Vampire will spawn in 10 minutes", and in another minute it will say "The Vampire will spawn in 9 minutes", ect, ect, ect.

Is this correct?

If so then you should be able to do that fairly simply with just a timer firing off every minute after you hit a hotkey (or how ever the timer is initially started), and that sould do it.

If this is correct, explain how you want it to start, Ill write a script up (not done this before, but it seems rather simple, and I'd like to do such a thing if this is how you imagine it).
Back to top
dmatch



Joined: 15 Oct 2007
Posts: 113

PostPosted: Sun Feb 03, 2008 1:38 am    Post subject: Reply with quote

I don't know if it will help but I messed around and created a function that runs timers that sets a caller's chosen variables to true as they fire. It doesn't require labels. I posted it in the Scripts and Functions Forum.

http://www.autohotkey.com/forum/viewtopic.php?t=28233

dmatch
Back to top
View user's profile Send private message
Rhijaen
Guest





PostPosted: Sun Feb 03, 2008 1:55 am    Post subject: Reply with quote

guest wrote:
Okay, so, what you want to do is every minute it will say "The Vampire will spawn in 10 minutes", and in another minute it will say "The Vampire will spawn in 9 minutes", ect, ect, ect.

Is this correct?

If so then you should be able to do that fairly simply with just a timer firing off every minute after you hit a hotkey (or how ever the timer is initially started), and that sould do it.

If this is correct, explain how you want it to start, Ill write a script up (not done this before, but it seems rather simple, and I'd like to do such a thing if this is how you imagine it).


Yes, that is how the timer is supposed to work. The only problem is that if you try and start a new timer such as .Timer Chests.20.2 (reminder for chests in 20 minutes with an reminder interval of 2 minutes.), the timer before it will be "overwritten" and forgotten. The new timer starts and the old one is gone.

I need to be able to have as many timers running as I need at the same time.

dmatch wrote:
I don't know if it will help but I messed around and created a function that runs timers that sets a caller's chosen variables to true as they fire. It doesn't require labels. I posted it in the Scripts and Functions Forum.

http://www.autohotkey.com/forum/viewtopic.php?t=28233

dmatch


Thanks, I'll take a look at it.
Back to top
Rhijaen
Guest





PostPosted: Sun Feb 03, 2008 2:24 am    Post subject: Reply with quote

Okay..the script reads from logs and does stuff depending on what it finds in that line (this is for a game I play.)

Here's an example..see how it gets off when I start a new timer?

Quote:
01/21/2002 22:30:50-- Panzer LTK pages you: .timer This little piggy goes to market.10000.1
01/21/2002 22:30:51-- ["CC ahk"] "Maddox": Panzer LTK set timer: This little piggy goes to market will spawn in 10000 minutes. Reminder interval of 1 minutes.
01/21/2002 22:31:50-- ["CC ahk"] "Maddox": This little piggy goes to market will spawn in 9999 minutes.
01/21/2002 22:32:50-- ["CC ahk"] "Maddox": This little piggy goes to market will spawn in 9998 minutes.
01/21/2002 22:32:55-- Panzer LTK pages you: .timer chests.20.1
01/21/2002 22:32:56-- ["CC ahk"] "Maddox": Panzer LTK set timer: chests will spawn in 20 minutes. Reminder interval of 1 minutes.
01/21/2002 22:33:56-- ["CC ahk"] "Maddox": chests will spawn in 19 minutes.
01/21/2002 22:34:56-- ["CC ahk"] "Maddox": chests will spawn in 19 minutes.
Back to top
dmatch



Joined: 15 Oct 2007
Posts: 113

PostPosted: Sun Feb 03, 2008 4:54 am    Post subject: See If This Is What You Have In Mind Reply with quote

This may be similar to what you are trying to do. The code below includes the SetWinTimer function that I posted in the other Scripts and Functions thread.
Code:
Gui,Show,w300 h100,Test
Gui,Add,Text,vTimerStatus1,Timer1 Running...Please Wait.
Gui,Add,text,vTimerStatus2,Timer2 Running...Please Wait.
WinActivate,Test
WinWaitActive,Test
hGui:=WinExist()
Timer1:=0x1001
Timer2:=0x1002
TimeInterval1:=2000
TimeInterval2:=4000
TimerFired1:=0
TimerFired2:=0
TimeLeft1:=10000
TimeLeft2:=16000
SetWinTimer(hGui,Timer1,TimeInterval1,TimerFired1)
Sleep 1000 ;for demonstration purposes
SetWinTimer(hGui,Timer2,TimeInterval2,TimerFired2)
Loop
{
   NeedToDisplay:=false
   If(TimerFired1){
      TimerName:="TimerStatus1"
      DisplayName:="First Timer"
      TimeLeft1:=TimeLeft1-TimeInterval1
      Left:=TimeLeft1
      if(Left<=0){
         Left:=0
         TimeInterval1:=0
         SetWinTimer(hGui,Timer1,0,TimerFired1)
      }
      TimerFired1:=false
      NeedToDisplay:=true
   }
   Else If(TimerFired2){
      TimerName:="TimerStatus2"
      DisplayName:="Second Timer"
      TimeLeft2:=TimeLeft2-TimeInterval2
      Left:=TimeLeft2
      if(Left<=0){
         Left:=0
         TimeInterval2:=0
         SetWinTimer(hGui,Timer2,0,TimerFired2)
      }
      TimerFired2:=false
      NeedToDisplay:=true
   }
   if(NeedToDisplay){
      Left:=Floor(Left/1000) ;convert to seconds for display purposes
      GuiControl,,%TimerName%,%DisplayName% time left = %Left% seconds
   }
   if(TimeInterval1=0 and TimeInterval2=0)
      break ;exit the loop we are done
}
msgbox,Finished
return
GuiEscape:
GuiClose:
   ;Kill Timers in case of early exit
   SetWinTimer(hGui,Timer1,0,TimerFired1)
   SetWinTimer(hGui,Timer2,0,TimerFired2)
ExitApp

;************************ SetWinTimer ***********************
; Starts/Kills 1 or more timers using DllCalls to
; Window's SetTimer/KillTimer function.
;
; This function temporarily intercepts windows WM_TIMER messages
; using OnMessage Function of AHK. When ALL timers are killed it
; releases the WM_TIMER message handler. This message handler is
; included below as WM_TIMER().
;
; Creates no global variables and requires no labels.
; Changes the caller's TimerFired BYREF variable to true (1)
; when a timer fires.
;
; Returns 0 for failure and >0 for success.
;
; 2/2/2008
; dmatch @ AutoHotKey forum
;***************************************************************
SetWinTimer(GuiHandle   ;Window's Handle of Gui
,ID                   ;Your Timer ID (use 0x1000 and higher)
,Duration            ;Timer duration in miliseconds (msec.)
                  ;or 0 to kill timer (1000 msec.=1 sec.)
,BYREF TimerFired)      ;Will be made true (1) when timer fires
{
   Static OnMessageDone
   if(!OnMessageDone){
      OnMessage(275,"WM_TIMER")
      OnMessageDone:=true
   }
   if(!Duration){ ;Kill the timer
      result:=WM_TIMER(0,ID,GuiHandle,-1)
      if(!result){ ;indicates no timers are running
         OnMessage(275,"")
         OnMessageDone:=false
         result:=1
      }
      return result
   }
   ;Start the Timer
   result:=DllCall("SetTimer",uint,GuiHandle,uint,ID,uint,Duration,uint,0)
   if(!result)
      return 0
   ;Introduce new timer to WM_TIMER message handler
   result:=WM_TIMER(0,ID,&TimerFired,0)
   if(!result)
      return 0
   return result
}
;*********************************************************
; Windows WM_TIMER Message Handler that is started in
; SetWinTimer above.
;*********************************************************
WM_TIMER(wParam,lParam,msg,hWnd)
{
   Static TimerIDs
   KillIt:=false
   Result:=0
   if(wParam=0){ ;Was internal call from SetWinTimer to introduce/kill timer
      if lParam is not integer ;check if contains legit TimerID
         return result
      if(hWnd>=0){ ;Indicates to add a Timer
         TimerIDs .=lParam+0 . "," . msg+0 . ","
         ;We now have a comma delimted string
         ;with "TimerID,VariableAddress,".....
         return 1
      }
      Else{ ; - number (<0) indicates to kill the Timer
         wParam:=Lparam ;move TimerID to wParam
         hWnd:=msg ;Move Gui Window Handle to hWnd
         KillIt:=true ;Set switch to Kill the timer later (below)
      }
   }
   ;Comes here when called from windows when timer counts down (fires)
   ;OR when we call internally to kill a timer
   wParam:=wParam+0 ;make sure it's handled as an integer
   FoundIt:=false
   Loop,Parse,TimerIDs,CSV ;Parse the TimerIDs string
   {
      if(Mod(A_Index,2)=1){ ;Check TimerID
         if(wParam=A_LoopField){
            FoundIt:=true
            TimerID:=A_LoopField
         }
      }
      Else if(FoundIt and Mod(A_Index,2)=0){ ;Timer Fired Variable Address
         ;Set user's Timer Fired Variable to true
         ;A_LoopField contains address of the variable
         NumPut(asc("1"),A_LoopField+0,"char")
         if(ErrorLevel)
            return
         if(KillIt){
            result:=DllCall("KillTimer",uint,hWnd,uint,TimerID)
            ;remove Timer info from string
            pos:=InStr(TimerIDs,wParam)
            StartPos:=pos
            Loop,2
               pos:=InStr(TimerIDs,",",0,pos+1)
            TimerIDs:=SubStr(TimerIDs,1,StartPos-1) . SubStr(TimerIDs,pos+1)
            if(!TimerIDs)
               return 0 ;indicates to SetWinTitle that no timers are left
         }
         if(FoundIt)
            return result
      }
   }
   ;Not a timer we are interested in so don't return anything
   return
}

The first Timer (Timer1) counts down in intervals of 2 seconds and is allowed to run for 10 seconds (This could be minutes). The second Timer2 counts down in 4 second intervals and is allowed to run 16 seconds (This could be minutes). That's 2 different timers with 2 different timing intervals concurrently.

BTW, I corrected a bug in the SetWinTimer function. The corrected version is here and in Scripts and Functions.

Hope this helps,

dmatch
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group