Entwickler-Ecke

Sonstiges (Delphi) - OnIdle


Mortal-Shadow - Di 03.02.09 16:56
Titel: OnIdle
Hi,

ich habe angefangen ein bisschen mit opengl zu arbeiten, wo es hies, ich solle das zeichnen in onidle machen.
Wäre soweit auch toll nur ist mir dabei etwas sehr merkwürdiges aufgefallen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.IdleHandler(Sender: TObject; var Done: Boolean);
begin
oldtime := actualtime;
actualtime := Gettickcount;
memo1.Lines.Add(inttostr(actualtime-oldtime));
inc(Framescounter);
If (Framestime + 1000) < actualtime then
begin
        inc(Framestime, 1000);
        Form1.caption := inttostr(Framescounter);
        framescounter := 0;
end;
end;

sind alles int64.

Memo1 gibt mir nun sowas aus:

Also kurz: die frames sind zwischen 0 und über einer halben sekunde lang!
Woher kommt das?
Liegt das daran, dass events derart lahm abgefragt werden ( bis zu 500 ms)?
Und wie kann ich das ganze glätten?


Boldar - Di 03.02.09 16:58

das liegt villeicht mit daran, dass das TMemo dafür um einiges zu langsam ist...
und soweit ich weiss ist int64 irgendwie falsch implementiert und macht bei additionen und so mist, vielleicth liegt das daran?


Mortal-Shadow - Di 03.02.09 17:13

Ok, hab es jetzt so gemacht, dass ich erst alles in einen String geaddet hab und
erst zum Schluss ausgegeben habe.

Die "langen Phasen" sind jetzt halbiert (aber 219 ist immer noch extrem viel)
Was meinst du mit int64 falsch impelmentiert?
Kann man das fixen oder sollte ich ein anderes Format nehmen (welches - real?)
PS: Das ganze ist delphi 6 und nicht 7 bei mir.


GTA-Place - Di 03.02.09 17:18

Ähm... wo ist Done := False im Handler?


Mortal-Shadow - Di 03.02.09 17:29

Nirgends: da kommen noch aktionen rein.
Eben das zeichnen.
Und dass soll ja immer wieder neu gemacht werden.
Für den test hab ich bei #2 nur n button gemacht mit dem ich ne boolean auf false setzen kann.
Dann hört idle auf.


GTA-Place - Di 03.02.09 17:33

Dann füg Done := False ein (z.B. am Anfang der Funktion) und du wirst sehen, es funktioniert. Ansonsten wird OnIdle immer darauf warten, dass was passiert, z.B. dass du die Maus bewegst ;-)


Mortal-Shadow - Di 03.02.09 17:52

Ahw hab irgendwie gedacht du meinst: Done := true.
Deine Methode hat aber ein Problem - auch wenn es sau schnell ist - alles 0 ms jetzt -
und zwar dass das Programm auf Aktionen von ausen nicht mehr reagiert.
(Wie zum Beispiel Tastendruck, Maus gedrückt)
Aber eben deshalb hab ich ja OnIdle genommen statt eines Repeat..until false.
Ein application.processmessages bringt dabei auch nichts.

€: Ok, ich hab den Fehler gefunden.
Ich habe ja alles dem String hinzugefügt - aber der hat 120.000 Verlängerungen/sec natürlich nicht gepackt (-> zu groß)
Deshalb ist er da immer abgekackt.
Funktioniert jetzt alles dank done := false :-)