Autor Beitrag
Euklid
Hält's aus hier
Beiträge: 10

Win XP

BeitragVerfasst: Mi 17.08.05 00:11 
Grüezi allerseits

Ich habe ein Programm nach dem alten Vorbild "Hopalong" bzw. "Hüpfer" geschrieben. Es geht dabei um eine rekursive Folge. Der neu berechnete x- und y-Wert werden je auf einem Canvas dargestellt. So weit, so gut. Nun habe ich einerseits eine Schleife eingebaut. Die Schleife berechnet alles und stellt das Bild dar, sobald alles fertig ist. Weil mich aber auch der Aufbau des entstehenden Bildes interessiert, habe ich auch noch einen Timer eingebaut. Nun kann man wählen, ob man das Bild mit dem Timer oder mit der Schleife zeichnen lassen will.
Das leidige Problem einmal mehr: Der Timer ist sehr langsam. Die Wahl des Intervalls spielt gar keine grosse Rolle, solange das Intervall unter etwa 50 ms bleibt. Danach glaube ich einen Unterschied zu bemerken. (Mir ist klar, dass der Timer eine sehr niedrige Systempriorität hat und all das, hab mich im Forum ein bisschen 'klug' gelesen, hoffe ich...)
Nun habe ich in einem Buch ("Borland Delphi 7, Grundlagen und Profiwissen" von Walter Doberenz und Thomas Kowalski) gelesen, dass der Timer abhängig vom Betriebssystem nur 18.2-mal pro Sekunde aufgerufen werden kann. Dividiert man nun 1000 ms durch die 18.2 bekommt man gerundet 55 ms. Das kann doch kein Zufall sein. Also ist nicht mein PC zu langsam, um die Operationen durchzuführen, sondern die niedrige Priorität des Timers im System macht mir einen Strich durch die Rechnung.
Gibt es eine andere Lösung, damit ich das Intervall dennoch tiefer einstellen kann? Ich habe mir überlegt, dass ich in die Schleife eine Pause (mit Break) einfügen könnte, aber das bringt ja nichts. Es sei denn, ich könnte das Bild bei jedem Schleifendurchlauf aktualisieren (zeichnen lassen)...

Vielen Dank fürs Durchlesen und gute Nacht
Euklid
LigH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 239

