Recent

Author Topic: Game style timer use question  (Read 3532 times)

jbmckim

  • Full Member
  • ***
  • Posts: 144
Game style timer use question
« on: May 24, 2017, 07:38:00 pm »
I'm testing TTimer to evaluate its use in a game style dispatch loop.  (The application is actually interrogating and displaying instrument data but the idea is substantially the same.)  Here's what I've come up with for a blocking (blocking in the sense the TTimer will not again execute until the instructions) TTimer loop:   

Code: Pascal  [Select][+][-]
  1. procedure TSpectrometerInterfaceForm.Timer1Timer(Sender: TObject);
  2. begin
  3.   Timer1.Enabled := False;
  4.   Scan_Procedure();
  5.   Timer1.Enabled := True;
  6. end;

Do I have this right or is there another (better) way to do this?  Clearly, exiting and messagebox style UI inside the loop will have to be managed.  Are there other considerations as well.

Thanks.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Game style timer use question
« Reply #1 on: May 24, 2017, 08:13:06 pm »
It partly depends on how CPU-intensive your Scan_Procedure is, and whether it matters if your GUI is unresponsive for a second or two.
Another approach is to use the Application.OnIdle event
Code: Pascal  [Select][+][-]
  1. procedure TForm1.AppOnIdle(Sender: TObject; var Done: Boolean);
  2. begin
  3.   if DataHasChanged then begin
  4.     ShowOrLogUpdatedData;
  5.     Done:=True;
  6.   end
  7.   else Done:=True;
  8. end;

jbmckim

  • Full Member
  • ***
  • Posts: 144
Re: Game style timer use question
« Reply #2 on: May 24, 2017, 09:07:04 pm »
"It partly depends on how CPU-intensive your Scan_Procedure is, and whether it matters if your GUI is unresponsive for a second or two."

I'm using the TTimer in my prototype now and not seeing an unresponsive GUI. Is it the "good" guy or the "bad" guy?

A bit more info:  The timer is set to 1milsec.  The instruments are all at least 3milsec and usually more, sometimes a lot more.

The next thing I need to prototype is threading the instrument call when n instruments (where n is > 1) are used.  That will be a "block until all threads complete" flavor of threading.  Any considerations/issues doing that inside a TTimer branch?

krolikbest

  • Full Member
  • ***
  • Posts: 246
Re: Game style timer use question
« Reply #3 on: May 24, 2017, 10:45:11 pm »
i'm not sure but perhaps you'd like to do:

inside some procedure (button.onClick or whatever)
timer.enabled:=True;

then in timer.onTimer you write:
Scan_Procedure();
timer.enabled:=False;
end;

Martin

PatBayford

  • Full Member
  • ***
  • Posts: 125
Re: Game style timer use question
« Reply #4 on: May 24, 2017, 10:59:51 pm »
That approach will definitely work, just be very sure you are doing as little processing as possible inside the "Scan_Procedure"!!!
Lazarus 1.8.0 FPC 3.0.2 SVN 56594 Windows 10 64bit (i386-win32-win32/win64)

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Game style timer use question
« Reply #5 on: May 25, 2017, 12:23:13 am »
That approach will definitely work, just be very sure you are doing as little processing as possible inside the "Scan_Procedure"!!!
Shouldn't matter. Even if Timer interval is 10ms and "Scan_Procedure" takes 1 minute, multiple clicks during that process will not simultaneously start a second one. Using TTimer is not an alternative to actual threading, so that scan may lock down rest of the program unless using Application.ProcessMessages.
« Last Edit: May 25, 2017, 12:25:22 am by User137 »

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 844
Re: Game style timer use question
« Reply #6 on: May 25, 2017, 08:26:53 am »
Not sure about Linux, but on Windows TTimer should use WM_TIMER, that is window message and therefore no any other message can be processed, including new WM_TIMER, till this one won't end. But this is true, only if you don't call Application.ProcessMessages inside OnTimer.

Timer create proc for Windows. It uses standard SetTimer API.
Code: Pascal  [Select][+][-]
  1. function TWin32WidgetSet.CreateTimer(Interval: integer; TimerFunc: TWSTimerProc) : THandle;
  2. var
  3.   TimerInfo: PWin32TimerInfo;
  4. begin
  5.   Result := 0;
  6.   if (Interval > 0) and (TimerFunc <> nil) then begin
  7.     New(TimerInfo);
  8.     TimerInfo^.TimerFunc := TimerFunc;
  9.     TimerInfo^.TimerID := Win32Extra.SetTimer(0, 0, Interval, @TimerCallBackProc);
  10.     if TimerInfo^.TimerID=0 then
  11.       dispose(TimerInfo)
  12.     else begin
  13.       FTimerData.Add(TimerInfo);
  14.       Result := TimerInfo^.TimerID;
  15.     end;
  16.   end;
  17. end;
  18.  

Quote
If you specify a window handle in the call to SetTimer, the application associates the timer with that window. Whenever the time-out value for the timer elapses, the system posts a WM_TIMER message to the window associated with the timer. If no window handle is specified in the call to SetTimer, the application that created the timer must monitor its message queue for WM_TIMER messages and dispatch them to the appropriate window. If you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

P.S. My own experience of game development shows, that trying to do everything in continuous and asynchronous fashion via using timers - is really bad idea. This complicates whole process a lot and causes lots of problems with synchronization and game logic. Approach, all real games and applications use - using so called frames, i.e. fixed quanta of time. In most cases internal game frames are synchronized with monitor update frequency, cuz it's better to flip video memory pages during retrace, so both logical and visual frames become essentially the same thing. If it isn't possible - frame skip can always be performed.
« Last Edit: May 25, 2017, 10:06:15 am by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Game style timer use question
« Reply #7 on: June 04, 2017, 02:25:59 am »
Application.OnIdle generally performs far better than TTimers. However, there's definitely situations where Application.OnIdle isn't suitable or even possible to use at all due to the inherent lack of customizability.

 

TinyPortal © 2005-2018