0

I am trying to develop a console application, where I will display the system date and time in real time (or as real as I can get). This is the easy part. The hard part is that I must also have the cursor available for the user to enter information through. I can't use NCurses in my application, nor any other library that it not included in vanilla GCC 4.4 (there goes boost! Noooo....)

This is my code so far:

The realtime class, where I am incorporating the solution given by Jeremy Friesner here pthreads in c++ inside classes

#ifndef _REALTIME_H_
#define _REALTIME_H_
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>    

class MyThreadClass
{
public:
   MyThreadClass() {/* empty */}
   virtual ~MyThreadClass() {/* empty */}

   /** Returns true if the thread was successfully started, false if there was an error starting the thread */
   bool startMainThread()
   {
      return (pthread_create(&_mainThread, NULL, mainRunnerFunc, this) == 0);
   }

   bool startDisplayThread()
   {
      return (pthread_create(&_displayThread, NULL, displayThreadFunc, this) == 0);
   }

   /** Will not return until the main thread has exited. */
   void waitForMainThreadToExit()
   {
      (void) pthread_join(_mainThread, NULL);
   }

   void waitForDisplayThreadToExit()
   {
      (void) pthread_join(_displayThread, NULL);
   }

protected:
   /** Implement this method in your subclass with the code you want your thread to run. */
   virtual void mainRunner() = 0;
   virtual void displayTime() = 0;

private:
   static void * mainRunnerFunc(void * This) {((MyThreadClass *)This)->mainRunner(); return NULL;}
   static void * displayThreadFunc(void * This) {((MyThreadClass *)This)->displayTime(); return NULL;}
   pthread_t _mainThread;
   pthread_t _displayThread;
};

class DynamicTime : public MyThreadClass
{
private:
    const string currentDate();
    void gotoxy(int,int);
    void displayTime();
    void mainRunner();
    pthread_mutex_t mutex1;
public:
//    pthread_mutex_t mutex1;
    DynamicTime();
    unsigned int lifeTime;
    unsigned int updateTime;
    void start();
    int Exit;
};

const string DynamicTime::currentDate()
{
    time_t now = time(0);
    struct tm tstruct;
    char buf[80];
    tstruct = *localtime(&now);
    strftime(buf,sizeof(buf),"%I:%M:%S %p, %d-%m-%y",&tstruct);
    return buf;
}

DynamicTime::DynamicTime()
{
    pthread_mutex_init(&(mutex1),NULL);
    lifeTime=-1; /* 100 seconds */
    updateTime = 1; /* 5 seconds interval */
    Exit=1;
}

void DynamicTime::gotoxy(int x,int y)
{
    /* go to location */
    printf("\033[%d;%df",y,x);
}

void DynamicTime::displayTime()
{
    pthread_mutex_lock(&mutex1);
    /* save the cursor location */
    printf("\033[s");
    gotoxy(75,30);
    cout << "Date : " << currentDate() << endl;
    /* restore the cursor location */
    printf("\033[u");
    pthread_mutex_unlock(&mutex1);
}

void DynamicTime::mainRunner()
{
    unsigned long iterate, iterate2;
    int iret1,iret2;
    if(lifeTime!=-1)
    {
        for(iterate=0;iterate<lifeTime*100000;iterate++)
        {
            if(iterate%(updateTime*50)==0)
            {
                iret2 = startDisplayThread();
                waitForDisplayThreadToExit();
            }
            for(iterate2=0;iterate2<100000;iterate2++);
        }
        std::cout << "Ending main thread..." << endl;
    }
    else
    {
        while(1&Exit) /* infinitely */
        {
            iret2 = startDisplayThread();
            waitForDisplayThreadToExit();
            for(iterate2=0;iterate2<100000;iterate2++);
        }
        std::cout << "Exiting Application.... " << endl;
    }
}

void DynamicTime::start()
{
    //system("clear");
    //cout << "Starting...."  << endl;
    if(startMainThread()==false)
    {
        std::cerr << "Coudln't start main Thread! " << endl;
    }
    /* call this function in the main program
     * else
    {
        waitForMainThreadToExit();
    }*/
}

/* Example
 * on how to use the program
 * int main()
{
    DynamicTime DT;
    DT.lifeTime = 100;
    DT.start();
    return 0;
}
*/
#endif

and my example program, where I am trying to read data from the user, while showing the time at the same time:

//#include <iostream>
#include "realtime2.h"   

int main()
{
    DynamicTime DT;
    string temp="abcd";
    DT.start();
    while(temp!="exit")
    {
        std::cout << "$> " ;
        std::cin >> temp;
    }
    DT.waitForMainThreadToExit();
    return 0;
}

This would be called a fully-functional program, if only I could get the user to enter data without interruption from the display thread. Any ideas as to how to get around this ? Or if I can't get around this, what would be the proper way to do so ?

Community
  • 1
  • 1

0 Answers0