0

I am a beginner. Actually, I wrote a code for the washing machine to operate. I have different processes. But I am having a simple issue with my code. I want to pause and resume while processes are ongoing with user input. I meant like if I press Q it will pause and if I press ENTER it will continue but if I don't press anything it will continue its program. I tried with cin.get() but it didn't work. So I tried to make a function {in the code its char pause()} that can be called in a certain process and the user will input Q to pause and "ENTER" / "RETURN" to resume the program but when I use this function the process stops till I don't press q and then ENTER. That's why I disabled that function. Please let me know if you can help. The code is shown below. Thanks in advance.

class WMachine {
  public :
      int waterlevel;
      char q;
      bool soak (int time) ;
      bool wash (int time);
      bool rinse (int time);
      bool spin (int time);
      void WL(int WL);
      // char pause(char in);
      void sleep(float seconds);
      WMachine(){};

};
// char WMachine :: pause(char in){
//     while(1){
//     cin>>in;
//     if(in == 'Q' || in == 'q') break;
// }}

void WMachine :: WL(int WL){
    if(WL==4){
        cout<<"\nWater Level is Now at High..."<<endl;
    }
    else if(WL == 3){
        cout<<"\nWater Level is Now at Middle..."<<endl;
    }
    else if(WL==2){
        cout<<"\nWater Level is Now at Low..."<<endl;
    }
    else if(WL==1){
        cout<<"\nWater Level is Now at Little..."<<endl;
    }
}
bool WMachine :: soak(int time){
    int T = time;
    if (true){

        sleep(4.0);
        cout<<"\nSoaking...."<<endl;
        // pause(q);
        sleep(3.5);
        cout<<"\nTime Remaining.. "<<T<<" minutes"<<endl;
        // pause(q);
        sleep(3.0);

    }
    else {return false;};
}
bool WMachine :: wash(int time){
    int T = time;
    if (true){

        sleep(3.0);
        cout<<"\nWashing...."<<endl;
        // pause(q);
        sleep(2.5);
        cout<<"\nTime Remaining.. "<<T<<" minutes"<<endl;
        // pause(q);
        sleep(2.0);

    }
    else return false;
}
bool WMachine :: rinse(int time){

    int T = time;
    if (true){
        sleep(2.0);
        cout<<"\nRinsing...."<<endl;
        // pause(q);
        sleep(1.5);
        cout<<"\nTime Remaining.. "<<T<<" minutes"<<endl;
        // pause(q);
        sleep(1.0);

    }
    else return false;
}
bool WMachine :: spin(int time){
    int T = time;
    if (true){


        sleep(2.5);
        cout<<"\nSpining..."<<endl;
        // pause(q);
        sleep(1.5);
        cout<<"\nTime Remaining.. "<<T<<" minutes"<<endl;
        // pause(q);
        sleep(1.0);


    }
    else return false;
}

void WMachine :: sleep (float seconds){

   clock_t startClock = clock();
   float secondsAhead = seconds * CLOCKS_PER_SEC;
   while(clock() < startClock+secondsAhead);
   return;

}

class ProgWM : public WMachine {
  public :
        ProgWM(){};
        void setProgMode();
        bool standard(string x);
        bool strong(string y);
        bool fast(string w);
        bool soft(string z);

};
bool ProgWM :: standard(string x){
    if (x == "sd") return true;
    else {return false;}
}
bool ProgWM :: strong(string y){
    if (y == "sg") return true;
    else {return false;}
}
bool ProgWM :: fast(string w){
    if (w == "fa") return true;
    else {return false;}
}
bool ProgWM :: soft(string z){
    if (z == "so") return true;
    else {return false;}
}


void ProgWM :: setProgMode(){
    string p;
    string choice;
    int no;
    cout<<"      \nChoose Mode :"<<endl;
    cout<<"----------------------"<<endl;
    cout<<"===> Default Mode (Press d) "<<endl;
    cout<<"===> Manual Mode  (Press m) "<<endl;
    cin>>choice;
    if(choice=="d"){
        cout<<"Choose (Type) Your Program :"<<endl;
        cout<<". Standard (sd)"<<endl;
        cout<<". Strong (sg)"<<endl;
        cout<<". Fast (fa)"<<endl;
        cout<<". Soft (so)"<<endl;
        cin>>p;
    if(standard(p)){
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(1);
        spin(4);
        cout<<"\n\nWASHING IS DONE.."<<endl;
        cout<<"\nTHANK YOU !"<<endl;

    }
    else if(strong(p)){
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(1);
        spin(1);
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(1);
        spin(1);
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(1);
        spin(4);
        cout<<"\n\nWASHING IS DONE.."<<endl;
        cout<<"\nTHANK YOU !"<<endl;

    }
    else if(fast(p)){
        WL(4);
        soak(3);
        WL(3);
        wash(3);
        WL(2);
        rinse(3);
        WL(4);
        soak(2);
        WL(3);
        wash(2);
        WL(2);
        rinse(2);
        WL(1);
        spin(2);
        cout<<"\n\nWASHING IS DONE.."<<endl;
        cout<<"\nTHANK YOU !"<<endl;

    }
    else if(soft(p)){
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        WL(4);
        soak(7);
        WL(3);
        wash(7);
        WL(2);
        rinse(4);
        cout<<"\n\nWASHING IS DONE.."<<endl;
        cout<<"\nTHANK YOU !"<<endl;
    }

    else{
        cout<<"Invalid Input !"<<endl;
    };
}
else if(choice=="m"){

    cout<<"Select Process :"<<endl;
    cout<<". Soak   (1)"<<endl;
    cout<<". Wash   (2)"<<endl;
    cout<<". Rinse  (3)"<<endl;
    cout<<". Spin   (4)"<<endl;
    cin>>no;
    if(no==1) {

        cout<<"Select Water Level :"<<endl;
        cout<<". High   (4)"<<endl;
        cout<<". Middle (3)"<<endl;
        cout<<". Low    (2)"<<endl;
        cout<<". Little (1)"<<endl;
        cin>>waterlevel;
        WL(waterlevel);
        soak(7);
        cout<<"\n\nWASHING IS DONE.."<<endl;
        cout<<"\nTHANK YOU !"<<endl;}
    else if (no == 2) {cout<<"Select Water Level :"<<endl;
    cout<<". High   (4)"<<endl;
    cout<<". Middle (3)"<<endl;
    cout<<". Low    (2)"<<endl;
    cout<<". Little (1)"<<endl;
    cin>>waterlevel;
    WL(waterlevel);
    wash(7);
    cout<<"\n\nWASHING IS DONE.."<<endl;
    cout<<"\nTHANK YOU !"<<endl;}
    else if (no == 3) {cout<<"Select Water Level :"<<endl;
    cout<<". High   (4)"<<endl;
    cout<<". Middle (3)"<<endl;
    cout<<". Low    (2)"<<endl;
    cout<<". Little (1)"<<endl;
    cin>>waterlevel;
    WL(waterlevel);
    rinse(5);
    cout<<"\n\nWASHING IS DONE.."<<endl;
    cout<<"\nTHANK YOU !"<<endl;}
    else if (no == 4) {cout<<"Select Water Level :"<<endl;
    cout<<". High   (4)"<<endl;
    cout<<". Middle (3)"<<endl;
    cout<<". Low    (2)"<<endl;
    cout<<". Little (1)"<<endl;
    cin>>waterlevel;
    WL(waterlevel);
    spin(4);
    cout<<"\n\nWASHING IS DONE.."<<endl;
    cout<<"\nTHANK YOU !"<<endl;}
    else {cout<<"Invalid !"<<endl;};

}

};

