mIRC Home    About    Download    Register    News    Help

Topic Options
#264309 - 18/11/18 11:20 PM $timer().pause + .secs
westor Offline
Hoopy frood

Registered: 27/12/08
Posts: 1510
Loc: Greece
Hello,

I am not sure if this is by design or bug, but it seems when i pause a timer the trigger seconds doesn't paused too.

Example:

/timer[test] 1 600 noop
/timer[test] -p
//echo -a IS: $timer([test]).pause -- $timer([test]).secs

P.S: I saw in help file says "$timer(3).secs returns number of seconds left before timer is triggered".
_________________________
Need Online mIRC help or an mIRC Scripting Freelancer? -> http://westor.ucoz.com/contact <-

Top
#264310 - 19/11/18 01:18 AM Re: $timer().pause + .secs [Re: westor]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
This has been reported before:

https://forums.mirc.com/ubbthreads.php/topics/230738/pausing_timer#Post230738

and you had already +1'ed the backwards-compatible requested fix:

https://forums.mirc.com/ubbthreads.php/ubb/showflat/Number/230920

-p1 would offer the documented behavior instead of the backwards-compatible behavior. Currently, instead of pausing the timer, the .secs countdown continues to zero, and only then does it pause. There's effectively no difference as to when you use -p as long as you do it before the next .reps execution.

The documented behavior is misleading. If this were an mp3 player, when you paused the player it would continue silently playing the song. If you resumed the player before the song ended, it would resume as if you had temporarily turned the volumen down. But if you resumed after the time when the song would have otherwise ended, it would begin the next song instead of resuming play of the portion of the song you missed.

This shows the countdown continues to zero while it is "paused":

Code:
//timerx1 2 7 noop | timerx2 10 1 echo -a $!timer(x1).reps $!timer(x1).secs | timerx3 1 2 timerx1 -p


Top
#264312 - 19/11/18 09:09 AM Re: $timer().pause + .secs [Re: maroon]
westor Offline
Hoopy frood

Registered: 27/12/08
Posts: 1510
Loc: Greece
So this is a bug, and is not by design, but it won't fix because break backward compatibility ok i didn't expect anything else, i have a 90's code and is still working on 7.52 yeah that's the goal.

It seems Ouims suggestion with -pN sounds fair, and seems also all the scripters supporting that idea! so that's a good reason to add. (more money laugh )
_________________________
Need Online mIRC help or an mIRC Scripting Freelancer? -> http://westor.ucoz.com/contact <-

Top
#264314 - 19/11/18 06:27 PM Re: $timer().pause + .secs [Re: westor]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Thanks for your bug report. As mentioned by maroon, this issue has been discussed before. This is not a bug and is by design. This feature was added to v5.91 in 2001 because a scripter requested it. It is likely that the scripter wanted a way to temporarily stop a timer command from being triggered but still wanted it to continue counting down. At the time, calling it "pause" probably seemed reasonable, since it paused the triggering of the command, and that is the context in which we understood it.

I have updated the help file description to make it clearer.

Top
#264333 - 21/11/18 06:48 PM Re: $timer().pause + .secs [Re: Khaled]
Wims Offline
Planetary brain

Registered: 31/07/06
Posts: 3436
Loc: France
Quote:
63.Added /timer -P switch that temporarily pauses a timer to stop it
from being triggered and from counting down.
Thanks!
_________________________
Looking for a good help channel about mIRC? Check #mircscripting @ irc.swiftirc.net

Top
#264336 - 22/11/18 01:22 AM Re: $timer().pause + .secs [Re: Wims]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
They were expecting that -P would pause the .secs at the number it was when the -P was issued. Instead, it's causing .secs to immediately jump up to the interval parameter as if the timer had been paused immediately after being launched. The effect is that there's no difference in pausing a 60-second interval timer at 1 second after launch or 59 second after launch.

The code I pasted in my earlier post of this thread shows this happening, with .secs jumping up to 7.

Top
#264349 - 22/11/18 09:18 AM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Right. This has turned out to be more complicated than I thought and I have not been able to find a solution to it yet without changing core timer code in multiple places which could easily break /timers in some way. I have reverted this change and will be leaving it for the next beta cycle.

