Re: [Lazarus] TTimer woes (newbie)

2014-04-01 Thread Michael Schnell

On 03/31/2014 07:51 PM, Flávio Etrusco wrote:


TTimer in Windows (and the basic timer support in Windows ) is 
implemented using window messages and you're not allowing the app to 
process messages inside your loop.


This necessity is not limited to Windows nor to TTimer.


Any Object Pascal Event handler (hence most code done in normal 
projects) is driven by the Project's Event Queue (which in Windows in 
turn is driven by Windows messages).


In fact using Application.ProcessMessages in a loop is a workaround 
that is necessary when you really need a long winding loop in one of the 
(main Thread-) - Events) calculating something.


It is a lot better style to do short events, whenever possible (maybe 
doing the long winding stuff in a TThread). Infinite (polling) loops in 
fact are (close to) forbidden, as they eat up CPU cycles that can better 
be used for other activities in the project or in any other program 
running on that PC.


In fact Bob is not doing this (eating up CPU Cycles), but he uses 
wait(), which only hampers it's own project. This also usually is (close 
to) forbidden in the main thread, as the GUI will stop working while the 
main thread waits.


Thus he should either use a TTimer instead of waiting and continue the 
work to be done in a newly entered Timer Event, or execute the code that 
includes the wait() in a TThread.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-04-01 Thread Howard Page-Clark

On 01/04/2014 09:44, Michael Schnell wrote:


In fact Bob is not doing this (eating up CPU Cycles), but he uses
wait(), which only hampers it's own project.


Actually Bob's wait uses his own TTimer-based code, and is not well 
designed.
As Flavio wrote, he would be best to replace all his waits with a Sleep, 
and remove his timer altogether.


Howard


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-04-01 Thread Paul Breneman

On 03/31/2014 01:51 PM, Flávio Etrusco wrote:
...

I guess simply changing your loop to:
+++
repeat
   Application.ProcessMessages;
until not timer1.enabled;
+++
should make it work.


That loop will work, but the CPU usage will be 100% and the CPU will run 
warm and the battery life on a laptop will be bad.  I'd normally add a 
Sleep(10) in the loop to avoid those problems.


Best regards,
Paul
www.TurboControl.com


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-03-31 Thread Michael Schnell

On 03/31/2014 01:44 AM, Bob Axtell wrote:

can someone show a newbie how to use the two system timers?


What do you mean by system timers ?

In a normal GUI based application you normally use TTimer for time-based 
actions.


You easily can create as many TTimers as you like (as well visually 
using the Lazarus GUI designer) as dynamically by having your program 
do myTimerN := TTimer.Create(Self); )



-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-03-31 Thread Howard Page-Clark

On 31/03/2014 10:25, Michael Schnell wrote:

On 03/31/2014 01:44 AM, Bob Axtell wrote:

can someone show a newbie how to use the two system timers?


What do you mean by system timers ?


I think he means the TTimer and TIdleTimer found on the System page of 
the Component Palette.
If you drop one of each on the main form of a new project with a label 
and a memo, and add this code, it should give you an idea of how to use 
them.


