Recent

Author Topic: TTimer not firing....  (Read 189 times)

Prime

  • Jr. Member
  • **
  • Posts: 77
TTimer not firing....
« on: May 19, 2026, 12:42:03 pm »
Hi all,

Lazarus 4.6.0 on SuSE Tumbleweed, installed from RPM files (not suse repository).

I have a console mode application running in Linux that I need a regular tick for, so I have created a timer, set it's interval to 1000ms (1s) and set it's OnTimer event. However it doesn't seem to be running when set to enabled.

Code: Pascal  [Select][+][-]
  1. PROGRAM runforp;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. USES
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes, SysUtils, CustApp, Forms, extctrls, Interfaces
  10.   { you can add units after this };
  11.  
  12. TYPE
  13.  
  14.   { TRunFor }
  15.  
  16.   TRunFor = CLASS(TCustomApplication)
  17.   protected
  18.     RunTime         : INTEGER;
  19.     ReportTime      : INTEGER;
  20.     OutputFileName  : STRING;
  21.  
  22.     Ticks           : LongInt;
  23.     Timer           : TTimer;
  24.     Periods         : INTEGER;
  25.  
  26.     PROCEDURE DoRun; override;
  27.     FUNCTION GetTimeSeconds(FromString : STRING) : INTEGER;
  28.     FUNCTION GetTimeText(When   : TDateTime) : STRING;
  29.     PROCEDURE TimerTick(Sender : TObject);
  30.     PROCEDURE StartTimer;
  31.   public
  32.     CONSTRUCTOR Create(TheOwner: TComponent); override;
  33.     DESTRUCTOR Destroy; override;
  34.     PROCEDURE WriteHelp; virtual;
  35.   END;
  36.  
  37. CONST
  38.   OptSHelp          = 'h';  // Give some help
  39.   OptSRuntime       = 'r';  // Time to run.
  40.   OptSReportTime    = 'R';  // How often to report
  41.   OptSOutName       = 'p';  // Output filename
  42.  
  43.   OptLHelp          = 'help';       // Give some help
  44.   OptLRuntime       = 'runtime';    // Time to run.
  45.   OptLReportTime    = 'reporttime'; // How often to report
  46.   OptLOutName       = 'output';     // Output filename
  47.  
  48.   ShortOpts : STRING = OptSHelp         + '::' +
  49.                        OptSRuntime      + ':' +
  50.                        OptSReportTime   + ':' +
  51.                        OptSOutName      + ':';
  52.  
  53.   LongOptsArray : ARRAY[1..4] OF STRING = (
  54.                        OptLHelp         + '::',
  55.                        OptLRuntime      + ':' ,
  56.                        OptLReportTime   + ':' ,
  57.                        OptLOutName      + ':');
  58.  
  59. DefaultRuntime      = 60;
  60. DefaultReportTime       = 10;
  61. BuffSize                    = 32;
  62. DefaultOutFile      = '/dev/null';
  63. //TIMEBUFFSIZE  = 80;
  64. { TRunFor }
  65.  
  66. PROCEDURE WriteFmt(FormatStr    : STRING;
  67.                    Params       : ARRAY OF CONST);
  68. BEGIN;
  69.   Write(Format(FormatStr,Params));
  70. END;
  71.  
  72. PROCEDURE WriteLnFmt(FormatStr    : STRING;
  73.                      Params       : ARRAY OF CONST);
  74. BEGIN;
  75.   WriteLn(Format(FormatStr,Params));
  76. END;
  77.  
  78.  
  79. PROCEDURE TRunFor.StartTimer;
  80.  
  81. BEGIN;
  82.   Ticks:=0;
  83.   Periods:=0;
  84.   Timer.Enabled:=TRUE;
  85. END;
  86.  
  87. PROCEDURE TRunFor.TimerTick(Sender : TObject);
  88.  
  89. BEGIN;
  90.   Ticks:=Ticks+1;
  91.   Writeln('Tick!');
  92. END;
  93.  
  94. FUNCTION TRunFor.GetTimeText(When   : TDateTime) : STRING;
  95.  
  96. BEGIN;
  97.   Result:=FormatDateTime('ddd d mmmm yyyy hh:nn:ss',When);
  98. END;
  99.  
  100. FUNCTION TRunFor.GetTimeSeconds(FromString : STRING) : INTEGER;
  101.  
  102. VAR Scan    : INTEGER;
  103.     Buff    : STRING;
  104.     Total   : INTEGER = 0;
  105.     BuffCh  : CHAR;
  106.  
  107. BEGIN;
  108.   Buff:='';
  109.  
  110.   FOR Scan:=1 TO Length(FromString) DO
  111.   BEGIN;
  112.     BuffCh:=UpCase(FromString[Scan]);
  113.  
  114.     CASE BuffCh OF
  115.       'D'       : Total:=Total+(StrToIntDef(Buff,0) * (3600*24));
  116.       'H'       : Total:=Total+(StrToIntDef(Buff,0) * 3600);
  117.       'M'       : Total:=Total+(StrToIntDef(Buff,0) * 60);
  118.       'S'       : Total:=Total+StrToIntDef(Buff,0);
  119.       '0'..'9'  : Buff:=Buff+BuffCh;
  120.        ELSE
  121.          WriteLn('Error, invalid character in input ',BuffCh,' exiting!');
  122.  
  123.     END;
  124.  
  125.     IF (BuffCh IN ['D','H','M','S']) THEN
  126.       Buff:='';
  127.   END;
  128.   Result:=0;
  129. END;
  130.  
  131. PROCEDURE TRunFor.DoRun;
  132. VAR
  133.   ErrorMsg: String;
  134. BEGIN
  135.   // quick check parameters
  136.   ErrorMsg:=CheckOptions(ShortOpts, LongOptsArray);
  137.  
  138.   IF HasOption(OptSRuntime,OptLRuntime) THEN
  139.     RunTime:=GetTimeSeconds(GetOptionValue(OptSRuntime,OptLRuntime));
  140.  
  141.   IF HasOption(OptSReportTime,OptLReportTime) THEN
  142.       ReportTime:=GetTimeSeconds(GetOptionValue(OptSReportTime,OptLReportTime));
  143.  
  144.   IF HasOption(OptSOutName,OptLOutName) THEN
  145.       OutputFileName:=GetOptionValue(OptSOutName,OptLOutName);
  146.  
  147.   IF ErrorMsg<>'' THEN BEGIN
  148.     ShowException(Exception.Create(ErrorMsg));
  149.     Terminate;
  150.     Exit;
  151.   END;
  152.  
  153.   WriteLnFmt('Start time : %s',[GetTimeText(Now)]);
  154.   WriteLnFmt('Requested runtime : %d seconds, Report interval %d seconds',[RunTime,ReportTime]);
  155.   WriteLnFmt('Output filename : %s',[OutputFileName]);
  156.  
  157.  
  158.   StartTimer;
  159.   WHILE (Ticks < RunTime) DO
  160.   BEGIN;
  161.     IF ((Ticks MOD ReportTime) = 0) THEN
  162.     BEGIN;
  163.       Periods:=Periods+1;
  164.       WriteLnFmt('%d periods of %d seconds elapsed : %d seconds',[Periods,ReportTime,Ticks]);
  165.     END;
  166.     Sleep(1000);
  167.   END;
  168.  
  169.   WriteLnFmt('Complete, %d seconds elapsed',[Ticks]);
  170.   WriteLnFmt('End time : %s',[GetTimeText(Now)]);
  171.  
  172.   // stop program loop
  173.   Terminate;
  174. END;
  175.  
  176. CONSTRUCTOR TRunFor.Create(TheOwner: TComponent);
  177. BEGIN
  178.   INHERITED Create(TheOwner);
  179.   StopOnException:=True;
  180.   RunTime:=DefaultRuntime;
  181.   ReportTime:=DefaultReportTime;
  182.   OutputFileName:=DefaultOutFile;
  183.   Timer:=TTimer.Create(NIL);
  184.   Timer.Enabled:=FALSE;
  185.   Timer.Interval:=1000;
  186.   Timer.OnTimer:=@TimerTick;
  187. END;
  188.  
  189. DESTRUCTOR TRunFor.Destroy;
  190. BEGIN
  191.   Timer.Free;
  192.   INHERITED Destroy;
  193. END;
  194.  
  195. PROCEDURE TRunFor.WriteHelp;
  196. BEGIN
  197.   { add your help code here }
  198.   writeln('Usage: ', ExeName, ' <opts>');
  199.   WriteLn('Where options are : ');
  200.   WriteLn(' -h, --help         : Display help');
  201.   WriteLn(' -r, --runtime=     : Specify runtime');
  202.   WriteLn(' -R, --reporttime=  : Specify time between reports');
  203.   WriteLn(' -p, --output=      : Specify output file');
  204.   WriteLn;
  205.   WriteLn('Times are specified by giving one or 2 digits and then a unit specifier');
  206.   WriteLn(' d=days, h=hours, m=minutes, s=seconds. Multiple specifiers are valid');
  207.   WriteLn('e.g. 5h30m for 5 hours and 30 minutes');
  208. END;
  209.  
  210. VAR
  211.   Application: TRunFor;
  212. BEGIN
  213.   Application:=TRunFor.Create(NIL);
  214.   Application.Title:='RunFor';
  215.   Application.Run;
  216.   Application.Free;
  217. END.
  218.  
  219.  

