Merge branch 'master' into defaults

This commit is contained in:
Seeker4 2019-07-14 20:28:06 -07:00
commit f6941843e8
6 changed files with 367 additions and 515 deletions

View File

@ -38,6 +38,48 @@
extern MainWindow * mainwin;
//void SaveThread::run()
//{
// bool running = true;
// while (running) {
// Session //sess = machine->popSaveList();
// if (sess) {
// if (machine->m_donetasks % 20 == 0) {
// int i = (float(machine->m_donetasks) / float(machine->m_totaltasks) * 100.0);
// emit UpdateProgress(i);
// }
// sess->UpdateSummaries();
// //machine->saveMutex.lock();
// sess->Store(path);
// //machine->saveMutex.unlock();
//
// sess->TrashEvents();
// } else {
// if (!machine->m_save_threads_running) {
// break; // done
// } else {
// yieldCurrentThread(); // go do something else for a while
// }
// }
// }
//
// machine->savelistSem->release(1);
//}
void SaveTask::run()
{
sess->UpdateSummaries();
mach->saveMutex.lock();
sess->Store(mach->getDataPath());
mach->saveMutex.unlock();
sess->TrashEvents();
}
void LoadTask::run()
{
sess->LoadSummary();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Machine Base-Class implmementation
//////////////////////////////////////////////////////////////////////////////////////////
@ -549,17 +591,10 @@ void Machine::setInfo(MachineInfo inf)
m_loader = GetLoader(inf.loadername);
}
//const quint32 channel_version=1;
const QString Machine::getDataPath()
{
m_dataPath = p_pref->Get("{home}/Profiles/")+profile->user->userName()+"/"+info.loadername + "_"
+ (info.serial.isEmpty() ? hexid() : info.serial) + "/";
//if (m_dataPath.isEmpty()) {
// m_dataPath = profile->Get("{" + STR_GEN_DataFolder + "}/" + info.loadername + "_" + (info.serial.isEmpty() ? hexid() : info.serial)) + "/";
// }
return m_dataPath;
}
const QString Machine::getSummariesPath()
@ -634,8 +669,6 @@ bool Machine::Load(ProgressDialog *progress)
progress->setProgressValue(0);
QApplication::processEvents();
QTime time;
time.start();
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
@ -752,147 +785,20 @@ bool Machine::SaveSession(Session *sess)
return true;
}
/*void Machine::queSaveList(Session * sess)
{
if (!m_save_threads_running) {
// Threads aren't being used.. so run the actual immediately...
int i = (float(m_donetasks) / float(m_totaltasks) * 100.0);
//qprogress->setValue(i);
//QApplication::processEvents();
sess->UpdateSummaries();
sess->Store(getDataPath());
if (!AppSetting->cacheSessions()) {
sess->TrashEvents();
}
} else {
listMutex.lock();
m_savelist.append(sess);
listMutex.unlock();
}
}*/
Session *Machine::popSaveList()
{
Session *sess = nullptr;
listMutex.lock();
if (!m_savelist.isEmpty()) {
sess = m_savelist.at(0);
m_savelist.pop_front();
m_donetasks++;
}
listMutex.unlock();
return sess;
}
/*// Call any time queing starts
void Machine::StartSaveThreads()
{
m_savelist.clear();
if (!AppSetting->multithreading()) return;
QString path = getDataPath();
int threads = QThread::idealThreadCount();
savelistSem = new QSemaphore(threads);
savelistSem->acquire(threads);
m_save_threads_running = true;
m_donetasks=0;
m_totaltasks=0;
for (int i = 0; i < threads; i++) {
SaveThread * thr = new SaveThread(this, path);
QObject::connect(thr, SIGNAL(UpdateProgress(int)), qprogress, SLOT(setValue(int)));
thread.push_back(thr);
thread[i]->start();
}
}
// Call when all queing is completed
void Machine::FinishSaveThreads()
{
if (!m_save_threads_running)
return;
m_save_threads_running = false;
// Wait for all tasks to finish
while (!savelistSem->tryAcquire(thread.size(), 250)) {
if (qprogress) {
QApplication::processEvents();
}
}
for (int i = 0; i < thread.size(); ++i) {
while (thread[i]->isRunning()) {
SaveThread::msleep(250);
QApplication::processEvents();
}
QObject::disconnect(thread[i], SIGNAL(UpdateProgress(int)), qprogress, SLOT(setValue(int)));
delete thread[i];
}
delete savelistSem;
} */
void SaveThread::run()
{
bool running = true;
while (running) {
Session *sess = machine->popSaveList();
if (sess) {
if (machine->m_donetasks % 20 == 0) {
int i = (float(machine->m_donetasks) / float(machine->m_totaltasks) * 100.0);
emit UpdateProgress(i);
}
sess->UpdateSummaries();
//machine->saveMutex.lock();
sess->Store(path);
//machine->saveMutex.unlock();
sess->TrashEvents();
} else {
if (!machine->m_save_threads_running) {
break; // done
} else {
yieldCurrentThread(); // go do something else for a while
}
}
}
machine->savelistSem->release(1);
}
class SaveTask:public ImportTask
{
public:
SaveTask(Session * s, Machine * m): sess(s), mach(m) {}
virtual ~SaveTask() {}
virtual void run();
protected:
Session * sess;
Machine * mach;
};
void SaveTask::run()
{
sess->UpdateSummaries();
mach->saveMutex.lock();
sess->Store(mach->getDataPath());
mach->saveMutex.unlock();
sess->TrashEvents();
}
//Session *Machine::popSaveList()
//{
// Session *sess = nullptr;
// listMutex.lock();
//
// if (!m_savelist.isEmpty()) {
// sess = m_savelist.at(0);
// m_savelist.pop_front();
// m_donetasks++;
// }
//
// listMutex.unlock();
// return sess;
//}
void Machine::queTask(ImportTask * task)
{
@ -913,24 +819,23 @@ void Machine::runTasks()
QThreadPool * threadpool = QThreadPool::globalInstance();
/***********************************************************
int m_totaltasks=m_tasklist.size();
int m_currenttask=0;
if (loader())
emit loader()->setProgressMax(m_totaltasks);
// int m_totaltasks=m_tasklist.size();
// int m_currenttask=0;
// if (loader())
// emit loader()->setProgressMax(m_totaltasks);
***********************************************************/
while (!m_tasklist.isEmpty()) {
if (threadpool->tryStart(m_tasklist.at(0))) {
m_tasklist.pop_front();
/************************************************************
if (loader()) {
emit loader()->setProgressValue(++m_currenttask);
QApplication::processEvents();
}
// if (loader()) {
// emit loader()->setProgressValue(++m_currenttask);
// QApplication::processEvents();
// }
***************************************************************/
}
}
QThreadPool::globalInstance()->waitForDone(-1);
}
bool Machine::hasModifiedSessions()
@ -948,23 +853,6 @@ bool Machine::hasModifiedSessions()
const QString summaryFileName = "Summaries.xml";
const int summaryxml_version=1;
class LoadTask:public ImportTask
{
public:
LoadTask(Session * s, Machine * m): sess(s), mach(m) {}
virtual ~LoadTask() {}
virtual void run();
protected:
Session * sess;
Machine * mach;
};
void LoadTask::run()
{
sess->LoadSummary();
}
bool Machine::LoadSummary(ProgressDialog * progress)
{
QTime time;
@ -1073,7 +961,6 @@ bool Machine::LoadSummary(ProgressDialog * progress)
}
QMap<qint64, Session *>::iterator it_end = sess_order.end();
QMap<qint64, Session *>::iterator it;
int cnt = 0;
bool loadSummaries = profile->session->preloadSummaries();
qDebug() << "PreloadSummaries is" << (loadSummaries ? "true" : "false");
qDebug() << "Queue task loader is" << (loader() ? "" : "not ") << "available";
@ -1081,15 +968,16 @@ bool Machine::LoadSummary(ProgressDialog * progress)
// progress->setMessage(QObject::tr("Queueing Open Tasks"));
// QApplication::processEvents();
// int cnt = 0;
// progress->setMaximum(sess_order.size());
for (it = sess_order.begin(); it != it_end; ++it, ++cnt) {
for (it = sess_order.begin(); it != it_end; ++it /*, ++cnt*/ ) {
/****************************************************************
if ((cnt % 100) == 0) {
progress->setValue(cnt);
//QApplication::processEvents();
}
// if ((cnt % 100) == 0) {
// progress->setValue(cnt);
// //QApplication::processEvents();
// }
*****************************************************************/
Session * sess = it.value();
if (!AddSession(sess)) {
@ -1212,7 +1100,7 @@ bool Machine::Save()
QHash<SessionID, Session *>::iterator s;
m_savelist.clear();
// m_savelist.clear();
// store any event summaries..
for (s = sessionlist.begin(); s != sessionlist.end(); s++) {

View File

@ -41,24 +41,24 @@ class Machine;
/*! \class SaveThread
\brief This class is used in the multithreaded save code.. It accelerates the indexing of summary data.
*/
class SaveThread: public QThread
{
Q_OBJECT
public:
SaveThread(Machine *m, QString p) { machine = m; path = p; }
//! \brief Static millisecond sleep function.. Can be used from anywhere
static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
//! \brief Start Save processing thread running
virtual void run();
protected:
Machine *machine;
QString path;
signals:
//! \brief Signal sent to update the Progress Bar
void UpdateProgress(int i);
};
//class SaveThread: public QThread
//{
// Q_OBJECT
// public:
// SaveThread(Machine *m, QString p) { machine = m; path = p; }
//
// //! \brief Static millisecond sleep function.. Can be used from anywhere
// static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
//
// //! \brief Start Save processing thread running
// virtual void run();
// protected:
// Machine *machine;
// QString path;
// signals:
// //! \brief Signal sent to update the Progress Bar
// void UpdateProgress(int i);
//};
class ImportTask:public QRunnable
{
@ -68,15 +68,39 @@ public:
virtual void run() {}
};
class MachineLoader;
class SaveTask:public ImportTask
{
public:
SaveTask(Session * s, Machine * m): sess(s), mach(m) {}
virtual ~SaveTask() {}
virtual void run();
protected:
Session * sess;
Machine * mach;
};
class LoadTask:public ImportTask
{
public:
LoadTask(Session * s, Machine * m): sess(s), mach(m) {}
virtual ~LoadTask() {}
virtual void run();
protected:
Session * sess;
Machine * mach;
};
class MachineLoader; // forward
/*! \class Machine
\brief This Machine class is the Heart of SleepyLib, representing a single Machine and holding it's data
*/
class Machine
{
friend class SaveThread;
friend class MachineLaoder;
// friend class MachineLaoder;
public:
/*! \fn Machine(MachineID id=0);
@ -115,15 +139,6 @@ class Machine
return m_availableSettings.contains(code);
}
//! \brief Contains a secondary index of day data, containing just this machines sessions
QMap<QDate, Day *> day;
//! \brief Contains all sessions for this machine, indexed by SessionID
QHash<SessionID, Session *> sessionlist;
//! \brief List of text machine properties, like brand, model, etc...
QHash<QString, QString> properties;
//! \brief Returns a pointer to a valid Session object if SessionID exists
Session *SessionExists(SessionID session);
@ -160,50 +175,13 @@ class Machine
//! \brief Returns the date of the most recent loaded Session
const QDate &LastDay() { return lastday; }
// //! \brief Add a new task to the multithreaded save code
//void queSaveList(Session * sess);
bool hasModifiedSessions();
//! \brief Grab the next task in the multithreaded save code
Session *popSaveList();
// //! \brief Start the save threads which handle indexing, file storage and waveform processing
//void StartSaveThreads();
// //! \brief Finish the save threads and safely close them
//void FinishSaveThreads();
//! \brief The list of sessions that need saving (for multithreaded save code)
QList<Session *> m_savelist;
//yuck
QVector<SaveThread *>thread;
volatile int savelistCnt;
int savelistSize;
QMutex listMutex;
QSemaphore *savelistSem;
bool m_unsupported;
bool m_untested;
bool unsupported() { return m_unsupported; }
void setUnsupported(bool b) { m_unsupported = b; }
bool untested() { return m_untested; }
void setUntested(bool b) { m_untested = b; }
void lockSaveMutex() { listMutex.lock(); }
void unlockSaveMutex() { listMutex.unlock(); }
void skipSaveTask() { lockSaveMutex(); m_donetasks++; unlockSaveMutex(); }
void clearSkipped() { skipped_sessions = 0; }
int skippedSessions() { return skipped_sessions; }
inline int totalTasks() { return m_totaltasks; }
inline void setTotalTasks(int value) { m_totaltasks = value; }
inline int doneTasks() { return m_donetasks; }
inline MachineType type() const { return info.type; }
inline QString brand() const { return info.brand; }
inline QString loaderName() const { return info.loadername; }
@ -231,23 +209,69 @@ class Machine
MachineLoader * loader() { return m_loader; }
// much more simpler multithreading...
void queTask(ImportTask * task);
void runTasks();
QMutex saveMutex;
void setInfo(MachineInfo inf);
const MachineInfo getInfo() { return info; }
void updateChannels(Session * sess);
QString getPixmapPath();
QPixmap & getPixmap();
// //! \brief The multi-threading methods follow
// //! \brief Add a new task to the multithreaded save code
//void queSaveList(Session * sess);
//! \brief Grab the next task in the multithreaded save code
//Session *popSaveList();
// //! \brief Start the save threads which handle indexing, file storage and waveform processing
//void StartSaveThreads();
// //! \brief Finish the save threads and safely close them
//void FinishSaveThreads();
// void lockSaveMutex() { listMutex.lock(); }
// void unlockSaveMutex() { listMutex.unlock(); }
// void skipSaveTask() { lockSaveMutex(); m_donetasks++; unlockSaveMutex(); }
//
// void clearSkipped() { skipped_sessions = 0; }
// int skippedSessions() { return skipped_sessions; }
//
// inline int totalTasks() { return m_totaltasks; }
// inline void setTotalTasks(int value) { m_totaltasks = value; }
// inline int doneTasks() { return m_donetasks; }
// much more simpler multithreading...(no such thing - pholynyk)
void queTask(ImportTask * task);
void runTasks();
// Public Data Members follow
MachineInfo info;
protected:
bool m_unsupported;
bool m_untested;
//! \brief Contains a secondary index of day data, containing just this machines sessions
QMap<QDate, Day *> day;
//! \brief Contains all sessions for this machine, indexed by SessionID
QHash<SessionID, Session *> sessionlist;
//! \brief List of text machine properties, like brand, model, etc...
QHash<QString, QString> properties;
//! \brief The list of sessions that need saving (for multithreaded save code)
// QList<Session *> m_savelist;
// Following are the items related to multi-threading
// QVector<SaveThread *>thread;
// volatile int savelistCnt;
// int savelistSize;
QMutex listMutex;
QMutex saveMutex;
// QSemaphore *savelistSem;
protected: // only Data Memebers here
QDate firstday, lastday;
SessionID highest_sessionid;
MachineID m_id;
@ -258,13 +282,6 @@ class Machine
bool changed;
bool firstsession;
int m_totaltasks;
int m_donetasks;
int skipped_sessions;
volatile bool m_save_threads_running;
QList<ImportTask *> m_tasklist;
QHash<ChannelID, bool> m_availableChannels;
QHash<ChannelID, bool> m_availableSettings;
@ -274,6 +291,15 @@ class Machine
QString m_dataPath;
Profile * profile;
// The following are the multi-threading data members
int m_totaltasks;
int m_donetasks;
int skipped_sessions;
volatile bool m_save_threads_running;
QList<ImportTask *> m_tasklist;
};

View File

@ -1,5 +1,6 @@
/* SleepLib Machine Loader Class Implementation
*
* Copyright (c) 2019 The OSCAR Team
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
*
* This file is subject to the terms and conditions of the GNU General Public
@ -13,11 +14,139 @@
#include "machine_loader.h"
// GLOBALS:
bool genpixmapinit = false;
QList<MachineLoader *> m_loaders;
QPixmap * MachineLoader::genericCPAPPixmap;
// This crap moves to Profile
QList<MachineLoader *> m_loaders;
MachineLoader::MachineLoader() :QObject(nullptr)
{
#ifndef UNITTEST_MODE // no QPixmap without a QGuiApplication
if (!genpixmapinit) {
genericCPAPPixmap = new QPixmap(genericPixmapPath);
genpixmapinit = true;
}
#endif
m_abort = false;
m_type = MT_UNKNOWN;
m_status = NEUTRAL;
}
MachineLoader::~MachineLoader()
{
}
void MachineLoader::unsupported(Machine * m)
{
if (m == nullptr) {
qCritical("MachineLoader::unsupported(Machine *) called with null machine object");
return;
}
m->setUnsupported(true);
emit machineUnsupported(m);
}
void MachineLoader::addSession(Session * sess)
{
sessionMutex.lock();
new_sessions[sess->session()] = sess;
sessionMutex.unlock();
}
void MachineLoader::finishAddingSessions()
{
// Using a map specifically so they are inserted in order.
for (auto it=new_sessions.begin(), end=new_sessions.end(); it != end; ++it) {
Session * sess = it.value();
Machine * mach = sess->machine();
mach->AddSession(sess);
}
new_sessions.clear();
}
QPixmap & MachineLoader::getPixmap(QString series)
{
QHash<QString, QPixmap>::iterator it = m_pixmaps.find(series);
if (it != m_pixmaps.end()) {
return it.value();
}
return *genericCPAPPixmap;
}
QString MachineLoader::getPixmapPath(QString series)
{
QHash<QString, QString>::iterator it = m_pixmap_paths.find(series);
if (it != m_pixmap_paths.end()) {
return it.value();
}
return genericPixmapPath;
}
void MachineLoader::queTask(ImportTask * task)
{
m_MLtasklist.push_back(task);
}
void MachineLoader::runTasks(bool threaded)
{
m_totalMLtasks=m_MLtasklist.size();
if (m_totalMLtasks == 0)
return;
emit setProgressMax(m_totalMLtasks);
m_currentMLtask=0;
threaded=AppSetting->multithreading();
if (!threaded) {
while (!m_MLtasklist.isEmpty() && !m_abort) {
ImportTask * task = m_MLtasklist.takeFirst();
task->run();
// update progress bar
m_currentMLtask++;
emit setProgressValue(m_currentMLtask);
QApplication::processEvents();
delete task;
}
} else {
ImportTask * task = m_MLtasklist[0];
QThreadPool * threadpool = QThreadPool::globalInstance();
while (!m_abort) {
if (threadpool->tryStart(task)) {
m_MLtasklist.pop_front();
if (!m_MLtasklist.isEmpty()) {
// next task to be run
task = m_MLtasklist[0];
// update progress bar
emit setProgressValue(++m_currentMLtask);
QApplication::processEvents();
} else {
// job list finished
break;
}
}
//QThread::sleep(100);
}
QThreadPool::globalInstance()->waitForDone(-1);
}
if (m_abort) {
// delete remaining tasks and clear task list
for (auto & task : m_MLtasklist) {
delete task;
}
m_MLtasklist.clear();
}
}
QList<MachineLoader *> GetLoaders(MachineType mt)
{
@ -60,6 +189,7 @@ void RegisterLoader(MachineLoader *loader)
loader->initChannels();
m_loaders.push_back(loader);
}
void DestroyLoaders()
{
for (auto & loader : m_loaders) {
@ -69,32 +199,23 @@ void DestroyLoaders()
m_loaders.clear();
}
MachineLoader::MachineLoader() :QObject(nullptr)
QList<ChannelID> CPAPLoader::eventFlags(Day * day)
{
#ifndef UNITTEST_MODE // no QPixmap without a QGuiApplication
if (!genpixmapinit) {
genericCPAPPixmap = new QPixmap(genericPixmapPath);
genpixmapinit = true;
}
#endif
m_abort = false;
m_type = MT_UNKNOWN;
m_status = NEUTRAL;
}
Machine * mach = day->machine(MT_CPAP);
MachineLoader::~MachineLoader()
{
}
QList<ChannelID> list;
void MachineLoader::finishAddingSessions()
{
// Using a map specifically so they are inserted in order.
for (auto it=new_sessions.begin(), end=new_sessions.end(); it != end; ++it) {
Session * sess = it.value();
Machine * mach = sess->machine();
mach->AddSession(sess);
if (mach->loader() != this) {
qDebug() << "Trying to ask" << loaderName() << "for" << mach->loaderName() << "data";
return list;
}
new_sessions.clear();
list.push_back(CPAP_ClearAirway);
list.push_back(CPAP_Obstructive);
list.push_back(CPAP_Hypopnea);
list.push_back(CPAP_Apnea);
return list;
}
bool uncompressFile(QString infile, QString outfile)
@ -194,165 +315,3 @@ bool compressFile(QString infile, QString outfile)
return true;
}
void MachineLoader::queTask(ImportTask * task)
{
m_tasklist.push_back(task);
}
void MachineLoader::runTasks(bool threaded)
{
m_totaltasks=m_tasklist.size();
if (m_totaltasks == 0) return;
emit setProgressMax(m_totaltasks);
m_currenttask=0;
threaded=AppSetting->multithreading();
if (!threaded) {
while (!m_tasklist.isEmpty() && !m_abort) {
ImportTask * task = m_tasklist.takeFirst();
task->run();
// update progress bar
m_currenttask++;
emit setProgressValue(++m_currenttask);
QApplication::processEvents();
delete task;
}
} else {
ImportTask * task = m_tasklist[0];
QThreadPool * threadpool = QThreadPool::globalInstance();
while (!m_abort) {
if (threadpool->tryStart(task)) {
m_tasklist.pop_front();
if (!m_tasklist.isEmpty()) {
// next task to be run
task = m_tasklist[0];
// update progress bar
emit setProgressValue(++m_currenttask);
QApplication::processEvents();
} else {
// job list finished
break;
}
}
//QThread::sleep(100);
}
QThreadPool::globalInstance()->waitForDone(-1);
}
if (m_abort) {
// delete remaining tasks and clear task list
for (auto & task : m_tasklist) {
delete task;
}
m_tasklist.clear();
}
}
QList<ChannelID> CPAPLoader::eventFlags(Day * day)
{
Machine * mach = day->machine(MT_CPAP);
QList<ChannelID> list;
if (mach->loader() != this) {
qDebug() << "Trying to ask" << loaderName() << "for" << mach->loaderName() << "data";
return list;
}
list.push_back(CPAP_ClearAirway);
list.push_back(CPAP_Obstructive);
list.push_back(CPAP_Hypopnea);
list.push_back(CPAP_Apnea);
return list;
}
/*const QString machine_profile_name="MachineList.xml";
void MachineLoader::LoadMachineList()
{
}
void MachineLoader::StoreMachineList()
{
}
void MachineLoader::LoadSummary(Machine *m, QString &filename)
{
QFile f(filename);
if (!f.exists())
return;
f.open(QIODevice::ReadOnly);
if (!f.isReadable())
return;
}
void MachineLoader::LoadSummaries(Machine *m)
{
QString path=(*profile)["ProfileDirectory"]+"/"+m_classname+"/"+mach->hexid();
QDir dir(path);
if (!dir.exists() || !dir.isReadable())
return false;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Name);
QString fullpath,ext_s,sesstr;
int ext;
SessionID sessid;
bool ok;
QMap<SessionID, int> sessions;
QFileInfoList list=dir.entryInfoList();
for (int i=0;i<list.size();i++) {
QFileInfo fi=list.at(i);
fullpath=fi.canonicalFilePath();
ext_s=fi.fileName().section(".",-1);
ext=ext_s.toInt(&ok,10);
if (!ok) continue;
sesstr=fi.fileName().section(".",0,-2);
sessid=sesstr.toLong(&ok,16);
if (!ok) continue;
}
}
void MachineLoader::LoadAllSummaries()
{
for (int i=0;i<m_machlist.size();i++)
LoadSummaries(m_machlist[i]);
}
void MachineLoader::LoadAllEvents()
{
for (int i=0;i<m_machlist.size();i++)
LoadEvents(m_machlist[i]);
}
void MachineLoader::LoadAllWaveforms()
{
for (int i=0;i<m_machlist.size();i++)
LoadWaveforms(m_machlist[i]);
}
void MachineLoader::LoadAll()
{
LoadAllSummaries();
LoadAllEvents();
LoadAllWaveforms();
}
void MachineLoader::Save(Machine *m)
{
}
void MachineLoader::SaveAll()
{
for (int i=0;i<m_machlist.size();i++)
Save(m_machlist[i]);
}
*/

View File

@ -1,5 +1,6 @@
/* SleepLib MachineLoader Base Class Header
*
* Copyright (c) 2019 The OSCAR Team
* Copyright (c) 2018 Mark Watkins <mark@jedimark.net>
*
* This file is subject to the terms and conditions of the GNU General Public
@ -27,7 +28,8 @@
#define protected public
#endif
class MachineLoader;
class MachineLoader; // forward
enum DeviceStatus { NEUTRAL, IMPORTING, LIVE, DETECTING };
const QString genericPixmapPath = ":/icons/mask.png";
@ -61,59 +63,34 @@ class MachineLoader: public QObject
virtual MachineInfo newInfo() { return MachineInfo(); }
//! \brief Override to returns the class name of this MachineLoader
virtual const QString &loaderName() = 0;
inline MachineType type() { return m_type; }
void unsupported(Machine * m) {
if (m == nullptr) {
qCritical("MachineLoader::unsupported(Machine *) called with null machine object");
return;
}
m->setUnsupported(true);
emit machineUnsupported(m);
}
void queTask(ImportTask * task);
void addSession(Session * sess)
{
sessionMutex.lock();
new_sessions[sess->session()] = sess;
sessionMutex.unlock();
}
//! \brief Process Task list using all available threads.
void runTasks(bool threaded=true);
int countTasks() { return m_tasklist.size(); }
inline bool isAborted() { return m_abort; }
void abort() { m_abort = true; }
virtual const QString & loaderName() = 0;
virtual void process() {}
DeviceStatus status() { return m_status; }
void setStatus(DeviceStatus status) { m_status = status; }
virtual void initChannels() {}
void unsupported(Machine * m);
void addSession(Session * sess);
inline MachineType type() { return m_type; }
inline DeviceStatus status() { return m_status; }
inline void setStatus(DeviceStatus status) { m_status = status; }
QPixmap & getPixmap(QString series);
QString getPixmapPath(QString series);
void queTask(ImportTask * task);
//! \brief Process Task list using all available threads.
void runTasks(bool threaded = false);
inline int countTasks() { return m_MLtasklist.size(); }
inline bool isAborted() { return m_abort; }
inline void abort() { m_abort = true; }
QMutex sessionMutex;
QMutex saveMutex;
virtual void initChannels() {}
QPixmap & getPixmap(QString series) {
QHash<QString, QPixmap>::iterator it = m_pixmaps.find(series);
if (it != m_pixmaps.end()) {
return it.value();
}
return *genericCPAPPixmap;
}
QString getPixmapPath(QString series) {
QHash<QString, QString>::iterator it = m_pixmap_paths.find(series);
if (it != m_pixmap_paths.end()) {
return it.value();
}
return genericPixmapPath;
}
public slots:
void abortImport() { abort(); }
@ -125,27 +102,26 @@ signals:
void machineUnsupported(Machine *);
protected:
void finishAddingSessions();
static QPixmap * genericCPAPPixmap;
MachineType m_type;
QString m_class;
int m_currenttask;
int m_totaltasks;
int m_currentMLtask;
int m_totalMLtasks;
bool m_abort;
DeviceStatus m_status;
MachineType m_type;
QString m_class;
void finishAddingSessions();
QMap<SessionID, Session *> new_sessions;
QHash<QString, QPixmap> m_pixmaps;
QHash<QString, QString> m_pixmap_paths;
private:
QList<ImportTask *> m_tasklist;
QList<ImportTask *> m_MLtasklist;
};
class CPAPLoader:public MachineLoader
@ -167,15 +143,17 @@ public:
};
struct ImportPath
class ImportPath
{
public:
ImportPath() {
path = QString();
loader = nullptr;
}
ImportPath(const ImportPath & copy) {
loader = copy.loader;
path = copy.path;
}
// ImportPath(const ImportPath & copy) {
// loader = copy.loader;
// path = copy.path;
// }
ImportPath(QString path, MachineLoader * loader) :
path(path), loader(loader) {}
@ -186,14 +164,15 @@ struct ImportPath
// Put in machine loader class as static??
void RegisterLoader(MachineLoader *loader);
QList<MachineLoader *> GetLoaders(MachineType mt = MT_UNKNOWN);
MachineLoader * lookupLoader(Machine * m);
MachineLoader * lookupLoader(QString loaderName);
void DestroyLoaders();
// Why here? Where are these called?
bool compressFile(QString inpath, QString outpath = "");
bool uncompressFile(QString infile, QString outfile);
QList<MachineLoader *> GetLoaders(MachineType mt = MT_UNKNOWN);
#endif //MACHINE_LOADER_H

View File

@ -308,7 +308,7 @@ int main(int argc, char *argv[]) {
QString datadir ;
if ((i+1) < args.size()) {
datadir = args[++i];
if (datadir.length() < 2 || datadir.at(1) != ":") // Allow a Windows drive letter (but not UNC)
if (datadir.length() < 2 || datadir.at(1) != QLatin1Char(':')) // Allow a Windows drive letter (but not UNC)
datadir = homeDocs+datadir;
settings.setValue("Settings/AppData", datadir);
// force_data_dir = true;

View File

@ -93,10 +93,10 @@ void parseAndEmitSessionYaml(const QString & path)
s_loader->ScanFiles(paths, sessionid_base, m);
// Each session now has a PRS1Import object in m_tasklist
// Each session now has a PRS1Import object in m_MLtasklist
QList<ImportTask*>::iterator i;
while (!s_loader->m_tasklist.isEmpty()) {
ImportTask* task = s_loader->m_tasklist.takeFirst();
while (!s_loader->m_MLtasklist.isEmpty()) {
ImportTask* task = s_loader->m_MLtasklist.takeFirst();
// Run the parser
PRS1Import* import = dynamic_cast<PRS1Import*>(task);