-- code begin --

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  SysUtils, Forms, ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
IdleTimer1: TIdleTimer;
LAverageSoFar: TLabel;
MNumbers: TMemo;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure IdleTimer1Timer(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
  private
FNumber: integer;
FRunningTotal: integer;
FCount: integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  MNumbers.Clear;

  Timer1.Interval:=500;
  Timer1.OnTimer:=@Timer1Timer;
  Timer1.Enabled:=True;

  IdleTimer1.Interval:=1000;
  IdleTimer1.OnTimer:=@IdleTimer1Timer;
  IdleTimer1.Enabled:=True;
end;

procedure TForm1.IdleTimer1Timer(Sender: TObject);
begin
  LAverageSoFar.Caption:=
Format('Average of random numbers so far is 
%n',[FRunningTotal/FCount]);

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  FNumber:=Random(101);
  MNumbers.Lines.Add(IntToStr(FNumber));
  Inc(FCount);
  Inc(FRunningTotal, FNumber);
end;

end.

-- code end --

Howard


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-03-31 Thread Bob Axtell
mine (a morse-code blinker) just doesn't work:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
Panel1: TPanel;
Timer1: TTimer;
procedure FormKeyPress(Sender: TObject; var Key: char);
procedure Timer1Timer(Sender: TObject);
  private
{ private declarations }
procedure morse;
procedure dash;
procedure dot;
procedure wait(x: longint);
{ public declarations }
 end;

var
  Form1: TForm1;
  a,b,i: byte;
  count,dat,
  ms,ls,mchar: byte;
  tick: integer;
  col: integer = clblue;
  mtbl: string[16] =
   #$bf#$be#$bc#$b8#$b0#$a0#$a1#$a3#$a7#$af#$42#$81#$85#$61#$20#$84;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 timer1.enabled:= false;
end;

procedure TForm1.wait(x: longint);
begin
 tick:= x;
 while tick  0 do
  begin
timer1.enabled:= true;
repeat until not timer1.enabled;
dec(tick)
  end;
end;

procedure Tform1.dash;
begin
 Panel1.color:= col;
 wait(30);
 Panel1.color:= clwhite;
 wait(10);
end;

procedure Tform1.dot;
begin
 panel1.color:= col;
 wait(10);
 panel1.color:= clwhite;
 wait(10);
end;

procedure tform1.morse;
begin
 mchar:= $33;
 ms:= ord(mtbl[succ((mchar shr 4) and 15)]);
 ls:= ord(mtbl[succ(mchar and 15)]);
 count:= (ms shr 5) and 7;
 dat:= ms and 31;
 for i:= 1 to count do
 begin
  if ((dat and 1)  0) then dash else dot;
  wait(10);
  dat:= dat shr 1;
 end;
 wait(50);
 { ms done, ls begins}
 count:= (ls shr 5) and 7;
 dat:= ls and 31;
 for i:= 1 to count do
 begin
  if ((dat and 1)  0) then dash else dot;
  wait(10);
 end;
 wait(100);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
   case key of
   'r': begin
 col:= clred;
 wait(15);
end;
   'g': begin
 col:= clgreen;
 wait(15);
end;
   'b': begin
 col:= clblue;
 wait(15);
end;
   ' ': morse;
  end;

end;

end.

any ideas? using v1.0.14 under WinXP.

--Bob A





On Mon, Mar 31, 2014 at 2:35 AM, Howard Page-Clark h...@talktalk.netwrote:

 On 31/03/2014 10:25, Michael Schnell wrote:

 On 03/31/2014 01:44 AM, Bob Axtell wrote:

 can someone show a newbie how to use the two system timers?


 What do you mean by system timers ?


 I think he means the TTimer and TIdleTimer found on the System page of the
 Component Palette.
 If you drop one of each on the main form of a new project with a label and
 a memo, and add this code, it should give you an idea of how to use them.

 -- code begin --

 unit Unit1;

 {$mode objfpc}{$H+}

 interface

 uses
   SysUtils, Forms, ExtCtrls, StdCtrls;

 type

   { TForm1 }

   TForm1 = class(TForm)
 IdleTimer1: TIdleTimer;
 LAverageSoFar: TLabel;
 MNumbers: TMemo;
 Timer1: TTimer;
 procedure FormCreate(Sender: TObject);
 procedure IdleTimer1Timer(Sender: TObject);
 procedure Timer1Timer(Sender: TObject);
   private
 FNumber: integer;
 FRunningTotal: integer;
 FCount: integer;
   end;

 var
   Form1: TForm1;

 implementation

 {$R *.lfm}

 { TForm1 }

 procedure TForm1.FormCreate(Sender: TObject);
 begin
   Randomize;
   MNumbers.Clear;

   Timer1.Interval:=500;
   Timer1.OnTimer:=@Timer1Timer;
   Timer1.Enabled:=True;

   IdleTimer1.Interval:=1000;
   IdleTimer1.OnTimer:=@IdleTimer1Timer;
   IdleTimer1.Enabled:=True;
 end;

 procedure TForm1.IdleTimer1Timer(Sender: TObject);
 begin
   LAverageSoFar.Caption:=
 Format('Average of random numbers so far is
 %n',[FRunningTotal/FCount]);
 end;

 procedure TForm1.Timer1Timer(Sender: TObject);
 begin
   FNumber:=Random(101);
   MNumbers.Lines.Add(IntToStr(FNumber));
   Inc(FCount);
   Inc(FRunningTotal, FNumber);
 end;

 end.

 -- code end --

 Howard



 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] TTimer woes (newbie)

2014-03-31 Thread Flávio Etrusco
On Mon, Mar 31, 2014 at 2:24 PM, Bob Axtell bob.axt...@gmail.com wrote:

 mine (a morse-code blinker) just doesn't work:

 unit Unit1;

 {$mode objfpc}{$H+}

 interface

 uses
   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
 ExtCtrls;

 type

   { TForm1 }

   TForm1 = class(TForm)
 Panel1: TPanel;
 Timer1: TTimer;
 procedure FormKeyPress(Sender: TObject; var Key: char);
 procedure Timer1Timer(Sender: TObject);
   private
 { private declarations }
 procedure morse;
 procedure dash;
 procedure dot;
 procedure wait(x: longint);
 { public declarations }
  end;

 var
   Form1: TForm1;
   a,b,i: byte;
   count,dat,
   ms,ls,mchar: byte;
   tick: integer;
   col: integer = clblue;
   mtbl: string[16] =
#$bf#$be#$bc#$b8#$b0#$a0#$a1#$a3#$a7#$af#$42#$81#$85#$61#$20#$84;

 implementation

 {$R *.lfm}

 { TForm1 }

 procedure TForm1.Timer1Timer(Sender: TObject);
 begin
  timer1.enabled:= false;
 end;

 procedure TForm1.wait(x: longint);
 begin
  tick:= x;
  while tick  0 do
   begin
 timer1.enabled:= true;
 repeat until not timer1.enabled;
 dec(tick)
   end;
 end;

 procedure Tform1.dash;
 begin
  Panel1.color:= col;
  wait(30);
  Panel1.color:= clwhite;
  wait(10);
 end;

 procedure Tform1.dot;
 begin
  panel1.color:= col;
  wait(10);
  panel1.color:= clwhite;
  wait(10);
 end;

 procedure tform1.morse;
 begin
  mchar:= $33;
  ms:= ord(mtbl[succ((mchar shr 4) and 15)]);
  ls:= ord(mtbl[succ(mchar and 15)]);
  count:= (ms shr 5) and 7;
  dat:= ms and 31;
  for i:= 1 to count do
  begin
   if ((dat and 1)  0) then dash else dot;
   wait(10);
   dat:= dat shr 1;
  end;
  wait(50);
  { ms done, ls begins}
  count:= (ls shr 5) and 7;
  dat:= ls and 31;
  for i:= 1 to count do
  begin
   if ((dat and 1)  0) then dash else dot;
   wait(10);
  end;
  wait(100);
 end;

 procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
 begin
case key of
'r': begin
  col:= clred;
  wait(15);
 end;
'g': begin
  col:= clgreen;
  wait(15);
 end;
'b': begin
  col:= clblue;
  wait(15);
 end;
' ': morse;
   end;

 end;

 end.

 any ideas? using v1.0.14 under WinXP.

 --Bob A


TTimer in Windows (and the basic timer support in Windows ) is implemented
using window messages and you're not allowing the app to process messages
inside your loop.

I guess simply changing your loop to:
+++
   repeat
  Application.ProcessMessages;
   until not timer1.enabled;
+++
should make it work.
If it's no problem that your app freezes the UI during the wait (like it
does right now) you could just use Sleep() and abandon TTimer.
OTOH the usual way to use TTimer is to do processing in the OnTimer
handler, but then you'd have to change your code to store some state.

Regards,
Flávio
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] TTimer woes (newbie)

2014-03-30 Thread Bob Axtell
can someone show a newbie how to use the two system timers?

--Bob A
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus