Endlosschleife

CodeKrieger

Mitglied
Hallöchen,

folgende Situation: Ich emuliere eine Umgebung. Darauf wird eine Aufzeichnung (Mausklicks, Tastatureingaben) abgespielt. Nun soll es einen sogenannten UserInteraction Mode geben, bei dem der Benutzer die Wiedergabe pausieren darf. Dann werden Eingaben erlaubt. Der Eintritt in den User InteractionMode hängt von mehreren Begingungen ab, einerseits ein String innerhalb der Aufzeichnung, andererseits ein SyncPoint. Das ist eine Art Hash der Pixel in einem Bereich. Braucht euch aber nicht zu interessieren.

Nun ist es so, dass die Aufzeichnungen in einer Schleife durchlaufen werden. Wenn ich also an einer Stelle anhalten will, muss ich da eine weitere Schleife reinsetzen, die erst dann endet, sobald der Benutzer die Tastenkombi drückt, mit der er die Wiedergabe wiederaufnehmen kann.

Diese zweite Schleife implementiere ich gerade.
Java:
 private void UIModeLoop(){
        while(beginUIMode && _vc.getState() == 5){
            if(endUIMode)return;
            
        }
        
    }

Das Problem ist jetzt natürlich, dass die CPU-Auslastung auf 100% geht und die Tastenkombination garnicht verarbeitet werden kann. Auf dem emulierten System regt sich nichts mehr. :toll:

Gibt es irgendeine Möglichkeit das zu verhindern?

Hier nochmal der Ablauf schematisch
String UserInteractionBegin =>SyncPoint ok? >>falls ja >> erlaube Benutzereingaben, halte Verarbeitung der Aufzeichnungen an.
Wenn Tastenkombi X erhalten >> Fahre fort mit Aufzeichnungen >> SyncPoint wiederum ok? >> wenn ja >> String UserInteractionEnd >> Normal mit der Aufzeichnung fortfahren.

Ich hoffe es ist halbwegs klar geworden was ich will?!
 

Marco13

Top Contributor
Schau dir mal die verwendung der Methoden "wait" und "notifyAll" an, und ggf. den Kram in java.util.concurrent, wie etwa Locks und Conditions.
 

CodeKrieger

Mitglied
Hm, dazu brauche ich aber Threads? Ich glaube nicht, dass das Projekt für Threads geschrieben ist. Zumindest habe ich davon noch nichts gesehen.

Ich habe das Problem jetzt gelöst, indem ich aus der Schleife rausgehe und später wieder rein.

Es sind leider sehr viele Anpassungen nötig, um diese Zustände zu ermöglichen, aber anders gehts wohl nicht.
 

ARadauer

Top Contributor
oder sowas...

Java:
while(beginUIMode && _vc.getState() == 5){
Thread.sleep(250);
            if(endUIMode)return;
            
        }
 

CodeKrieger

Mitglied
Ich habe es nun folgendermaßen gelöst:

Bedingung der While-Schleife enthält den String, wo sie enden soll. Die While-Schleife wurde ausgegliedert aus der Methode actionPerformed(). Wenn ich nun fertig bin, mit dem UI-Mode, dann rufe ich die Methode mit der while-Schleife wieder auf und übergebe dabei quasi den aktuellen String (eine HashMap).

Das ganze funktioniert nun beim Start soweit, allerdings funkt beim Ende irgendwie die Mathode ActionPerformed dazwischen. Diese MEthode wirft mir Rätsel auf, sie wird in meinem Projekt nämlich nie aufgerufen. Nur die actionPerformed() anderer Klassen werden benutzt.

Hier einmal die wichtigsten Methoden

Java:
 public void actionPerformed(ActionEvent e) {
	if(e.getSource().equals(_timer))
        {
        long t = System.currentTimeMillis();

	if (_syncWait && _lastMouseMotion != null)
        {
	    if (t > _lastMouseMotionSent + 1000) {
		log("Trying to wiggle the mouse...");

		MouseEvent wiggle =
		    new MouseEvent(_vc,
				   _lastMouseMotion.getID(),
				   t,
				   _lastMouseMotion.getModifiers(),
				   _lastMouseMotion.getX() - 1,
				   _lastMouseMotion.getY(),
				   0, false,
				   _lastMouseMotion.getButton());
		_vc.processLocalMouseEvent(wiggle, true);
		_vc.processLocalMouseEvent(_lastMouseMotion, true);
		_lastMouseMotionSent = t;
	    }
	}

	if (_syncWait &&
	    (_syncWaitStarted > 0) &&
	    (t > _syncWaitStarted + SYNC_TIMEOUT_SEC * 1000))
	{
	    log("Timed out waiting for sync after " + (t - _syncWaitStarted) + " msec");
	    stop();
	}
        //main replayer loop
        Map<String, String> m = next();
        mainLoop(m);	
      }
    }
    private void mainLoop(Map<String, String> m){
        int mode = UIMode(m);
        while (!_syncWait && _syncWaitClear < System.currentTimeMillis() 
                && mode == 0) {	    
	    if (m == null) {
		stop();
		return;                
	    }
	    long ts = Long.parseLong(m.get("run-at"));
	    if (ts < System.currentTimeMillis()) {
		doEvent(m);
		_lastEventCompletion = System.currentTimeMillis();
		/* _lastEventCompletion = ts; */
	    } else {
		pushBack(m);
		return;
	    }
            m = next();
            mode = UIMode(m);
	}
        if (mode == 1){
            userInteractionMode(true, m);
        }
    }
    private int UIMode(Map<String, String> m){
        int mode = 0;
        if (m == null){
            return mode;
        }
        else if (m.get("type").equals("stage")){
            if (m.get("title").equals("UserInteractionBegin")){
                UIModeBeginStage = true;
                mode = 1; //UIMode starts
            }
            else if(m.get("title").equals("UserInteractionEnd") 
                    && UIModeEndShortcut && UIModeEndSync){
                mode = 4; //UIMode fends
            }
        }
        else if (m.get("type").equals("sync")){
            if (UIModeBeginStage){
                UIModeBeginSync = true;
                UIMode = true;
                mode = 2; //now, UImode is running
            }
            else if(UIModeEndShortcut){                
                mode = 3;
            }
            
            
        } 
        //System.out.println("Mode: " + mode);
        return mode;
        
    }

Vielleicht kann mir mal einer sagen wozu diese ActionPerformed() Methode gut ist. Das Problem beim Beenden des UI-Mode besteht darin, dass er immer eine Zeile weiter ist. Die Zeile mit UserInteractionEnd wird irgendwie übersprungen.
 

Ähnliche Java Themen

Neue Themen


Oben