Bool Variable mit nur einem Signal toggeln. [gelöst]



  • Hi 🙂

    Ich beschreib mal kurz was das Problem ist:
    Durch WM_KeyDown abfrage, wird eine bool variable genau solange true gesetzt wie ich Sie gedrückt halte. Läuft das Programm mit 60 Frames pro Sekunde, wird es sehr sehr unwahrscheinlich sein das die Taste nur einen Schleifen-durchlauf true ist. Das erschwert für mich die realisierung einer Toggle variable.

    Ich möchte durch Betätigen einer Taste eine bool variable abwechselnd von True zu false toggeln. Hier kurz eine kleine Tabelle damit es keine Missverständnisse gibt. 🙂

    Anzahl tastendrücke:               boolwert:
    (Unabhängig von Drückdauerdauer)
    1                                    true
    2                                    false
    3                                    true
    

    folgender Code geht... aber ich denke das es sehr unschön ist, oder hoffe das es eine bessere lösung gibt. (gerne auch ein Objekt)

    if(m_keystate[CL_TAB])
    	{
    		if(m_Automatic	== true && PData.swapped[0] == false)
    		{
    			PData.swapped[0]	= true;
    			PData.automatic		= false;
    		}
    		if(PData.automatic	== false && PData.swapped[0] == false)
    		{
    			PData.swapped[0]	= true;
    			PData.automatic		= true;
    		}
    	}
    	else
    	{
    		PData.swapped[0] = false;
    	}
    

    Gruß, Chris


  • Mod

    boolvariabe ^= 1;
    


  • was macht das?



  • cl90 schrieb:

    was macht das?

    Das toggelt boolvariable .



  • ^ ist das bitweise nicht. Es dreht die Bits um.

    Man kann auch das logische Nicht verwenden, dann so:

    flag = !flag;
    

    Jedoch muss rechts nochmal flag stehen, dadurch gewinnt die ^-Variante also an Reiz.



  • Eisflamme schrieb:

    ^ ist das bitweise nicht. Es dreht die Bits um.

    Nein, ^ ist das bitweise XOR (entweder-oder).

    x ^= y;
    

    toggelt in x alle Bits, die in y eins sind. Im Fall von

    x ^= 1;
    

    ist das das unterste, und da Bools entweder 0 oder 1 sind, reicht das (sofern vorher kein Schindluder getrieben wurde). Da

    x = !x;
    

    aber auch im Fall von Schindluder funktioniert, würde ich diese Variante vorziehen.



  • Eisflamme schrieb:

    flag = !flag;
    

    Jedoch muss rechts nochmal flag stehen, dadurch gewinnt die ^-Variante also an Reiz.

    Dafür ist die !flag Variante leichter zu überzuckern.
    Wodurch sie wiederum an Reiz gewinnt.



  • bool &toggle(bool &x) { x = !x; return x; }
    
    bool a = true;
    toggle(a);
    


  • hustbaer schrieb:

    Eisflamme schrieb:

    flag = !flag;
    

    Jedoch muss rechts nochmal flag stehen, dadurch gewinnt die ^-Variante also an Reiz.

    Dafür ist die !flag Variante leichter zu überzuckern.
    Wodurch sie wiederum an Reiz gewinnt.

    Ich würde die ! Variante auch auf jeden Fall bevorzugen, da die ^ Variante, so harmlos sie auch aussehen mag, auf relativ arkanen Mechanismen beruht...



  • Vielen dank für die vielen Antworten 🙂
    Eure lösungen gefallen mir sehr gut, ich werde mir bei eurer syntax was abschauen 🙂

    theliquidwave schrieb:

    bool &toggle(bool &x) { x = !x; return x; }
    
    bool a = true;
    toggle(a);
    

    das ist ja aber genau das problem das ist habe^^
    das toggelt die variable jetzt hervorragend. aber leider ruft 1! tastendruck ca. 10-20 schleifenaufrufe auf.

    ich drücke die taste:
    im ersten schleifen durchlauf toggelt die variable - im nächsten durchlauf wieder zurück. und so weiter. bis ich die taste loslasse. also ist es glückssache ob die variable genau da stehen bleibt wo ich sie haben möchte.

    nochmal ein beispiel:

    Taste gedrückt für 200ms. bei 50Frames per second
    zeit:      status:
    0          true
    20ms       false
    40ms       true
    60ms       false
    80ms       true
    100ms      false
    120ms      true
    140ms      false
    160ms      true
    180ms      false
    200ms      true
    

    dafür hatte ich eine weitere swapped variable eingefügt. die false gesetzt wird sobald die entsprechende Taste oben (false) ist. wird die taste nun gedrückt, wird die variable getoggelt, und die swapped variable wird true gesetzt, was das toggeln verhindert.
    aber je mehr ich darüber nachdenke... ich glaube anders scheint es nicht zu gehen. ich bastel da noch ein bisschen herrum und wende eure syntax an. so wie ihr das geschrieben habt spaare ich mich ein paar zeilen code 🙂



  • Das es sich um einen bool handelt, finde ich die Variante mit dem logischen NICHT passender. XOR oder bit-weises NICHT dienen zur Bitmanipulation, sind also eher was für Masken oder hardwarenahe Programmierung.

    bool toggle(bool v)
    {
        return !v;
    }
    


  • @TE:

    Benutze zwei bool Variablen. Die eine nutzt du wie bisher und mit der anderen merkst du dir, ob im letzten Frame das keypress Event ausgelöst wurde.

    Alternativ anderes Event nehmen.



  • gut dann scheint es wohl wirklich nichts anderes zu geben erstmal.
    das ist dann meine hübschere lösung für das problem:

    void	Control :: m_Toggle(bool key, bool* variable)
    {
    	if(key)
    	{
    		if(m_swapped[0] == false)
    		{
    			*variable	 = !(*variable);
    			m_swapped[0] = true;
    		}
    	}
    	else
    	{
    		m_swapped[0] = false;
    	}
    }
    

    ich denke das passt schon so
    danke euch! 🙂



  • void Control::m_Toggle(bool key, bool* variable)
    {
        if (m_lastKeyState[0] == false && key == true) // steigende Flanke?
            *variable = !(*variable);
    
        m_lastKeyState[0] = key; // letzten Zustand merken
    }
    

Anmelden zum Antworten