PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++: While-Schleife nicht unterbrechbar?


WhiteVelvet
2005-05-27, 11:49:20
Mit Hilfe eines Coin3D Timers möchte ich eine For-Schleife ausbremsen, um eine Animation ablaufen zu lassen:

for (i=0;i<100;i++)
{
berechne mir irgendwas
mach damit was

global_timer_variable_vom_typ-bool=FALSE;
while (!global_timer_variable_vom_typ-bool)
tue nichts
}

Der Timer setzt im Hintergrund jede Sekunde die bool-Variable auf TRUE, damit er die while-Schleife verlässt, aber die while-Schleife lässt dem Timer keine Chance und die Variable wird niemals TRUE. Was kann ich dagegen machen? Hoffentlich hat das nichts mit komplizierter Thread-Programmierung zutun :(

EDIT: Ich hörte eben bool volatile soll helfen, aber es bringt nichts. Die Schleife scheint den Timer Thread "schlafen zu schicken".

ShadowXX
2005-05-27, 12:00:21
Mit Hilfe eines Coin3D Timers möchte ich eine For-Schleife ausbremsen, um eine Animation ablaufen zu lassen:

for (i=0;i<100;i++)
{
berechne mir irgendwas
mach damit was

global_timer_variable_vom_typ-bool=FALSE;
while (!global_timer_variable_vom_typ-bool)
tue nichts
}

Der Timer setzt im Hintergrund jede Sekunde die bool-Variable auf TRUE, damit er die while-Schleife verlässt, aber die while-Schleife lässt dem Timer keine Chance und die Variable wird niemals TRUE. Was kann ich dagegen machen? Hoffentlich hat das nichts mit komplizierter Thread-Programmierung zutun :(

EDIT: Ich hörte eben bool volatile soll helfen, aber es bringt nichts. Die Schleife scheint den Timer Thread "schlafen zu schicken".

Brauchst du den Timer unbedingt bzw. hat die Routine innerhalb des Timers irgendwelche zusammenhänge mit der For-Schleife?

Falls nicht.....warum benutzt du nicht einfach "sleep" zum ausbremsen??

Demirug
2005-05-27, 12:12:01
WhiteVelvet, da optimiert dir wohl der Compiler (zu recht) die Schleife weg.

Mit Verlaub aber so macht man das nicht.

Die korrekte Vorgehensweise in solchen Fällen ist es die Animationsroutine regelmässig aus der Hauptprogrammschleife (aka Gameloop) aufzurufen. In dieser Routine prüft man dann zuerst ob der nächste Animationschrift fällig ist. Ist das nicht der Fall verlässt man die Rountine sofort wieder. Ansonsten führt man die Animationsänderung durch.

Irgendwo in einem Programm Routionen zu verstecken welche auf das vergehen von Zeit bzw: das Eintreffen von Ereignissen warten ist sehr schlecht. So etwas sollte man maximal auf der höchsten Ebene eines Programms/Threads machen und dann die Zeit auch nicht in einer schleife abwarten sondern durch entsprechenden Funktionen (wie das von ShadowXX aufgeführte Sleep) dem OS sagen das man die Rechenzeit jetzt gerade nicht braucht.

WhiteVelvet
2005-05-27, 12:20:25
So ist uns das aber vorgegeben. Ich erklärs mal genauer: Für ein Praktikum an der Uni sollen wir 4 Aufgaben programmieren. Damit wir das alles in einem Semester schaffen bekommen wir das Programmgrundgerüst vorgegeben. Nur einige eigene Methoden sollen wir selbst einfügen. Für diese Aufgabe benutzen wir Coin3D (OpenInventor). In der main Methode gibt es ein selectionCallback und ein animationCallback. Wenn ich etwas auf dem Spielfeld (Steck-Halma) anklicke, soll sich ein Roboterarm dorthin bewegen und den Stein aufheben und woanders ablegen. Also muss ich eh auf eine Benutzereingabe warten. Wenn die da ist, führe ich die Animation aus, und das wollte ich erst über den Timer machen, weil dieser im Grundgerüst genannt wird (der Timmer sollte die For-Schleife abbremsen, damit man überhaupt eine flüssige Bewegung sieht). Aber die Sleep() Funktion wäre wirklich einfacher, ich frage gerade nach, ob wir den Timer auch rauswerfen dürfen...

zeckensack
2005-05-27, 15:12:14
<...>
Wenn die da ist, führe ich die Animation aus, und das wollte ich erst über den Timer machen, weil dieser im Grundgerüst genannt wird (der Timmer sollte die For-Schleife abbremsen, damit man überhaupt eine flüssige Bewegung sieht).
<...>
Was kann der Timer denn sonst noch so?
Wenn er Zeit messen kann, dann bist du aus dem Schneider. Die korrekte Lösung ist, mittels des Timers herauszufinden wieviel Zeit seit dem letzten Animationsschritt vergangen ist, und die Animation dann nur diesem Zeitintervall entsprechend voranzutreiben. Kennen wir ja aus der Physik:
Delta(v)=a*Delta(t)
Delta(P)=v*Delta(t)

v:=Geschwindigkeit; a:=Beschleunigung; P:=Position;
(alles Vektoren, wenn's sein muss)

WhiteVelvet
2005-05-27, 16:43:00
Ich hab die Animation jetzt komplett in den Timer gezogen, ohne externe For-Schleife, es klappt jetzt so wie es sein sollte. Trotzdem Danke!