Vepir
Vepir

Reputation: 602

Delphi XE8 TThread Frozen on Android, but works on Windows

I use one thread and a synchronized procedure for a simple game loop. On my computer, Windows 7, it works as a charm but when I run it on my android device and after I click play and the thread starts the screen goes black or sometimes dim, and sometimes it stays normal but all objects visible on screen either stretch or fail to render properly; at this point the thread seems to be frozen (The music from the main form still continue to play).

Here is the thread itself:

procedure TTheThread.Loop;
begin
  MainForm.GameLoop;
end;

procedure TTheThread.Execute;
begin

    while NOT Terminated do 
    begin
      Application.ProcessMessages;

      TC:= TStopwatch.GetTimeStamp;

      //The Following repeats itself every second:    
      if TC>(TCTime+10000000) then
      begin
        TCTime:= TStopwatch.GetTimeStamp;
        TimeT:= TimeT+1; //Time in seconds

        //Increasing game playing speed:
        Gravity:= Gravity + 0.0075 * DEF;
        PJump:= PJump+IncJump
      end;

      //...just to have it on screen:
      With MainForm do
      Label1.Text:= IntToStr(TC);

      //This seems to make the loop run smooth and without lagging on my PC:    
      if TC>(TCLast) then
      begin
        Synchronize(Loop);
        TCLast:= TC;
      end;

    end;

end;

This is how it starts:

  TCTime:= TStopwatch.GetTimeStamp;
  TCLast:= TCTime;

  GameThread:= TTheThread.Create(True);
  GameThread.FreeOnTerminate:= True;
  GameThread.Start;

Upvotes: 1

Views: 671

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596527

Your thread has some unsafe code in it, which can easily cause deadlocks and dead UIs (amongst other issues). DO NOT access UI controls directly in a thread, you must synchronize with the main UI thread, such as with TThread.Synchronize() or TThread.Queue(), eg:

TThread.Synchronize(nil,
  procedure
  begin
    MainForm.Label1.Text := IntToStr(TC);
  end
);

Also, do not call Application.ProcessMessages() in a thread, either. It belongs in the main UI thread only. And even then, if you have to report to calling it at all, you are likely doing something wrong to begin with. Under normal conditions, you should never have to resort to calling it manually.

Upvotes: 2

Related Questions