Multithreading prototype.

This commit is contained in:
Julien Wadel 2022-09-11 22:20:28 +02:00
parent d0f8e7335e
commit 3399c9e445
11 changed files with 255 additions and 15 deletions

View file

@ -241,6 +241,7 @@ set(SOURCES
src/components/content/ContentProxyModel.cpp
src/components/core/CoreHandlers.cpp
src/components/core/CoreManager.cpp
src/components/core/CoreManagerGUI.cpp
src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
src/components/file/FileDownloader.cpp
src/components/file/FileExtractor.cpp
@ -252,6 +253,7 @@ set(SOURCES
src/components/ldap/LdapModel.cpp
src/components/ldap/LdapListModel.cpp
src/components/ldap/LdapProxyModel.cpp
#src/components/linphoneObject/LinphoneThread.cpp
src/components/notifier/Notifier.cpp
src/components/other/clipboard/Clipboard.cpp
src/components/other/colors/ColorModel.cpp
@ -381,6 +383,7 @@ set(HEADERS
src/components/content/ContentProxyModel.hpp
src/components/core/CoreHandlers.hpp
src/components/core/CoreManager.hpp
src/components/core/CoreManagerGUI.hpp
src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
src/components/file/FileDownloader.hpp
src/components/file/FileExtractor.hpp
@ -392,6 +395,7 @@ set(HEADERS
src/components/ldap/LdapModel.hpp
src/components/ldap/LdapListModel.hpp
src/components/ldap/LdapProxyModel.hpp
src/components/linphoneObject/LinphoneThread.hpp
src/components/notifier/Notifier.hpp
src/components/other/clipboard/Clipboard.hpp
src/components/other/colors/ColorModel.hpp

View file

@ -61,6 +61,10 @@
#include "components/participant/ParticipantListModel.hpp"
#include "components/participant/ParticipantProxyModel.hpp"
#include <linphone++/enums.hh>
#include <linphone++/linphone.hh>
Q_DECLARE_METATYPE(linphone::ConfiguringState)
// =============================================================================
using namespace std;
@ -200,8 +204,7 @@ bool App::setFetchConfig (QCommandLineParser *parser) {
App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::User | Mode::ExcludeAppPath | Mode::ExcludeAppVersion) {
connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(stateChanged(Qt::ApplicationState)));
connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(stateChanged(Qt::ApplicationState)));
setWindowIcon(QIcon(Constants::WindowIconPath));
@ -658,6 +661,7 @@ void App::registerTypes () {
qRegisterMetaType<QSharedPointer<ChatCallModel>>();
qRegisterMetaType<QSharedPointer<ConferenceInfoModel>>();
//qRegisterMetaType<std::shared_ptr<ChatEvent>>();
qRegisterMetaType<linphone::ConfiguringState>();
LinphoneEnums::registerMetaTypes();
registerType<AssistantModel>("AssistantModel");
@ -741,7 +745,7 @@ void App::registerSharedTypes () {
qInfo() << QStringLiteral("Registering shared types...");
registerSharedSingletonType<App, &App::getInstance>("App");
registerSharedSingletonType<CoreManager, &CoreManager::getInstance>("CoreManager");
registerSharedSingletonType<CoreManagerGUI, &CoreManager::getInstanceGUI>("CoreManager");
registerSharedSingletonType<SettingsModel, &CoreManager::getSettingsModel>("SettingsModel");
registerSharedSingletonType<AccountSettingsModel, &CoreManager::getAccountSettingsModel>("AccountSettingsModel");
registerSharedSingletonType<SipAddressesModel, &CoreManager::getSipAddressesModel>("SipAddressesModel");

View file

@ -52,6 +52,7 @@
#include "content/ContentProxyModel.hpp"
#include "core/CoreHandlers.hpp"
#include "core/CoreManager.hpp"
#include "core/CoreManagerGUI.hpp"
#include "file/FileDownloader.hpp"
#include "file/FileExtractor.hpp"
#include "file/TemporaryFile.hpp"

View file

@ -0,0 +1,32 @@
#include "Core.hpp"
#include <QDebug>
#include <QTimer>
#include "utils/Constants.hpp"
Core::Core(QObject * parent) : LinphoneObject<std::shared_ptr<linphone::Core>>(parent){
}
void Core::startIterate(){
mCbsTimer = new QTimer((QThread*)this);
mCbsTimer->setInterval(Constants::CbsCallInterval);
QObject::connect(mCbsTimer, &QTimer::timeout, this, &Core::iterate);
qInfo() << QStringLiteral("Start iterate");
mCbsTimer->start();
start();
}
void Core::stopIterate(){
qInfo() << QStringLiteral("Stop iterate");
mCbsTimer->stop();
mCbsTimer->deleteLater();// allow the timer to continue its stuff
mCbsTimer = nullptr;
}
void Core::iterate ()
if(mLinphoneObject)
mLinphoneObject->iterate();
}

View file

@ -0,0 +1,22 @@
#ifndef CORE_H
#define CORE_H
#include <linphone++/core.hh>
#include "components/linphoneObject/LinphoneObject.h"
#include <QThread>
class QTimer;
class Core : public LinphoneObject<std::shared_ptr<linphone::Core>>{
public:
Core(QObject * parent = nullptr);
void startIterate();
void stopIterate();
void iterate ();
private:
QTimer * mCbsTimer;
};
#endif // CORE_H

View file

@ -34,6 +34,7 @@
#include "components/contact/VcardModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "components/contacts/ContactsImporterListModel.hpp"
#include "components/core/CoreManagerGUI.hpp"
#include "components/history/HistoryModel.hpp"
#include "components/ldap/LdapListModel.hpp"
#include "components/recorder/RecorderManager.hpp"
@ -56,6 +57,7 @@
#include <linphone/core.h>
#include <linphone/core.h>
#include "components/linphoneObject/LinphoneThread.hpp"
// =============================================================================
@ -64,6 +66,8 @@ using namespace std;
// -----------------------------------------------------------------------------
CoreManager *CoreManager::mInstance=nullptr;
CoreManagerGUI *CoreManager::mInstanceGUI=nullptr;
QSharedPointer<LinphoneThread> CoreManager::gLinphoneThread = nullptr;
CoreManager::CoreManager (QObject *parent, const QString &configPath) :
QObject(parent), mHandlers(make_shared<CoreHandlers>(this)) {
@ -123,6 +127,10 @@ CoreManager *CoreManager::getInstance (){
return mInstance;
}
CoreManagerGUI *CoreManager::getInstanceGUI (){
return mInstanceGUI;
}
HistoryModel* CoreManager::getHistoryModel(){
if(!mHistoryModel){
@ -144,7 +152,12 @@ RecorderManager* CoreManager::getRecorderManager(){
void CoreManager::init (QObject *parent, const QString &configPath) {
if (mInstance)
return;
mInstance = new CoreManager(parent, configPath);
gLinphoneThread = QSharedPointer<LinphoneThread>::create(parent);
gLinphoneThread->start();
//this->moveToThread(mLinphoneThread.get());
mInstance = new CoreManager(nullptr, configPath);
gLinphoneThread->objectToThread(mInstance);
mInstanceGUI = new CoreManagerGUI(parent);
}
void CoreManager::uninit () {
@ -155,6 +168,10 @@ void CoreManager::uninit () {
mInstance->unlockVideoRender();
delete mInstance; // This will also remove stored Linphone objects.
mInstance = nullptr;
gLinphoneThread->exit();
gLinphoneThread = nullptr;
mInstanceGUI->deleteLater();
mInstanceGUI = nullptr;
core->stop();
if( core->getGlobalState() != linphone::GlobalState::Off)
qWarning() << "Core is not off after stopping it. It may result to have multiple core instance.";
@ -412,16 +429,19 @@ std::list<std::shared_ptr<linphone::Account>> CoreManager::getAccountList()const
// -----------------------------------------------------------------------------
void CoreManager::startIterate(){
mCbsTimer = new QTimer(this);
mCbsTimer = new QTimer();
mCbsTimer->setInterval(Constants::CbsCallInterval);
QObject::connect(mCbsTimer, &QTimer::timeout, this, &CoreManager::iterate);
QObject::connect(mCbsTimer, &QTimer::timeout, this, &CoreManager::iterate, Qt::DirectConnection);
qInfo() << QStringLiteral("Start iterate");
mCbsTimer->start();
emit gLinphoneThread->startT(mCbsTimer);
//gLinphoneThread->test(mCbsTimer);
//mCbsTimer->start();
}
void CoreManager::stopIterate(){
qInfo() << QStringLiteral("Stop iterate");
mCbsTimer->stop();
emit gLinphoneThread->stopT(mCbsTimer);
//mCbsTimer->stop();
mCbsTimer->deleteLater();// allow the timer to continue its stuff
mCbsTimer = nullptr;
}

View file

@ -26,6 +26,7 @@
#include <QString>
#include <QHash>
#include <QMutex>
#include <QSharedPointer>
// =============================================================================
@ -39,6 +40,7 @@ class ChatRoomModel;
class ContactsListModel;
class ContactsImporterListModel;
class CoreHandlers;
class CoreManagerGUI;
class EventCountNotifier;
class HistoryModel;
class LdapListModel;
@ -48,16 +50,17 @@ class SipAddressesModel;
class VcardModel;
class TimelineListModel;
class LinphoneThread;
class CoreManager : public QObject {
Q_OBJECT;
Q_OBJECT
Q_PROPERTY(QString version READ getVersion CONSTANT)
Q_PROPERTY(QString downloadUrl READ getDownloadUrl CONSTANT)
Q_PROPERTY(int eventCount READ getEventCount NOTIFY eventCountChanged)
Q_PROPERTY(int callLogsCount READ getCallLogsCount NOTIFY callLogsCountChanged)
Q_PROPERTY(bool initialized READ isInitialized NOTIFY coreManagerInitialized)
public:
bool started () const {
return mStarted;
@ -135,6 +138,11 @@ public:
}
static CoreManager *getInstance ();
static CoreManagerGUI *getInstanceGUI();
QString getVersion () const;
int getEventCount () const;
static QString getDownloadUrl ();
// ---------------------------------------------------------------------------
// Initialization.
@ -200,16 +208,12 @@ private:
void migrate ();
QString getVersion () const;
int getEventCount () const;
void iterate ();
void handleLogsUploadStateChanged (linphone::Core::LogCollectionUploadState state, const std::string &info);
static QString getDownloadUrl ();
std::shared_ptr<linphone::Core> mCore;
std::shared_ptr<CoreHandlers> mHandlers; // It is used for handling linphone. Keep it to shared_ptr.
@ -237,6 +241,9 @@ private:
QMutex mMutexVideoRender;
static CoreManager *mInstance;
static CoreManagerGUI *mInstanceGUI;
static QSharedPointer<LinphoneThread> gLinphoneThread;
};
#endif // CORE_MANAGER_H_

View file

@ -0,0 +1,29 @@
#include "CoreManagerGUI.hpp"
#include "components/Components.hpp"
CoreManagerGUI::CoreManagerGUI(QObject * parent) : QObject(parent){
auto core = CoreManager::getInstance();
connect(core, &CoreManager::coreManagerInitialized, this, &CoreManagerGUI::coreManagerInitialized);
connect(core, &CoreManager::chatRoomModelCreated, this, &CoreManagerGUI::chatRoomModelCreated);
connect(core, &CoreManager::historyModelCreated, this, &CoreManagerGUI::historyModelCreated);
connect(core, &CoreManager::recorderManagerCreated, this, &CoreManagerGUI::recorderManagerCreated);
connect(core, &CoreManager::eventCountChanged, this, &CoreManagerGUI::eventCountChanged);
connect(core, &CoreManager::callLogsCountChanged, this, &CoreManagerGUI::callLogsCountChanged);
}
QString CoreManagerGUI::getDownloadUrl (){
return CoreManager::getDownloadUrl();
}
QString CoreManagerGUI::getVersion () const{
return CoreManager::getInstance()->getVersion();
}
int CoreManagerGUI::getEventCount () const{
return CoreManager::getInstance()->getEventCount();
}
int CoreManagerGUI::getCallLogsCount() const{
return CoreManager::getInstance()->getCallLogsCount();
}

View file

@ -0,0 +1,36 @@
#ifndef COREMANAGERGUI_H
#define COREMANAGERGUI_H
#include <QObject>
class ChatRoomModel;
class HistoryModel;
class RecorderManager;
class CoreManagerGUI : public QObject{
Q_OBJECT
Q_PROPERTY(QString version READ getVersion CONSTANT)
Q_PROPERTY(QString downloadUrl READ getDownloadUrl CONSTANT)
Q_PROPERTY(int eventCount READ getEventCount NOTIFY eventCountChanged)
Q_PROPERTY(int callLogsCount READ getCallLogsCount NOTIFY callLogsCountChanged)
public:
CoreManagerGUI(QObject * parent = nullptr);
QString getVersion () const;
int getEventCount () const;
int getCallLogsCount() const;
static QString getDownloadUrl ();
signals:
void coreManagerInitialized ();
void chatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void historyModelCreated (HistoryModel *historyModel);
void recorderManagerCreated(RecorderManager *recorderModel);
void logsUploaded (const QString &url);
void eventCountChanged ();
void callLogsCountChanged();
};
#endif // COREMANAGERGUI_H

View file

@ -0,0 +1,31 @@
#ifndef LINPHONEOBJECT_H
#define LINPHONEOBJECT_H
#include <QObject>
#include <QThread>
#include <QDebug>
template<class T>
class LinphoneObject : public QObject{
public:
LinphoneObject(QObject * parent = nullptr) : QObject(parent){}
bool isValid() const{
bool ok = true;
if(!gLinphoneThread)
gLinphoneThread = QThread::currentThread();
else if(gLinphoneThread != QThread::currentThread()){
ok = false;
qCritical() << "Current Linphone Object is being used in the wrong thread" << this;
}
return ok;
}
private:
T mLinphoneObject;
static QThread * gLinphoneThread;
};
template<class T>
QThread *LinphoneObject<T>::gLinphoneThread = nullptr;
#endif // LINPHONEOBJECT_H

View file

@ -0,0 +1,54 @@
#ifndef LINPHONETHREAD_HPP
#define LINPHONETHREAD_HPP
#include <QThread>
#include <QTimer>
class LinphoneThread : public QObject{
Q_OBJECT
public:
class LThread : public QThread{
public:
LThread(QObject * parent) : QThread(parent){}
virtual void run(){
exec();
}
};
LThread * mThread;
LinphoneThread(QObject * parent = nullptr) : QObject(nullptr){
mThread = new LThread(parent);
this->moveToThread(mThread);
connect(this, &LinphoneThread::startT, this, &LinphoneThread::startAsync, Qt::QueuedConnection);
connect(this, &LinphoneThread::stopT, this, &LinphoneThread::stopAsync, Qt::QueuedConnection);
}
void start(){
mThread->start();
}
void exit(){
mThread->exit();
}
void objectToThread(QObject * object){
object->moveToThread(mThread);
}
signals:
void startT(QTimer * timer);
void stopT(QTimer * timer);
public slots:
void startAsync(QTimer * timer){
timer->moveToThread(mThread);
timer->start();
}
void stopAsync(QTimer * timer){
timer->stop();
}
/*
template<class T>
void create(T t){
t->moveToThread(this);
}*/
};
#endif // LINPHONETHREAD_HPP