Top
#264358 - 22/11/18 06:51 PM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
I have found a way of implementing this in only -P-related code, so core timer code is not affected. However, it is still tricky because timers are based on start/end tick counts and counters that are used in calculations. So -P-related code has to reset these values and its not clear if there are side-effects, eg. how this will interact with other timer switches. I am still testing this but it looks like it should make it into the next beta.

Top
#264362 - 23/11/18 08:40 PM Re: $timer().pause + .secs [Re: Khaled]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
For those who only need the timer to be 1 .reps this fix is working, however it doesn't work when the .reps parameter is 0 or greater than 1.

It appears that -P is sorta working, and there's an additional bug with -p not reported earlier, which also affects -P. On the 1st .rep the -P functions as expected, but on later reps the interval varies for both -p and -P. Also there's a ghost value reported for the timer's .secs value after it ceases to exist.

On the 2nd -p interval, it tries to change the interval for that timer so it's aligned with one of the execution points that would have been used if the -p had not been used. It then goes back to using the original .delay for all later intervals. And some of this behavior is affecting -P too.

On the 2nd -P interval, it looks like the timer is trying to do the same thing, but doesn't always get it right. But then for the 3rd and later intervals, even though $timer().delay continues to report the original delay, -P's actual delay is counting down from N, where N was the .secs value when the -P was issued.

This alias below waits until the time is hh:nn:00 to make things easier to see. The X1 target timer executes 4 times at 15 second intervals.

/test_timer_P 7 20 -p

at nn:07 seconds X1 pauses, then resumes at nn:25, when it executes immediately because .secs counted down to zero while paused. However that next interval is only 5 secs long because X1 tries to have the next interval at the nn:30 time, which was the 2nd execution point had the timer not paused. All intervals after that are original 15 secs.

/test_timer_P 7 25 -p

This pauses X1 at nn:07 with .secs at 8, and .secs remains at 8 until it resumes at nn:28 instead of nn:15 due to being paused for 13 secs. X1 decides the 2nd interval should be 4 secs, and counts down until the 2nd execution at nn:32. The interval then changes to be the 8 value of .secs when the -P was issued, so this interval of 8 secs causes the 3rd execution to be at nn:40 and the 4th interval at nn:48, which is sooner than it would have happened if the timer hadn't been paused.

I'm guessing the 4 comes from a calculation of 4xxx milliseconds between nn:30 when the timer was supposed to execute next vs the few ticks after nn:25 when the timer was resumed.

When using -p and -P, within 1 second of the timer halting it always reports to an external observer that $timer(x1).secs is the delay used by the final .rep even though $timer(x1) and $timer(x1).reps and $timer(x1).delay are all $null.

Even if the timer is paused and restarted N seconds later which is before the 1st .rep executes, the 2nd interval is lowered by N-1 seconds and the 3rd and later intervals are lowered to be whatever the .secs was when paused.

Code:
alias test_timer_P {
  var %pause_at 5 , %resume_at 20
  if ($1 isnum 5-) var -s %pause_at  $int($1)
  if ($2 isnum 6-) var -s %resume_at $int($2)
  if (%resume_at <= %pause_at) { echo -a "resume_at" must be greater than "pause_at": /test_timer_P pause_at resume_at -P|-p | return }
  var %paused_for %resume_at - %pause_at

  if ( $asctime($ctime,s) isnum 1-55) { echo -a waiting for seconds to reach zero $asctime | .timerx0 1 $calc(57- $v1) test_timer_P $1 $2 $3 | return }
  while ($asctime($ctime,s) != 0) noop

  echo -a pause_at %pause_at
  echo -a resume_at %resume_at
  echo -a paused_for %paused_for $iif($3 == -P,$3,-P)

  var %rep1 $asctime($calc($ctime + 15 + %paused_for))
  var %rep2 $asctime($calc($ctime + 30 + %paused_for))
  var %rep3 $asctime($calc($ctime + 45 + %paused_for))
  var %rep4 $asctime($calc($ctime + 60 + %paused_for))

  echo -a without pause/resume, green timers display at :15 / :30 / :45 / :00 secs
  var %i 1 | while (%i isnum 1-4) {
    echo -a with pause at launch+ $+ %pause_at and resume at launch + $+ %resume_at $+ , rep $+ %i should display at: $asctime($calc($ctime + 15*%i + %paused_for) )
    inc %i
  }

  echo 4 -a launch $asctime
  timerx? off
  timerx1 4 15 echo 3 -a X1: .reps= $!asctime reps= $!timer(x1).reps .delay= $!timer(x1).delay .secs= $!timer(x1).secs
  .timerx2 0 1 echo -a $!time x2 sees $!timer($timer(x1)) reps= $!timer(x1).reps secs= $!timer(x1).secs $(|) if (!$timer(x1)) timerx2 off
  .timerx3 1 %pause_at  timerx1 $iif($3 == -P,$3,-P)
  .timerx4 1 %resume_at timerx1 -r
  timerx?
}

Top
#264364 - 24/11/18 07:48 AM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Thanks for the explanation and script. Unfortunately, there is so much going on in this report that I cannot follow it.

Quote:
For those who only need the timer to be 1 .reps this fix is working, however it doesn't work when the .reps parameter is 0 or greater than 1.

I cannot seem to reproduce this here. I just tested -P with reps 0 and onwards, and they worked as expected.

Since you are reporting a bug with -p as well, I think I will need to put -P on hold for now.

Can you post another bug report that is as simple and short as possible, that describes the issue with -p?

Top
#264366 - 24/11/18 10:06 AM Re: $timer().pause + .secs [Re: Khaled]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
My post above had a typo. The 2nd example command should have used -P instead of -p. The two examples showing the -p and -P handling should have been:

/test_timer_P 7 20 -p
/test_timer_P 7 25 -P

The condensed behaviors are shown below. First is for -p intervals. Due to being paused for 10 seconds, the .secs is zero when it resumes at T+22 secs, so it executes immediately. Since this missed the original T+15 target time for the 1st execution, the timer tries to adjust the 2nd execution to be at T+30 seconds after launch, so the 2nd interval is 8.

Code:
//echo -a $asctime launch | timerx1 4 15 echo 4 -a $!asctime reps $!timer(x1).reps secs $!timer(x1).secs | .timerx2 1 12 .timerx1 -p | .timerx3 1 22 timerx1 -r | .timerx?



Next is for -P intervals. The 1st .rep correctly triggers 16 seconds after launch due to being paused for 1 second. However the 2nd interval executes after a 1 sec delay that's probably due to similar calculations attempted by -p's 2nd interval. The 3rd and all later intervals use a delay taken from the .secs=2 value at the time it was resumed. This causes the 4 .reps to execute in 24 seconds instead of 60.

Code:
//echo -a $asctime launch | timerx1 4 15 echo 4 -a $!asctime reps $!timer(x1).reps secs $!timer(x1).secs | .timerx2 1 12 .timerx1 -P | .timerx3 1 13 timerx1 -r | .timerx?



The bug where timerX2 was seeing info about timerX1 after X1 was halted isn't related to -p or -P. It turns out that the X1 and X2 timers were being executed during the same clock tick, so this is the same issue reported here in this thread:

https://forums.mirc.com/ubbthreads.php/topics/261772/$timer()_returning_info_about_#Post261772

Top
#264375 - 24/11/18 01:27 PM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Thanks. Please note that I am no longer looking at -P. If I manage to fix -p, I may look into -P again. But it is likely that -P will be left for the next beta cycle, as we need to test any changes to -p first.

I am running your example:

Code:
//echo -a $asctime launch | timerx1 4 15 echo 4 -a $!asctime reps $!timer(x1).reps secs $!timer(x1).secs | .timerx2 1 12 .timerx1 -p | .timerx3 1 22 timerx1 -r | .timerx?

Here is my output:

Quote:
Sat Nov 24 13:19:49 2018 launch
-
* Timer x1 activated
-
* Timer x2 activated
-
* Timer x3 activated
-
* Active timers:
* Timer x1 4 time(s) 15s delay echo 4 -a $asctime reps $timer(x1).reps secs $timer(x1).secs
* Timer x2 1 time(s) 12s delay .timerx1 -p
* Timer x3 1 time(s) 22s delay timerx1 -r
-
* Timer x2 halted
-
* Timer x1 resumed
-
* Timer x3 halted
-
Sat Nov 24 13:20:11 2018 reps 3 secs 8
Sat Nov 24 13:20:19 2018 reps 2 secs 15
Sat Nov 24 13:20:34 2018 reps 1 secs 15
Sat Nov 24 13:20:49 2018 reps 0 secs 15
-
* Timer x1 halted

What you would you expect to see? Please show me the above output as you would want to see it.

Would implementing your requested change break existing scripts?

Top
#264377 - 24/11/18 02:33 PM Re: $timer().pause + .secs [Re: Khaled]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
Sat Nov 24 13:20:11 2018 reps 3 secs 15
Sat Nov 24 13:20:26 2018 reps 2 secs 15
Sat Nov 24 13:20:41 2018 reps 1 secs 15
Sat Nov 24 13:20:56 2018 reps 0 secs 15

I would've expected the interval between the 1st and 2nd execution be the same 15 seconds as the later intervals. If x3 had resumed the timer at 29 instead of 22, the intervals between the 1st and 2nd execution wouldn've been only 1 second. And if x3 had resumed the timer at 30, the 1st and 2nd rep would execute during the same $tick.

But I also had expected the -p behavior for .rep #1 to be what the requested -P behavior was hoping to be. As for whether it would break -p scripts if the delay following the resume of that timer were the same 15 used by the later intervals, I can't see a likely use for the current -p behavior. I would've guessed that the original requestor was repeating a timer at 1 sec intervals and wanted to pause that timer temporarily. In that scenario the -p behavior is not very noticeable. The timer executing immediately after resuming and having a 0-1 sec delay prior to the .rep after that is very similar to that timer's normal behavior.

I can't speak for the others asking for the -P behavior, but I assume they would want -P to have the interval before all .reps be the same as the .delay parameter, except when increased by the duration between when it's paused then later resumed.

Top
#264384 - 25/11/18 04:43 PM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Isn't this just the behaviour of -p that others have mentioned before, ie. the fact that it continues to count down while paused because all -p does is silence the output?

Update: Actually, looking at it again, -p does not decrease the repetition count once the second count reaches zero for a repetition. It just silences the current repetition. So it is not even working the way I thought it was working (unless I change it to do this, in which case I would be changing its behaviour). In this case, it may make sense to change -p to what westor requested.


Edited by Khaled (25/11/18 05:54 PM)

Top
#264385 - 25/11/18 10:48 PM Re: $timer().pause + .secs [Re: Khaled]
maroon Offline
Hoopy frood

Registered: 12/01/04
Posts: 969
It looks like the timer is doing things "by design" but the end users are assuming the vernacular meaning of timer, and puzzled by how these timers behave differently. It looks like what the timer is really doing is recording the ticks value when the timer begins, then all behavior is pivoting from that starting time. It internally keeps track of how many reps have happened so far, then calculates the next trigger time based on that calculation. So that explains why the .secs value seen inside the timer during the final execution is [delay-1] or [delay-0] - because it's assuming that itself will execute forever, and it's only after that final execution finishes where the overhead cancels the timer.

People think interval means a duration between the executions, when it really means [beginning_ticks + N*X]. So the -P behavior was mis-behaving for later ticks because, instead of keeping track of the ticks duration the timer had been paused ($ticks-when-resumed less $ticks-when-paused), and adding this to the beginning-ticks, after being resumed, the beginning ticks was adjusted to a calculated value relative to the next execution time, and the .delay was then changed to become the .secs value as the timer was paused.

This also turns out to finally be the only situation where I can see the -c catchup switch doing anything except behaving as if you used an invalid switch when doing "/timerX1 -c" after launch. So instead of displaying an error message that -c in this context was not valid, it displays the matching timers as if you didn't use the switch at all. Now I see that -c is only valid when starting a timer, same as the -i or -o switches. If the timer were launched using the -c switch, then if it's paused with lower-case -p at start+12 seconds then resumed at start+61, then all 4 executions of the timer happen immediately.

