eventHandler thread terminate

This commit is contained in:
Ian Gebbie 2020-01-19 18:55:14 +02:00
parent 3a6adce628
commit 85ab7a3ace
18 changed files with 301 additions and 164 deletions

View file

@ -78,8 +78,9 @@ SOURCES += \
cntfilesystemmodel.cpp \
abstractdata.cpp \
matrixdata.cpp \
eventthread.cpp \
options.cpp
options.cpp \
eventtimer.cpp \
eventthread.cpp
HEADERS += \
mainwindow.h \
@ -119,9 +120,11 @@ HEADERS += \
cntfilesystemmodel.h \
abstractdata.h \
matrixdata.h \
eventthread.h \
options.h \
hp_typedef.h
hp_typedef.h \
eventtimer.h \
eventthread.h \
eventthread.h
FORMS += \
mainwindow.ui \

View file

@ -3,23 +3,11 @@
#include <QString>
#include <QByteArray>
#include "hp_typedef.h"
#include "hpusb.h"
#include "matrixdata.h"
enum hp_DataType{
HP_MAIN=0,
HP_APP=1,
HP_CAS=2,
HP_COMPLEX=3,
HP_LIST=4,
HP_MATRIX=5,
HP_NOTE=6,
HP_PROG=7,
HP_REAL=8,
HP_VAR=9,
HP_SCREEN=10,
HP_SETTINGS=10
};
struct m_Size {
int row;

View file

@ -78,13 +78,13 @@ QMimeData* contentFileSystemModel::mimeData(const QModelIndexList &indexes) cons
case HP_PROG: {
qDebug()<<"HP_PROG Found";
mimeDataPtr->setText(info.baseName());
mimeDataPtr->setData("application/x-programme",mydata);
mimeDataPtr->setData(mimetypes[HP_PROG][1],mydata);
break;
}
case HP_APP: {
qDebug()<<"HP_APP Found";
mimeDataPtr->setText(info.baseName());
mimeDataPtr->setData("application/x-application",mydata);
mimeDataPtr->setData(mimetypes[HP_APP][1],mydata);
break;
}
case HP_MATRIX: {

View file

@ -1,52 +1,25 @@
#include "eventthread.h"
#include "mainwindow.h"
#include <mainwindow.h>
#include <QDebug>
EventThread::EventThread(MainWindow * parent)
EventThread::EventThread(MainWindow * parent):QThread (parent)
{
main=parent;
if (main)
hpapi=main->getAPI();
if (hpapi==nullptr)
qDebug()<<"hpusb not started";
}
void EventThread::timerAction()
{
QMutexLocker locker(&mutex);
void EventThread::run() {
// qDebug()<<"In Eventhandler";
// QThread::msleep(1);
if(hpapi) {
hpapi->eventHandler();
}
qDebug()<<"Event run";
// emit startTimer();
hpapi->eventHandler();
qDebug()<<"Event end";
//exec();
}
void EventThread::start() {
timer = new QTimer(this);
timer->setInterval(100);
// timer->callOnTimeout(SLOT(timerEvent()),Qt::AutoConnection);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(timerAction()),Qt::AutoConnection);
timer->connect(this, SIGNAL(stop()), this, SLOT(stopTimer()));
timer->start();
qDebug()<<"EventThread::started Timer";
}
void EventThread::exit() {
emit stop();
stop();
}
void EventThread::stopTimer() {
qDebug()<<"EventThread::stop Timer";
timer->stop();
emit stopped();
}
EventThread::~EventThread()
{
stopTimer();
if (timer!=nullptr) {
delete timer;
timer=nullptr;
}
qDebug()<<"delete eventThread";
}

View file

@ -1,33 +1,27 @@
#ifndef EVENTTHREAD_H
#define EVENTTHREAD_H
#include <QThread>
#include <QTimer>
#include <QMutex>
#include "hpusb.h"
#include <hpusb.h>
class MainWindow;
class EventThread : public QObject
class EventThread : public QThread
{
Q_OBJECT
private:
MainWindow * main;
hpusb * hpapi;
QTimer * timer=nullptr;
hpusb * hpapi=nullptr;
mutable QMutex mutex;
public:
EventThread(MainWindow * parent);
~EventThread();
public slots:
void timerAction();
void start();
void exit();
void stopTimer();
void run() override;
signals:
void stop();
void stopped();
void startTimer();
};
#endif // EVENTTHREAD_H

65
eventtimer.cpp Normal file
View file

@ -0,0 +1,65 @@
#include "eventtimer.h"
#include "mainwindow.h"
EventTimer::EventTimer(MainWindow * main):QObject()
{
if (main)
hpapi=main->getAPI();
if (hpapi==nullptr)
qDebug()<<"hpusb not started";
}
void EventTimer::timerAction()
{
QMutexLocker locker(&mutex);
// qDebug()<<"In Eventhandler";
// QThread::msleep(1);
if(hpapi!=nullptr) {
hpapi->eventHandler();
}
emit tick();
}
void EventTimer::start() {
timer = new QTimer(this);
timer->setInterval(100);
// timer->callOnTimeout(SLOT(timerEvent()),Qt::AutoConnection);
timer->connect(timer, SIGNAL(timeout()), this, SLOT(timerAction()));
// timer->connect(timer, SIGNAL(timeout()), hpapi, SLOT(eventHandler()),Qt::DirectConnection);
// timer->connect(this, SIGNAL(tick()), this, SLOT(tickEvent()),Qt::AutoConnection);
timer->connect(this, SIGNAL(stop()), this, SLOT(stopTimer()));
timer->start();
qDebug()<<"EventTimer::started Timer";
}
void EventTimer::exit() {
emit stop();
stop();
}
void EventTimer::stopTimer() {
qDebug()<<"EventTimer::stop Timer";
timer->stop();
emit stopped();
}
void EventTimer::tickEvent() {
qDebug()<<"EventTimer::tickEvent";
}
EventTimer::~EventTimer()
{
stopTimer();
if (timer!=nullptr) {
delete timer;
timer=nullptr;
}
qDebug()<<"delete EventTimer";
}

36
eventtimer.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef EVENTTIMER_H
#define EVENTTIMER_H
#include <QThread>
#include <QTimer>
#include <QMutex>
#include "hpusb.h"
class MainWindow;
class EventTimer : public QObject
{
Q_OBJECT
private:
MainWindow * main;
hpusb * hpapi=nullptr;
QTimer * timer=nullptr;
mutable QMutex mutex;
public:
EventTimer(MainWindow * main);
~EventTimer();
public slots:
void timerAction();
void start();
void exit();
void stopTimer();
void tickEvent();
signals:
void stop();
void stopped();
void tick();
};
#endif // EVENTTHREAD_H

View file

@ -39,6 +39,6 @@ void hp_mdiVariableEdit::show() {
hp_mdiVariableEdit::~hp_mdiVariableEdit() {
// qDebug()<<"Entering ~hpmdiVariableEdit()";
qDebug()<<"Entering ~hpmdiVariableEdit()";
}

View file

@ -27,6 +27,6 @@ void hp_MdiWindow::show() {
hp_MdiWindow::~hp_MdiWindow() {
// qDebug()<<"Entering ~hpmdiWindow()";
qDebug()<<"Entering ~hpmdiWindow()";
}

View file

@ -3,10 +3,46 @@
#include <QString>
#include <QPixmap>
#include "abstractdata.h"
//#include "abstractdata.h"
#define FUNC_NUM 9
#define FUNC_NUM 10
typedef enum {
// 5 is triggered periodically by the official connectivity kit. It returns something with a PNG header, but much smaller.
CALC_SCREENSHOT_FORMAT_FIRST = 8,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x16 = 8,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x4 = 9,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x16 = 10,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x4 = 11,
CALC_SCREENSHOT_FORMAT_LAST ///< Keep this one last
} hp_screenshot_format;
enum hp_DataType{
HP_MAIN=0,
HP_APP=1,
HP_CAS=2,
HP_REAL=3,
HP_COMPLEX=4,
HP_LIST=5,
HP_MATRIX=6,
HP_NOTE=7,
HP_PROG=8,
HP_VAR=9,
HP_SCREEN=10,
HP_SETTINGS=10
};
const QString mimetypes[FUNC_NUM][2]={ {"Main","application/x-calc"},
{"Application Library","application/x-application"},
{"CAS Vars","application/x-casvars"},
{"Real","application/x-real"},
{"Complex","application/x-complex"},
{"Lists","application/x-list"},
{"Matrices","application/x-matrix"},
{"Notes","application/x-note"},
{"Programs","application/x-programme"},
{"Variables","application/x-var"}
};
struct hp_DataStruct {
QString filename;

View file

@ -12,12 +12,12 @@
const QString hpCalcData::func_list[FUNC_NUM][2]={{"Application Library",":/icons/apps_32x32.png"},
{"CAS Vars",":/icons/casFolder_32x32.png"},
{"Real",":/icons/real_32x32.png"},
{"Complex",":/icons/complex_32x32.png"},
{"Lists",":/icons/list_32x32.png"},
{"Matrices",":/icons/table_32x32.png"},
{"Notes",":/icons/note_32x32.png"},
{"Programs",":/icons/program_32x32.png"},
{"Real",":/icons/real_32x32.png"},
{"Variables",":/icons/varFolder_32x32.png"}
};
@ -413,5 +413,5 @@ void hpCalcData::vpkt_send_experiments(int cmd) {
}
hpCalcData::~hpCalcData() {
// qDebug()<<"Close ~hpCalcData";
qDebug()<<"Close ~hpCalcData";
};

View file

@ -8,18 +8,16 @@
#include <QMessageBox>
#include <QString>
#define FUNC_NUM 10
const QString hpTreeItem::func_list[FUNC_NUM][2]={
{"Main",":/icons/apps_32x32.png"},
{"Application Library",":/icons/apps_32x32.png"},
{"CAS Vars",":/icons/casFolder_32x32.png"},
{"Real",":/icons/real_32x32.png"},
{"Complex",":/icons/complex_32x32.png"},
{"Lists",":/icons/list_32x32.png"},
{"Matrices",":/icons/table_32x32.png"},
{"Notes",":/icons/note_32x32.png"},
{"Programs",":/icons/program_32x32.png"},
{"Real",":/icons/real_32x32.png"},
{"Variables",":/icons/varFolder_32x32.png"}
};
@ -27,12 +25,12 @@ const hp_DataType hpTreeItem::func_type[FUNC_NUM]={
HP_MAIN,
HP_APP,
HP_CAS,
HP_REAL,
HP_COMPLEX,
HP_LIST,
HP_MATRIX,
HP_NOTE,
HP_PROG,
HP_REAL,
HP_VAR
};
@ -600,7 +598,7 @@ hpTreeItem::~hpTreeItem() {
mdiarea=nullptr;
}
*/
//qDebug()<<"hpTreeItem:: delete";
removeColumn(0);
qDebug()<<"hpTreeItem:: delete"<<filename;
}

View file

@ -1389,10 +1389,15 @@ int hpusb::hotplugcallback(struct libusb_context *ctx, struct libusb_device *dev
//eventhandler called periodically to handle async events
int hpusb::eventHandler() {
// QMutexLocker locker(&mutex);
int completed;
// qDebug()<<"In Eventhandler";
libusb_handle_events_completed(nullptr, &completed);
QMutexLocker locker(&mutex);
int completed=0;
if (lb_init==1) {
libusb_handle_events_completed(nullptr, &completed);
}
qDebug()<<"hpusb::eventHandler::In Eventhandler closed";
return 0;
}

15
hpusb.h
View file

@ -5,6 +5,7 @@
#include <QObject>
#include <QByteArray>
#include <QMutex>
#include "hp_typedef.h"
struct hp_Settings;
class hpCalcData;
@ -117,15 +118,7 @@ struct hp_pkt_out {
uint8_t cmd;
};
typedef enum {
// 5 is triggered periodically by the official connectivity kit. It returns something with a PNG header, but much smaller.
CALC_SCREENSHOT_FORMAT_FIRST = 8,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x16 = 8,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_320x240x4 = 9,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x16 = 10,
CALC_SCREENSHOT_FORMAT_PRIME_PNG_160x120x4 = 11,
CALC_SCREENSHOT_FORMAT_LAST ///< Keep this one last
} hp_screenshot_format;
//! Structure defining a raw packet for the Prime, used at the lowest layer of the protocol implementation.
typedef struct
@ -217,12 +210,14 @@ public:
int hotplugcallback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event);
int eventHandler();
~hpusb();
signals:
void hotplug(int );
public slots:
int eventHandler();
};
#endif // HPUSB_H

View file

@ -45,6 +45,8 @@
#include "hp_mdivariableedit.h"
#include "hp_mditexteditor.h"
#include "options.h"
#include "eventthread.h"
#include "eventtimer.h"
errorHandler *main_err;
#define log(a) main_err->error(L7,0,QString(a),QString());
@ -119,14 +121,14 @@ MainWindow::MainWindow(QWidget *parent) :
err(L1,0,QString().sprintf("%s Failed to open libusb",__FUNCTION__));
//setup event handler
eventThread = new QThread(this);
eventTimer = new EventThread(nullptr);
eventThread = new EventThread(this);
eventTimer = new EventTimer(this);
// connect(eventTimer,SIGNAL(timeout()),this,SLOT(eventHandler()));
connect(eventThread,SIGNAL(finished()),eventTimer,SLOT(exit()), Qt::DirectConnection);
connect(eventTimer,SIGNAL(stopped()),this,SLOT(setTimerStopped()), Qt::DirectConnection);
connect(this,SIGNAL(stopTimer()),eventTimer,SLOT(exit()), Qt::DirectConnection);
connect(eventThread,SIGNAL(startTimer()),eventTimer,SLOT(start()));
eventTimer->moveToThread(eventThread);
// connect(eventTimer,SIGNAL(timeout()),this,SLOT(eventHandler()));
connect(eventThread,SIGNAL(started()),eventTimer,SLOT(start()));
connect(eventTimer,SIGNAL(stopped()),this,SLOT(setTimerStopped()));
connect(this,SIGNAL(stopTimer()),eventTimer,SLOT(stopTimer()));
eventThread->start();
ui->dwMessenger->hide();
@ -178,7 +180,7 @@ void MainWindow::eventHandler() {
if(hpapi) {
// qDebug()<<"In Eventhandler";
hpapi->eventHandler();
// hpapi->eventHandler();
}
}
@ -503,23 +505,11 @@ void MainWindow::setTimerStopped() {
qDebug()<<"MainWindow:: set timerStopped Flag";
timerStopped=1;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
//qDebug()<<"MainWindow:: closeEvent Step 1";
writeSettings();
//stop the timer pulse
emit stopTimer();
event->accept();
eventThread->exit();
close();
//qDebug()<<"MainWindow:: closeEvent Step 2";
}
void MainWindow::writeSettings()
{
QSettings appSettings("IRGP","QtHPconnect");
@ -648,43 +638,50 @@ void MainWindow::on_tvCalculators_customContextMenuRequested(const QPoint &pos)
}
}
void MainWindow::closeEvent(QCloseEvent *event)
{
qDebug()<<"MainWindow:: closeEvent Step 1";
writeSettings();
//stop the timer pulse
emit stopTimer();
eventThread->quit();
eventThread->terminate();
eventThread->wait();
event->accept();
qDebug()<<"MainWindow:: closeEvent Step 2";
}
//destructor
MainWindow::~MainWindow()
{
//qDebug()<<"MainWindow:: closeEvent Step 3";
ui->tvCalculators->close();
ui->tvContent->close();
ui->dwContent->close();
ui->dwMonitor->close();
ui->dwMessenger->close();
ui->dwCalculator->close();
// qDebug()<<"MainWindow:: closeEvent Step 4";
//qDebug()<<"MainWindow:: closeEvent Step 4";
if (main_err!=nullptr) {
delete main_err;
main_err=nullptr;
}
if (myModel!=nullptr) {
if (myModel!=nullptr) {
delete myModel;
myModel=nullptr;
}
//qDebug()<<"MainWindow:: closeEvent Step 5";
// qDebug()<<"MainWindow:: closeEvent Step 3";
ui->tvCalculators->close();
ui->tvContent->close();
ui->dwContent->close();
ui->dwMonitor->close();
ui->dwMessenger->close();
ui->dwCalculator->close();
//might need a mechanism to inform eventThread that the comms module is closed
if ((hpapi!=nullptr) && (timerStopped)) {
delete hpapi;
hpapi=nullptr;
}
//delete extra thread
if (eventThread!=nullptr) {
eventThread->quit();
}
// qDebug()<<"MainWindow:: closeEvent Step 5";
if (main_err!=nullptr) {
delete main_err;
main_err=nullptr;
}
qDebug()<<"MainWindow:: closing";
}

View file

@ -18,7 +18,7 @@
#include "hp_mdiwindow.h"
#include "hp_mdivariableedit.h"
#include "cntfilesystemmodel.h"
#include "eventthread.h"
#include "eventtimer.h"
class treeModel;
class errorHandler;
@ -82,9 +82,9 @@ private:
treeModel * hpTreeModel;
QThread * eventThread;
EventThread * eventTimer;
EventTimer * eventTimer;
QMenu * treeMenu=nullptr;
hpusb * hpapi;
hpusb * hpapi=nullptr;
QMdiSubWindow * msgWindow=nullptr;
hp_MdiWindow * logWindow=nullptr;
contentFileSystemModel contentModel;

View file

@ -199,23 +199,47 @@ bool treeModel::dropMimeData(const QMimeData* md_data, Qt::DropAction action, in
hpTreeItem * item=nullptr;
item = static_cast<hpTreeItem *>(itemFromIndex(index));
if (item!=nullptr) {
qDebug()<<md_data->formats();
hp_DataType type=HP_MAIN;
QStringList formatList;
QString mimeType;
formatList=md_data->formats();
QString name;
foreach(const QString& format, formatList) {
// qDebug()<<format;
for(int i = HP_MAIN; i < HP_SETTINGS; i++) {
mimeType=mimetypes[i][1];
// qDebug()<<mimeType;
if( mimeType==format) {
type=static_cast<hp_DataType>(i);
break;
}
}
}
name=md_data->text();
data_in=md_data->data("application/x-programme");
if ( type!=HP_MAIN) {
QString name=md_data->text();
data_in=md_data->data(mimetypes[type][1]);
QDataStream in(&data_in,QIODevice::ReadOnly);
absitem = new Program(name, HP_PROG, QStringLiteral(""));
absitem->parseData(in);
QDataStream in(&data_in,QIODevice::ReadOnly);
switch(type) {
case HP_PROG: {
absitem = new Program(name, HP_PROG, QStringLiteral(""));
absitem->parseData(in);
break;
}
}
QString calc = item->getCalculatorName();
addItem(calc,absitem);
qDebug()<<"treemodel::dropMimeData End";
// qDebug()<<"treemodel::dropMimeData End";
}
else {
qDebug()<<"treemodel::sropMimeData type not found "<<type;
return false;
}
}
return true;
}
@ -227,7 +251,7 @@ hpTreeItem * treeModel::findTypeRoot(QString calcName, hp_DataType type) {
hpTreeItem * calc=getCalculatorItem(calcName);
hpTreeItem *item;
qDebug()<<calc->getGroupName();
// qDebug()<<calc->getGroupName();
QModelIndex in = calc->index();
@ -286,10 +310,31 @@ Qt::ItemFlags treeModel::flags(const QModelIndex &index) const
return Qt::ItemIsDropEnabled | defaultFlags;
}
int deletCalculator(QString name, hpusb * handle) {
}
int treeModel::deleteAllCalculators() {
hpDataLink hplink;
hpCalcData * hpdata = nullptr;
foreach(QString key, hpCalcList.keys()) {
QMap<QString, hpDataLink>::const_iterator i = hpCalcList.find(key);
hplink=i.value();
delete(hplink.dataItem);
hpCalcList.remove(key);
}
hpCalcList.clear();
return 0;
}
treeModel::~treeModel() {
if (rootNode!=nullptr)
delete rootNode;
deleteAllCalculators();
qDebug()<<"treeModel:: delete";
}

View file

@ -29,6 +29,8 @@ public:
treeModel(QObject *parent);
virtual ~treeModel() override;
int addCalculator(QString name, hpusb * handle);
int deletCalculator(QString name, hpusb * handle);
int deleteAllCalculators();
hpCalcData * getCalculator(QString name);
hpTreeItem * getCalculatorItem(QString name);
hpCalcData * getHpCalcData(QString name);