PDA

View Full Version : Forms TTimer tutorial



Freddy1990
11-19-2006, 09:59 PM
In this tutorial we will learn how to add and use the TTimer component in SCAR forms.
Timers can be used for multithreading, each timer represents a separed thread.

We begin with a basic script that shows a form:
program TimerTest

var
frmDesign: TForm;

procedure InitForm;
begin
frmDesign := CreateForm;
frmDesign.Left := 259;
frmDesign.Top := 132;
frmDesign.Width := 354;
frmDesign.Height := 254;
frmDesign.Caption := 'Menu Testing Form';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := False;
frmDesign.PixelsPerInch := 96;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
SetArrayLength(v, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
SetArrayLength(v, 0);
ThreadSafeCall('ShowFormModal', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
end.
http://stuart.existhost.com/freddy/tutimages/menu1.PNG
Timer components are invisible, so this is the only pic i'll be needing :)

We're going to add 2 timers and make each of them run a procedure on different intervals.
First we declare the timer componenet variables:
tmr1, tmr2: TTimer;

Now we create the timer objects in our form:
tmr1 := TTimer.Create(frmDesign);
tmr2 := TTimer.Create(frmDesign);

The 2 different intervals will be 500ms and 1000ms, so we're going to set outr timers with those intervals:
tmr1.Interval := 500;
tmr2.Interval := 1000;

Now we will need some procedures to run with the timers, these are just like the ones used with onclick events:
procedure Timer1(sender: TObject);
begin
WriteLn('Timer1 looping!');
end;

procedure Timer2(sender: TObject);
begin
WriteLn('Timer2 looping!');
end;

While we use the onclick event for buttons, timers use the ontimer event, so we add the procedures to that event:
tmr1.OnTimer := @Timer1;
tmr2.OnTimer := @Timer2;

We end with the followig script:
program TimerTest;

var
frmDesign: TForm;
tmr1, tmr2: TTimer;

procedure Timer1(sender: TObject);
begin
WriteLn('Timer1 looping!');
end;

procedure Timer2(sender: TObject);
begin
WriteLn('Timer2 looping!');
end;

procedure InitForm;
begin
frmDesign := CreateForm;
frmDesign.Left := 259;
frmDesign.Top := 132;
frmDesign.Width := 354;
frmDesign.Height := 254;
frmDesign.Caption := 'Menu Testing Form';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := False;
frmDesign.PixelsPerInch := 96;

tmr1 := TTimer.Create(frmDesign);
tmr1.Interval := 500;
tmr1.OnTimer := @Timer1;

tmr2 := TTimer.Create(frmDesign);
tmr2.Interval := 1000;
tmr2.OnTimer := @Timer2;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('ShowFormModal', v);
end;

begin
SafeInitForm;
SafeShowFormModal;
FreeForm(frmDesign);
end.

Now when we run the script we'll get a nice output, for every time it says "Timer2 looping!", it says "Timer1 looping!" twice.


Timer1 looping!
Timer1 looping!
Timer2 looping!
Timer1 looping!
Timer1 looping!
Timer2 looping!
Timer1 looping!
Timer1 looping!
Timer2 looping!

That was it, have fun!

Yakman
11-19-2006, 10:37 PM
i knew about these, i learnt from kaitnieks game, Bejewled,

i used it to make a scar game called paper scissors stone, i can upload it here if you dont belive me

EDIT : i didnt know about setting the interval, my game has 100 TTimers which go off 10ms within each other

JuKKa
11-19-2006, 11:08 PM
i wanna play it!!!

Yakman
11-19-2006, 11:25 PM
ok here it is

i was intended as a test to see if i could combine FastDrawing and Forms

i can, but drawing on the form canvas too quickly gives strange runtime errors :confused:

enjoy
Paper Scissors Stone by Yakman!

Janilabo
11-19-2006, 11:49 PM
Very nice job Freddy

Rick
11-19-2006, 11:54 PM
very nice. 2nd tut. keep em coming. :P

yakman- nice game but... yes it gives strange runtime errors

Freddy1990
11-20-2006, 06:18 AM
Hmm, i didn't know bejeweled had timers

YoHoJo
11-20-2006, 06:58 AM
damn yaka very nice.
You are just too good with forums and all that grand utility hubba jub!
Wonderfull!

oh yea...
nice tut fredy =p

Freddy1990
11-20-2006, 03:05 PM
damn yaka very nice.
You are just too good with forums and all that grand utility hubba jub!
Wonderfull!

oh yea...
nice tut fredy =p

hmm thx for noticing... :P

n3ss3s
05-01-2007, 06:28 PM
Nice tut, all of SRL Devs' TUTs are easy to learn.

Smartzkid
05-06-2007, 02:52 AM
Awesome tut, but I have one question...why do ttimers have to be tied to a form? They still run when the parent form is closed, so why can't they be independant?


program TimerTest;

var
frmDesign: TForm;
tmr1, tmr2, tmr3, tmr4: TTimer;

procedure Timer1(sender: TObject);
begin
WriteLn('Timer1 looping!');
end;

procedure Timer2(sender: TObject);
begin
WriteLn('Timer2 looping!');
end;

procedure Timer3(sender: TObject);
begin
ClearDebug;
end;

procedure Timer4(sender: TObject);
begin
tmr1.Free;
tmr2.Free;
tmr3.Free;
tmr4.Free;
ClearDebug;
writeln('Exited');
TerminateScript;
end;

procedure InitForm;
begin
frmDesign := CreateForm;
frmDesign.Left := 259;
frmDesign.Top := 132;
frmDesign.Width := 354;
frmDesign.Height := 254;
frmDesign.Caption := 'Menu Testing Form';
frmDesign.Color := clBtnFace;
frmDesign.Font.Color := clWindowText;
frmDesign.Font.Height := -11;
frmDesign.Font.Name := 'MS Sans Serif';
frmDesign.Font.Style := [];
frmDesign.Visible := False;
frmDesign.PixelsPerInch := 96;

tmr1 := TTimer.Create(frmDesign);
tmr1.Interval := 500;
tmr1.OnTimer := @Timer1;

tmr2 := TTimer.Create(frmDesign);
tmr2.Interval := 1000;
tmr2.OnTimer := @Timer2;

tmr3 := TTimer.Create(frmDesign);
tmr3.Interval := 3000;
tmr3.OnTimer := @Timer3;

tmr4 := TTimer.Create(frmDesign);
tmr4.Interval := 6000;
tmr4.OnTimer := @Timer4;
end;

procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('InitForm', v);
end;

procedure ShowFormModal;
begin
frmDesign.ShowModal;
end;

procedure SafeShowFormModal;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('ShowFormModal', v);
end;

begin
ClearDebug;
SafeInitForm;
wait(7000);
// SafeShowFormModal;
// FreeForm(frmDesign);
end.

Hugolord
05-06-2007, 01:54 PM
ok here it is

i was intended as a test to see if i could combine FastDrawing and Forms

i can, but drawing on the form canvas too quickly gives strange runtime errors :confused:

enjoy
Paper Scissors Stone by Yakman!

uu i love this game !

botmaster
05-07-2007, 11:23 AM
Can TTimer objects be initialized without binding them to a form entirely? I'm creating a program that would benefit a lot from TTimers, however I don't want to waste memory on a form (not really important, but my programming style HATEZ wasted mem).

Jason2gs
05-13-2007, 01:32 AM
Ooooh...

Learned me somethin' new!

Thanks ;)

danrox2004
05-13-2007, 01:59 AM
Can TTimer objects be initialized without binding them to a form entirely? I'm creating a program that would benefit a lot from TTimers, however I don't want to waste memory on a form (not really important, but my programming style HATEZ wasted mem).

function SetTimeout(secs: Cardinal; procname: string): Integer; might work depending on what you want to use it for

Harled
06-01-2007, 01:52 PM
A very nice and clear tutorial. Thanks.

Wizzup?
01-28-2008, 01:06 PM
I didn't feel like making another topic on TTimers, so I'll make a quick post on how to use TTimers without an extra form. (So you add them directly to the SCAR form)

program New;

var
Timer: TTimer;

Procedure hi(Sender: TObject);

begin
writeln('hi');
end;

Procedure CreateTimer;

Begin
Timer := TTimer.Create(nil);
Timer.Interval := 2000;
Timer.Enabled := True;
Timer.OnTimer := @hi;
End;

Procedure DeleteTimer;

Begin
Timer.Enabled := False;
Timer.Free;
End;

Procedure ScriptTerminate;

Var
V: TVariantArray;

Begin
SetLength(V, 0);
ThreadSafeCall('DeleteTimer', V);
End;

Var
V: TVariantArray;
t: integer;
begin
SetLength(V, 0);
ThreadSafeCall('CreateTimer', V);
t := getsystemtime;
Repeat
Wait(100);
Until getsystemtime - t > 8000;
end.

The ScriptTerminate procedure becomes very handy in this case, because you always want to free and stop the Timer at the end of the script, if you don't, in this case every 2000 milliseconds an Access Violation will come up.
It's very funny to use this kind of timers to write progress reports:

Worked for 12 Minutes and 0 Seconds
Attacked 61 monsters.
Ate 1 Foodies.
Picked up arrows 10 times.


Worked for 13 Minutes and 0 Seconds
Attacked 67 monsters.
Ate 2 Foodies.
Picked up arrows 14 times.


Worked for 14 Minutes and 0 Seconds
Attacked 73 monsters.
Ate 2 Foodies.
Picked up arrows 15 times.

SKy Scripter
01-28-2008, 06:44 PM
Last time i added a Timer without a form... ouch...

Wizzup?
01-28-2008, 07:06 PM
Last time i added a Timer without a form... ouch...

Yes. Popup spammage. ;)
Thats why I currently fell in love with ScriptTerminate, it allows you to sort of safely free all the timers outside the SCAR script thread.
Don't use the quick stop though, (twice ctrl + alt + s, or just keep hitting the red stop) that way it won't call ScriptTerminate and the popup's keep coming.

MasterKill
01-28-2008, 07:32 PM
hehe that timer is kinda the same in VB6

um wizzup, if i use that, will it be looping while my script is playing to? that would be awesome.

:)

Wizzup?
01-28-2008, 09:54 PM
hehe that timer is kinda the same in VB6

um wizzup, if i use that, will it be looping while my script is playing to? that would be awesome.

:)

Yes. Dont make both the Timers and the Script Engine use the Mouse though. ;)

MasterKill
01-29-2008, 06:31 AM
Yes. Dont make both the Timers and the Script Engine use the Mouse though. ;)

rofl i'm not that stupid :D anyway that is uber awesome! o i'll use this, thanks :)