Any hints as to what the problem might be?

Cheers.

Phill.

jamie

  • Hero Member
  • *****
  • Posts: 7774
Re: TTimer not firing....
« Reply #1 on: May 19, 2026, 01:00:27 pm »
I could be wrong but i dont think that is going to work on anything but windows.

Timers are message driven from the os.

You could try simulating a timer in a thread and post a lm_timer message to the message loop.

Using the gettick64 call allows you to monitor the count in a loop, once a count is reached you post, update the starting for the next count.
The only true wisdom is knowing you know nothing

bytebites

  • Hero Member
  • *****
  • Posts: 789
Re: TTimer not firing....
« Reply #2 on: May 19, 2026, 01:06:59 pm »

ITomi

  • Newbie
  • Posts: 4
Re: TTimer not firing....
« Reply #3 on: May 19, 2026, 01:23:05 pm »
Hello Prime!

Maybe the Timer can't start because of Timer.Enabled:=FALSE; command in line 184?

Thausand

  • Hero Member
  • *****
  • Posts: 560
Re: TTimer not firing....
« Reply #4 on: May 19, 2026, 01:35:39 pm »
Timers are message driven from the os.
or thread, interrupt etc.

Maybe the Timer can't start because of Timer.Enabled:=FALSE; command in line 184?
That is why code have StartTimer that is set Enable := true.

@Prime:
bytesbites correct, have use TFPTimer and have UseTimerThread set true.
« Last Edit: May 19, 2026, 01:37:20 pm by Thausand »
A docile goblin always follow HERMES.md

Prime

  • Jr. Member
  • **
  • Posts: 77
Re: TTimer not firing....
« Reply #5 on: May 19, 2026, 02:40:46 pm »
Thanks all, TFPTimer seems to work correctly and does as I want.

Cheers.

Phill.

 

TinyPortal © 2005-2018