int main(){
    string power;
    ProgWM prog;
    cout<<"                 WELCOME                "<<endl;
    cout<<"----------------------------------------"<<endl;
    cout<<"\nSwitch Off / On (type on/off) : "<<endl;
    cin>>power;
    cout<<"Press Q/q After Every Process To Pause and Press ENTER To Start"<<endl;
    if(power == "On" || power == "on"){
        prog.setProgMode();
    }

    else if( power== "off" || power == "Off"){
        cout<<"\nSee You On Your Next Washing !"<<endl;

    }
    else{
        cout<<"Invalid Input !"<<endl;
    };


return 0;
  }
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Are you looking for a [debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems)? – πάντα ῥεῖ Oct 01 '20 at 18:43
  • From what I read, I assume that you are willing to have stoppable concurrent tasks. Is that correct? – g_bor Oct 01 '20 at 18:45
  • yes. I need to pause on a current task with input and resume with input and if I don't give anything it will continue as it was. – Sheikh Araf Oct 01 '20 at 18:51
  • Like what Actual Washing Machine Does with its PAUSE/ START button. I tried to use a function but it didn't work out :( – Sheikh Araf Oct 01 '20 at 18:55

2 Answers2

1

I somewhat misread your question. Your problem is actually how to not pause execution while waiting for keyboard input unless in a specific state.

There is a POSIX function names fctnl (file control) for, among many other things, making read operations on a file (stdin, stdout, and stderr are files in this sense as well) blocking or nonblocking. The file number for stdin is zero on all systems I've ever encountered but there's also a constant named STDIN_FILENO, so let's use that.

Setting stdin to non-blocking:

flags = fcntl(STDIN_FILENO, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(STDIN_FILENO, F_SETFL, flags);

Setting stdin to blocking:

flags = fcntl(STDIN_FILENO, F_GETFL, 0);
flags &= ~O_NONBLOCK;
fcntl(STDIN_FILENO, F_SETFL, flags);

For reading keyboard input, then use the POSIX function read.

In non-blocking mode, it will return an error indication (-1) and errno will be set to EAGAIN or EWOULDBLOCK.

The higher-level C++ I/O APIs will interpret the error as an actual error, so they maybe should not be used for input from a non-blocking file.

My original answer:

For pausing execution, there is a POSIX function called select.

It pauses the process (or the current thread) until there is input from any of the files it is told to listen to. No CPU cycles during the wait.

A similar function exists in the Win32 API, called WaitForMultipleObjects.

yeoman
  • 1,671
  • 12
  • 15
  • Can you explain with a little bit example so that I can use it in my certain process? – Sheikh Araf Oct 01 '20 at 18:59
  • I would have to write several pages of documentation and example code for that. I'll instead google a reasonable link for you. – yeoman Oct 01 '20 at 19:03
  • https://man7.org/linux/man-pages/man2/select.2.html – yeoman Oct 01 '20 at 19:04
  • The tutorial looks fine, the man page is the usual way to go to for details. It's linux man page but it's a Posix function, so there shouldn't be too many differences – yeoman Oct 01 '20 at 19:05
0

This can be achieved with multi threading. Have one thread doing processing in the background, and another thread waiting for user input.

The waiting thread could set a condition variable signifying that pausing is desired while the processing thread should periodically wait on this condition. The more often the condition is checked, the more responsive the interface will be.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Busy waiting with threads instead of a slim async process that behaves well is not a great approach. – yeoman Oct 01 '20 at 19:14
  • @yeoman Depends on use case. Washing machines don't need to be responsive, are rarely put on pause for long periods of time, and typically don't need to contend for resources of other processes. – eerorika Oct 01 '20 at 19:17
  • @yeoman But fair enough, I changed the answer to alternative which doesn't need busy waiting. – eerorika Oct 01 '20 at 19:43