So what the -p was doing for the 2nd interval in the original example was trying to execute at the next available beginning_ticks+N*X ticks that's in the future. Then for the later intervals it continued executing at beginning_ticks+N*X ticks beyond that.

If I understand how the timer is working, then the expected -P behavior to fix like Westor wanted would be like a repeat of the code from my prior post:

Code:
//echo -a $asctime launch | timerx1 4 15 echo 4 -a $!asctime reps $!timer(x1).reps secs $!timer(x1).secs | .timerx2 1 12 .timerx1 -P | .timerx3 1 13 timerx1 -r | .timerx?



at ticks=001, timer starts with reps=4 and delay=15. It calculates that the next execution time is at ticks=15001.

When the timer is paused at ticks=12001 or shortly later, then resumes at 13001 ticks or shortly later, after resumation the timer should calculate how many ticks the timer had been paused, then add that to the beginning base-time, and also to the next-execution time.

Assuming the timer was actually paused for 1234ms, the beginning time would be adjusted to be 001+1234=1235 ticks, and the next execution time is 15001+1234=16235 ticks.

This would always cause the next-execution time to be in the future. The interval would remain at 15000 instead of being adjusted based on the .secs value when the timer was resumed. After the timer next executes, on or after 16235, it calculates the following execution time. Since the beginning time has increased by the pause duration, the next execution time should be targeted to be ticks=1235+15000*2=31235.

If the timer resumed after the original expected execution time of 15001 instead of prior, the resume calculation should be the same as above, except that it's merely shifting both the beginning-time and next-time by larger numbers.

As I see it, the -c switch is only used for either a timer using small -p which is then paused for longer than 1 [delay], or perhaps a normal time which was interrupted by a $findfile() of long duration.

For the capital -P timer behavior, the -c should not cause any difference in calculation due to a pause, but only in other freezes such as for a $findfile or a different program freezing mIRC for longer than 1 [delay] duration. The current -P behavior is correctly not adjusting due to using -c then pausing at start+12 then wait until launch+61sec to resume the timer.

Top
#264391 - 26/11/18 10:51 AM Re: $timer().pause + .secs [Re: maroon]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
Right. I think it would be best to revert /timer code to v7.52 for now as we are too close to release. I will look at /timer again in the future. Thanks for your comments everyone.

Top
#264494 - 07/12/18 07:07 PM Re: $timer().pause + .secs [Re: westor]
Khaled Offline


Planetary brain

Registered: 04/12/02
Posts: 4295
Loc: London, UK
The latest beta includes some changes to /timer -p and adds a /timer -P.

The issue fixed with /timer -p is that it was not counting down repetitions. In other words, /timer -p was stopping the timer alias from being executed during the seconds count down for one repetition. /timer -r would then resume it for subsequent repetitions. The new /timer -p makes it count down across repetitions, so it will count down and skip repetitions during a pause and may even halt if it reaches the end of the repetition count. This is a significant change in behaviour but it seems to be in line with what was originally intended.

The new implementation of /timer -P pauses the timer completely. If anyone has a chance to test this out, please let me know if it is doing what was requrested in the original post.

Top
#264495 - 07/12/18 10:54 PM Re: $timer().pause + .secs [Re: Khaled]
Wims Offline
Planetary brain

Registered: 31/07/06
Posts: 3436
Loc: France
Both switches seems to work as intended in my manual tests, -P being used in my script, I tested that and didn't see any problem. And yes -P is doing what I originally requested, a (real) pause of the timer. I would like to see the help file updated for .timer -p, it should replace the term 'pause' with 'silencing' or 'prevent the execution', I mean it should be clear that the timer is still running in the background, that the state of repetitions and seconds left before execution is not preserved.


Edited by Wims (07/12/18 11:00 PM)
_________________________
Looking for a good help channel about mIRC? Check #mircscripting @ irc.swiftirc.net

Top