mainloop fuer Konsolenanwendung zickt
-
Servus,
ich verstehe gerade nicht, wieso ich nicht wieder in meinem main-loop zurückkomme?
Hm, komisch ich habe versucht mein Vorgehen in Python auf C++ zu übertragen aber das klappt so nicht, kann es sein, dass cin was macht, was ich nicht sehe?Hie ein kleines Beispiel, ich will eine Konsolen-Nutzeroberfläche bauen, ein Event ist eine Eingabe.
Geloescht, da es nicht mehr aktuell war, und das zweite Code-Beispiel von mir das Problem besser aufs Wesentliche beschränkt.
-
Ich würde das ganz anders angehen. Mach eine allgemeine Klasse, die Konsolen-Befehle bearbeiten kann und bei der du Handler für Befehle registrieren kannst.
In etwa so:class console { std::map<std::string, std::unique_ptr<signal_type>> signals; bool run; public: typedef void callback_signature(console&, const std::vector<std::string>&); typedef boost::signals::signal<callback_signature> signal_type; typedef std::function<callback_signature> callback_type; typedef boost::signals::connection connection_type; console() : run(true) {} connection_type register_callback(const std::string& cmd, callback_type cb) { // füge callback ein } void run_loop() { while(run) { std::string line; std::getline(std::cin, line); std::vector<std::string> args; std::ostringstream oss(std::move(line)); while(oss >> line) args.push_back(std::move(line)); auto iter = signals.find(args[0]); if(iter != signals.end) (*iter->second)(*this, args); } } void stop() { run = false; } };
-
Okay, erstmal Danke, über deine Herangehensweise muss ich mal nachdenken, das scheint in jedem Fall geschickter zu sein. Dennoch würde ich gern wissen warum ich nicht aus meinem Hauptloop zurückkomme Ich habe meinen Code mal korrigiert und etwas vereinfacht, damit das Problem schneller erkennbar wird.
class Tui { public: bool run; Tui() {} int start(); int stop(); // Eventprototypen int doActionOne(); }; // Events inline int Tui::doActionOne() { // Konfigurieren std::cout << "* -> Eingabe des ActionOne, 'RETURN' zum Absenden; 'q' zum Beenden.\n"; std::cout << "* Eingabe [String]:\n"; std::string stringToCompute = ""; std::cin >> stringToCompute; // Weiterleiten if ( stringToCompute == "q" ) { std::cout << " q in ActionOne erkannt\n"; stop(); } else { // Logik Griff ins Model double res = 0.45; // Antwort std::cout << "* [Eingabe: "; std::cout << stringToCompute; std::cout << "]: \n"; std::cout << "* "; std::cout << res; std::cout << "\n"; std::cout << "* Zurueck mit beliebiger Taste.\n"; std::string event; std::cin >> event; std::cout << "Eventeingabe:" << event << "\n"; } // korrektes Ende std::cout << "doActionOne() - korrekt gelaufen.\n"; return 0; } inline int Tui::start() { run = true; while ( run ) { std::cout << "\n"; std::cout << "******************** INFO [Konsolen-Interface] ********************************\n"; std::cout << "* ............................................................................ \n"; std::cout << "*** Hauptmenue *** ........................................................... \n"; std::cout << "* q - Anwendung beenden\n"; std::cout << "* A0 - ActionOne ...\n"; std::cout << "*** .......................................................................... \n"; std::cout << "* Eingabe: \n"; std::string event = ""; std::cin >> event; std::cout << "Eventeingabe: " << event << "\n"; if (event == "q") { std::cout << "mainloop q\n"; stop(); } else if (event == "A0") { std::cout << "Event start A0 start\n"; doActionOne(); std::cout << "Event start A0 ende - nichts, Hauptmenue\n"; } else { std::cout << "Event nicht erkannt - nichts, Hauptmenue\n"; } } std::cout << "* ... raus aus while ... beende Anwendung\n"; return 0; } inline int Tui::stop(){ this->run = false; }
-
Das gibts doch nicht ... habe nun etwas gelesen und es sieht mir so aus, dass das angeblich komplexer als erwartet ist, gar plattformabhängig. Ich dachte erst, dass ist ein absolutes Anfängerproblem das jeder schon x-mal gelöst hat. Laufen soll das Tui auf Linux, falls das für die Lösung eine Rolle spielt.
-
Könntest du etwas mehr Informationen liefern? Was passiert? Was erwartest du? Wo erwartest du was, was nicht passiert ist? Schon mal mit dem Debugger durchgegangen?
Die wenigsten haben wohl Lust, den Code durchzugehen und selber auf den möglichen Fehler zu treffen, den du irgendwo siehst.
Wo ist das Problem? Ausführlich bitte!
Siehe auch Punkte 6, 8 und 9:
http://www.c-plusplus.net/forum/200753Grüssli
-
Sodala,
in der main()-Funktion habe ich diesen Aufruf:
Tui tui; int rcode = tui.start(); // komplett rausDer Code aus meinem Beispiel direkt oben drüber ist denke ich lauffähig und man kann es gut nachvollziehen, das Code-Beispiel im Anfangspost ist für die Katz und ich werde es rauslöschen, damit keiner Zeit vertrödelt, dies durchzusehen.
Was passiert? Ich will, dass das Programm nach der Aufforderung 'Weiter mit beliebigem Tastendruck wieder im Hauptloop der Tui-Klasse landet, also in der Methode start() - das passiert aber nicht, meine Shell sieht so aus, dass nicht die Hauptmenueansicht erscheint, sondern einfach der Cursor eine Zeile weiter nach unten springt. Es sieht so aus, als ob die Rücksprungadresse den Loop nicht mehr findet. Das führt zu meinen Verdacht, dass der Loop der Methode start() nicht 'wartet'.
-
Jay1980 schrieb:
Es sieht so aus, als ob die Rücksprungadresse den Loop nicht mehr findet. Das führt zu meinen Verdacht, dass der Loop der Methode start() nicht 'wartet'.
Nach "* Zurueck mit beliebiger Taste.\n" wird ja noch einmal cin >> event aufgerufen, da musst du irgendwas eingeben.
(Also Text, führende Spaces werden ignoriert!)
-
Das war wieder so etwas ... ich hack da rum und hau mir Blasen durchs Drücken auf die Return-Taste .... aber die nimmt cin nicht ... oh mei, manchmal ...
Danke ... so nun kann es endlich weitergehen!