[gelöst] Schleife soll im Hintergrund arbeiten



  • Guten Abend Leute,

    ich habe angefangen das Buch (C++ für IT Berufe mit App Entwicklung) von Europa Lehrmittel zu lesen und habe die ersten Seiten gelesen (Basics wie Schleifen etc.)

    Nun habe ich angefangen ein Programm zu schreiben. Mein Programm ist eine Konsolenanwendung, und mein Problem ist folgendes :

    Ich möchte, dass eine Forschleife im Hintergrund hochzählt und z.B das Geld erhöht. Aber während diese Forschleife läuft soll man auch noch andere Dinge machen können.

    Ich hoffe ich habe mich verständlich genug ausgedrückt 😛
    Hat jemand eine Idee für die Lösung des Problems?
    Über eine Antwort würde ich mich riesig freuen!



  • http://en.cppreference.com/w/cpp/thread

    Das ist allerdings nicht gerade anfängerfreundlich, Daten zwischen Threads austauschen kann tricky sein.



  • @Nirndor
    Ja, du hast dich klar ausgedrückt.
    Das Problem ist nur dass dir das Problem nicht klar ist.
    Mein Tip: lös es anders.

    Dass du dir wünscht irgend etwas solle einfach so im Hintergrund "das Geld hochzählen" ist ein recht sicherer Hinweis darauf dass du nix zum Thema Threading und Synchronisierung weisst. Und da es beim Arbeiten mit Threads sehr wichtig ist das grundlegende Problem dabei verstanden zu haben und die Regeln zu kennen wie man Dinge sicher machen kann, ...



  • Hallo cooky451,
    vielen Dank für die schnelle Antwort. Ich werde mich dort mal durchlesen.

    Hallo hustbaer,
    auch an Dich vielen Dank für deine schnelle Antwort!
    Ich betone einfach nochmal, dass ich noch am Anfang stehe :p
    Die eigentliche Schleife wo das was ich möchte abläuft habe ich ja bereits.
    Jetzt muss man sich das Ganze so vorstellen :
    Man kommt zum besagten Punkt und gibt z.B eine Anzahl an Bäume an die gefällt werden sollen. z.B 10 -> Dort zählt die Forschleife dann bis 10 und addiert das Holz zum Lager des Anwenders. Momentan funktioniert das auch, nur, dass man währenddessen nichts anderes machen kann.
    Du hast Recht zum Theme Threading und Synchronisierung habe ich bisher nichts gelesen.

    "Mein Tip : lös es anders" - Hättest du denn eine andere Lösung dafür?

    MfG
    Nirndor

    Und nochmal vielen vielen Dank für eure Antworten - sehr sehr aufmerksam



  • Eine andere Lösung für dein Problem wäre jedes mal wenn der Wert für "wie viel Holz ist im Lager" gebraucht wird die vergangene Zeit abzufragen und den Wert entsprechend auszurechnen. (Ich vermute mal dass du willst dass irgendwie ein Holz pro Minute gefällt wird oder so, und man da nicht 10 Minuten warten muss?)

    http://en.cppreference.com/w/cpp/chrono/steady_clock



  • Hallo cooky451,

    nochmal Danke für die Antwort. So ähnlich hatte ich es geplant.
    Ich danke dir



  • Die meisten Spiele verwenden einen Frame-Loop der permanent läuft.
    D.h. da gibt es irgendwo ein (schematisch)

    while (!someExitCondition)
    {
        Update();
        RenderFrame();
    }
    

    Im Update-Teil tust du dann den Game-State updaten. z.B. könnte es da Code geben der eine Liste von "Update-Listenern" durchgeht, und diese darüber informiert dass ein neues Frame vorbereitet wird.

    So ein Update-Listener* kann dann abfragen wie die aktuelle Zeit ist**, anhand der Zeit entscheiden ob schon wieder ein neuer Baum gefällt wurde, und dann halt den Game-State entsprechend updaten (Geld inkrementieren oder was auch immer).

    Vielleicht hat das Game auch eine eigene Timer-Verwaltung. Wenn es viele Dinge gibt die periodisch gemacht werden müssen, aber eben nicht für jedes Frame, dann kann sich das auszahlen (=bessere Performance). Weil man dann nicht immer an allen Stellen selbst gucken muss "ob es schon Zeit ist", sondern der registrierte Timer einfach erst aufgerufen wird wenn es eben Zeit ist.

    Das ganze setzt natürlich vorauss dass man nirgends "blockierende" Funktionen verwendet um z.B. Input zu lesen. Also im Falle von Text-basierten Spielen kein std::cin >> blubb oder ähnliches. Das muss man sich dann nachbilden. z.B. mittels _kbhit und _getch.

    *: Für den Anfang musst du natürlich nicht gleich das Listener-Pattern implementieren wenn dir das zu viel auf einmal ist. Du kannst deine Update Funktion ja ersmal einfach so implementieren:

    void Update()
    {
        ProcessInput();
        Lumber();
        // ...
    }
    
    void Lumber()
    {
        if (lumbering)
        {
            if (isNextTreeChippedCompletely)
            {
                // ...
            }
        }
    }
    

    **: Idealerweise holt man sich die Zeit nur 1x im "Frame-Loop" und gibt die dann bei jedem Callback mit.



  • ps:
    Wenn du keine "live" Anzeige auf dem Schirm brauchst, und davon ausgehst dass du sie auch später nicht brauchen wirst, dann ist die Variante von cooky vermutlich besser, da vermutlich einfacher zu implementieren.

    Und... wie sieht denn die Hauptschleife deines Spiels aktuell aus?



  • Wow hustbaer,

    Danke für die ganze Mühe die du dir gemacht hast. So ausführlich hätte ich mir eine Antwort niemals erträumen lassen. Umsomehr macht es mich traurig, dass ich sie wohl erstmal nicht verwenden werde.
    Ich muss nochmal sagen, dass ich echt noch ein blutiger Anfänger bin und erstmal nur die Basics lerne und versuche mit einem "mini-mini-mini" Spiel mir spaßiger zu gestalten.

    Wie die Hauptschleife meines *hust* Spiels *hust* aussieht traue ich mich jetzt nichtmehr hier zu schreiben haha :p

    Wie gesagt ich bedanke mich nochmal recht herzlich bei euch für die informativen Antworten. Ich werde die Version von cooky jetzt erstmal versuchen zu programmieren. Eventuell werde ich mich dann nochmal melden wenn ichs geschaft/nicht geschafft habe 😃

    Danke Danke Danke 😉


Anmelden zum Antworten