chatroom.cpp 3.17 KB
#include "chatroom.h"
#include "ui_chatroom.h"

Chatroom::Chatroom(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Chatroom)
{
    ui->setupUi(this);
    QList<int> chatSizes;
    QList<int> splitSizes;
    chatSizes.push_front(ui->chatText->height());
    chatSizes.push_front(100);
    splitSizes.push_front(ui->chatWindow->width());
    splitSizes.push_front(200);
    ui->chatSplitter->setSizes(chatSizes);
    ui->windowSplitter->setSizes(splitSizes);
    connected = false;
}

void killThread(thread_args *t_arg)
{
    if(t_arg != 0)
    {
        delete t_arg;
        t_arg = 0;
    }
    pthread_exit(NULL);
}

void *sendThread(void* args)
{
    string send;
    struct thread_args *t_arg = (struct thread_args*)args;
    while(connected)
    {
        cout << "> ";
        getline(cin,send);
        if(cin.eof())
        {
            send = "/exit";
        }
        try
        {
            *(t_arg->s) << send;
            if(send == "/disconnect" || send == "/exit")
            {
                break;
            }
        }
        catch(SocketException& e)
        {
            cout << e.description() << endl;
        }
    }
    killThread(t_arg);
}

void *recvThread(void* args)
{
    string recv;
    struct thread_args *t_arg = (struct thread_args*)args;
    while(true)
    {
        try
        {
            *(t_arg->s) >> recv;
        }
        catch(SocketException &e)
        {
            connected = false;
            cout << e.description() << endl;
            cout << "Connection lost. Press Enter to retry connection to chatroom. Press CTRL+C to exit." << endl;
            pthread_cond_signal(t_arg->condition);
            break;
        }
        if(recv == "DISC_OK")
        {
            cout << "Disconnecting" << endl;
            connected = false;
            pthread_cond_signal(t_arg->condition);
            break;
        }
        else if(recv == "EXIT_OK")
        {
            cout << "Exiting" << endl;
            connected = false;
            pthread_cond_signal(t_arg->condition);
            break;
        }
        else
        {
            cout << recv << endl;
        }
    }
    killThread(t_arg);
}

void Chatroom::start()
{
    Socket s;
    connected = false;
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,0);
    pthread_cond_t condition;
    pthread_cond_init(&condition,0);
    pthread_t recv, send;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_mutex_lock(&mutex);
    thread_args *sArgs = new thread_args;
    thread_args *rArgs = new thread_args;
    sArgs->mutex = &mutex;
    sArgs->condition = &condition;
    sArgs->s = &s;

    rArgs->mutex = &mutex;
    rArgs->condition = &condition;
    rArgs->s = &s;

    pthread_create(&send,&attr,sendThread,(void *)sArgs);
    pthread_create(&recv,&attr,recvThread,(void *)rArgs);

    while(connected)
    {
        pthread_cond_wait(&condition,&mutex);
    }
    pthread_mutex_unlock(&mutex);
    pthread_join(recv,NULL);
    pthread_join(send,NULL);
    s.Close();
    pthread_cond_destroy(&condition);
    pthread_mutex_destroy(&mutex);

    //LAUNCH LOGINSCREEN
}

Chatroom::~Chatroom()
{
    delete ui;
}