Win98SE, Win2000SP4
D7
BeitragVerfasst: Mi 17.08.05 01:05 
Titel: Re: Bild bei Schleifendurchlauf aktualisieren? (Timer zu lah
user profile iconEuklid hat folgendes geschrieben:
Dividiert man nun 1000 ms durch die 18.2 bekommt man gerundet 55 ms.

Eigentlich anders herum: Die 55 ms sind der Standardwert; 1000 / 55 ergibt rund 18,2.

Man kann sicherlich die Auflösung des Timers erhöhen - oder einen alternativen "Multimedia Highspeed Timer" verwenden (sollte man suchen können).

Die andere Möglichkeit wäre, tatsächlich direkt zu zeichnen - wenn auch Canvas.Pixel recht langsam ist, aber es gibt ja schnellere Alternativen (z.B. per ScanLine, oder mit Units wie FastImage / FastBMP / FastLib).
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Mi 17.08.05 01:11 
...oder einfach nen endlosloop mit sleep(50);

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
LigH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 239

Win98SE, Win2000SP4
D7
BeitragVerfasst: Mi 17.08.05 01:24 
Na ja - in "Sleep()" macht das Tool ja nix, verschwendet nur Wartezeit.

Das würde höchstens Sinn machen, wenn ein Thread in ein Hintergrundbild zeichnet, und ein anderer Thread diesen Hintergrund ab und zu mal auf ein Vordergrund-Image zeichnet. Aber ob das so der Hit ist...

Die Demo zu "FastLib" ist jedenfalls beeindruckend! >> delphi.icm.edu.pl/ftp/d20free/fastlib.zip
Euklid Threadstarter
Hält's aus hier
Beiträge: 10

Win XP

BeitragVerfasst: Mi 17.08.05 09:44 
Vielen Dank für die schnellen Antworten.

Hat jemand zufällig einen Link zu einem "Multimedia Highspeed Timer"? Bei Google habe ich nichts Entsprechendes gefunden (vielleicht hab ich falsch gesucht?).

@retnyg: Bei einem Endlos-Loop ergibt sich für mich auch das Problem, dass das Bild erst gezeichnet wird, nachdem alles fertigberechnet wurde (genau so wie bei der Schleife).

@Ligh: Ich werde mir jetzt die Demo zu FastLib anschauen, danke für den Link!

Gruss
Euklid
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 17.08.05 12:47 
user profile iconEuklid hat folgendes geschrieben:

@retnyg: Bei einem Endlos-Loop ergibt sich für mich auch das Problem, dass das Bild erst gezeichnet wird, nachdem alles fertigberechnet wurde (genau so wie bei der Schleife).

Dann würde ich deinem Fenster ab und zu in der Schelife mal etwas Luft geben zum Atmen bzw. zum Neuzeichnen des Fensters. Application.ProcessMessages wäre eine Lösung, wenn auch nicht die schönste, dafür aber die einfachste.
zemy
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 207

Win XP Prof.
D7
BeitragVerfasst: Mi 17.08.05 13:10 
...wenns dann zu schnell läuft, kannste ja immernoch ein sleep danach drannsetzen oder wenn es zu langsam ist, nur bei jedem 3., 4., 100. Schleifendurchlauf zeichnen. (if i mod 10 = 0 then applcation.ProcessMessages;) Sollte eigentlich funzen...

_________________
LifeIsToShortToThinkAboutTheShortness
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mi 17.08.05 14:51 
Also ich habe schon häufiger etwas mit dem Timer gemacht und kann dieses Phänomen absolut nicht bestätigen. Ich muss aber gestehen, dass ich keine Anwendung am laufen hatte die erhebliche CPU Last mit sich bringt. Evtl sieht es dann ganz anders aus. Klar ist der Timer nicht der Genauste aber so etwas wie, dass der nur maximal 55 mal aufgerufen wird ist mir völlig fremd. Bin aber nicht völlig davon abgeneigt mich überzeugen zu lassen.

Wie dem auch sei. Solche Möglichkeiten mit Endlosschleifen verteufel ich persönlich, da die Anwendung in einer Methode feststeckt und ich immer wieder merkwürdie Effekte damit hatte. Und nebenbei bemerkt finde ich das so etwas von unsauber programmiert, dass man nur auf Designfehler schließen kann...

Die saubere Alternative wäre zum Beispiel neben einem extra Thread das Event Application.OnIdle. Wenn du dort den Parameter Done auf False setzt wird diese Methode am laufenden Band aufgerufen. Neben den normalen Fensterbotschaften die dadurch nicht beeinträchtigt werden. Darin kannst du dann ganz bequem messen wie viel Zeit seit dem letzten Bild vergangen ist wartest entsprechende ms bis dein Interval wieder erreicht ist. Somit zeichnet deine Anwendung konsequent 30 Bilder in der Sekunde und das System wird nicht auslasten. Das gleiche Prinzip geht auch mit Timern. Interval auf 1ms und los gehts.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
Euklid Threadstarter
Hält's aus hier
Beiträge: 10

Win XP

BeitragVerfasst: Sa 20.08.05 10:42 
Vielen Dank allerseits!

Ich habe es jetzt so gelöst, wie Luckie und zemy es vorgeschlagen haben. Nun läuft alles zu meiner vollen Zufriedenheit.
Mag sein, dass es nicht die bestmögliche und sauberste Lösung ist, aber ich muss auch ein bisschen auf die Machbarkeit achten, die momentan noch ziemlich stark durch meine mageren Kenntnisse beschränkt ist...

Gruss
Euklid