Browse Source

qt: daemon now operates in the background thread; added Quit GUI button

pull/522/head
hypnosis-i2p 9 years ago
parent
commit
1b35f68de9
  1. 10
      Daemon.cpp
  2. 14
      Daemon.h
  3. 45
      i2pd.cpp
  4. 83
      qt/i2pd_qt/DaemonQT.cpp
  5. 62
      qt/i2pd_qt/DaemonQT.h
  6. 4
      qt/i2pd_qt/android/AndroidManifest.xml
  7. 30
      qt/i2pd_qt/i2pd_qt.pro
  8. 24
      qt/i2pd_qt/i2pd_qt_gui.cpp
  9. 2
      qt/i2pd_qt/i2pd_qt_gui.h
  10. 51
      qt/i2pd_qt/mainwindow.cpp
  11. 18
      qt/i2pd_qt/mainwindow.h
  12. 60
      qt/i2pd_qt/mainwindow.ui

10
Daemon.cpp

@ -265,5 +265,13 @@ namespace i2p
return true; return true;
} }
}
bool DaemonQT::init(int argc, char* argv[])
{
#if 0
m_Impl = std::make_shared<DaemonQTImpl> (argc, argv);
#endif
return Daemon_Singleton::init(argc, argv);
}
}
} }

14
Daemon.h

@ -33,8 +33,10 @@ namespace i2p
#if defined(QT_GUI_LIB) // check if QT #if defined(QT_GUI_LIB) // check if QT
#define Daemon i2p::util::DaemonQT::Instance() #define Daemon i2p::util::DaemonQT::Instance()
class DaemonQTImpl; #if 0
class DaemonQT: public i2p::util::Daemon_Singleton class DaemonQTImpl;
#endif
class DaemonQT: public i2p::util::Daemon_Singleton
{ {
public: public:
@ -45,12 +47,14 @@ namespace i2p
} }
bool init(int argc, char* argv[]); bool init(int argc, char* argv[]);
void run (); #if 0
void run ();
private: private:
std::shared_ptr<DaemonQTImpl> m_Impl; std::shared_ptr<DaemonQTImpl> m_Impl;
}; #endif
};
#elif defined(_WIN32) #elif defined(_WIN32)
#define Daemon i2p::util::DaemonWin32::Instance() #define Daemon i2p::util::DaemonWin32::Instance()

45
i2pd.cpp

@ -1,15 +1,54 @@
#include <stdlib.h> #ifndef ANDROID
#include "Daemon.h" # include <stdlib.h>
# include "Daemon.h"
#else
# include "qt/i2pd_qt/i2pd_qt_gui.h"
# include <QMessageBox>
# include <QApplication>
# include "DaemonQT.h"
# include "mainwindow.h"
# include <QThread>
#endif
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
if (Daemon.init(argc, argv)) #ifdef ANDROID
//int result = runGUI(argc, argv);
//QMessageBox::information(0,"Debug","runGUI completed");
QApplication app(argc, argv);
qDebug("Initialising the daemon...");
bool daemonInitSuccess = i2p::util::DaemonQt::DaemonQTImpl::init(argc, argv);
if(!daemonInitSuccess) {
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
qDebug("Initialised, creating the main window...");
MainWindow w;
qDebug("Before main window.show()...");
w.show ();
int result;
{
i2p::util::DaemonQt::Controller daemonQtController;
qDebug("Starting the daemon...");
emit daemonQtController.startDaemon();
qDebug("Starting gui event loop...");
result = app.exec();
//QMessageBox::information(&w, "Debug", "exec finished");
}
i2p::util::DaemonQt::DaemonQTImpl::deinit();
//QMessageBox::information(&w, "Debug", "demon stopped");
//exit(result); //return from main() causes intermittent sigsegv bugs in some Androids. exit() is a workaround for this
qDebug("Exiting the application");
return result;
#else
if (Daemon.init(argc, argv))
{ {
if (Daemon.start()) if (Daemon.start())
Daemon.run (); Daemon.run ();
Daemon.stop(); Daemon.stop();
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
#endif
} }
#ifdef _WIN32 #ifdef _WIN32

83
qt/i2pd_qt/DaemonQT.cpp

@ -1,3 +1,83 @@
#include "DaemonQT.h"
#include "../../Daemon.h"
#include <QMutex>
#include <QMutexLocker>
namespace i2p
{
namespace util
{
namespace DaemonQt
{
void Worker::startDaemon() {
qDebug("Performing daemon start...");
DaemonQTImpl::start();
qDebug("Daemon started.");
emit resultReady();
}
void Worker::restartDaemon() {
qDebug("Performing daemon restart...");
DaemonQTImpl::restart();
qDebug("Daemon restarted.");
emit resultReady();
}
void Worker::stopDaemon() {
qDebug("Performing daemon stop...");
DaemonQTImpl::stop();
qDebug("Daemon stopped.");
emit resultReady();
}
Controller::Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller() {
qDebug("Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
qDebug("Waiting for daemon worker thread finished.");
if(i2p::util::DaemonQt::DaemonQTImpl::isRunning()) {
qDebug("Stopping the daemon...");
i2p::util::DaemonQt::DaemonQTImpl::stop();
qDebug("Stopped the daemon.");
}
}
static DaemonQTImpl::runningChangedCallback DaemonQTImpl_runningChanged;
static bool DaemonQTImpl_running;
static QMutex* mutex;
bool DaemonQTImpl::init(int argc, char* argv[]){mutex=new QMutex(QMutex::Recursive);setRunningCallback(0);DaemonQTImpl_running=false;return Daemon.init(argc,argv);}
void DaemonQTImpl::deinit(){delete mutex;}
void DaemonQTImpl::start(){QMutexLocker locker(mutex);setRunning(true);Daemon.start();}
void DaemonQTImpl::stop(){QMutexLocker locker(mutex);Daemon.stop();setRunning(false);}
void DaemonQTImpl::restart(){QMutexLocker locker(mutex);stop();start();}
void DaemonQTImpl::setRunningCallback(runningChangedCallback cb){DaemonQTImpl_runningChanged=cb;}
bool DaemonQTImpl::isRunning(){return DaemonQTImpl_running;}
void DaemonQTImpl::setRunning(bool newValue){
bool oldValue = DaemonQTImpl_running;
if(oldValue!=newValue) {
DaemonQTImpl_running = newValue;
if(DaemonQTImpl_runningChanged!=0)DaemonQTImpl_runningChanged();
}
}
}
}
}
#if 0
#include <memory> #include <memory>
#include "mainwindow.h" #include "mainwindow.h"
#include <QApplication> #include <QApplication>
@ -19,7 +99,7 @@ namespace util
void Run () void Run ()
{ {
MainWindow w; MainWindow w(m_App);
w.show (); w.show ();
m_App.exec(); m_App.exec();
} }
@ -62,3 +142,4 @@ namespace util
} }
} }
} }
#endif

62
qt/i2pd_qt/DaemonQT.h

@ -1,4 +1,66 @@
#ifndef DAEMONQT_H #ifndef DAEMONQT_H
#define DAEMONQT_H #define DAEMONQT_H
#include <QObject>
#include <QThread>
namespace i2p
{
namespace util
{
namespace DaemonQt
{
class Worker : public QObject
{
Q_OBJECT
public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();
signals:
void resultReady();
};
class DaemonQTImpl
{
public:
typedef void (*runningChangedCallback)();
/**
* @brief init
* @param argc
* @param argv
* @return success
*/
bool static init(int argc, char* argv[]);
void static deinit();
void static start();
void static stop();
void static restart();
void static setRunningCallback(runningChangedCallback cb);
bool static isRunning();
private:
void static setRunning(bool running);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller();
~Controller();
public slots:
void handleResults(){}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
}
}
}
#endif // DAEMONQT_H #endif // DAEMONQT_H

4
qt/i2pd_qt/android/AndroidManifest.xml

@ -1,6 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.8.0" android:versionCode="1" android:installLocation="auto"> <manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.8.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="i2pd">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
@ -46,7 +46,7 @@
<!-- auto screen scale factor --> <!-- auto screen scale factor -->
</activity> </activity>
</application> </application>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.

30
qt/i2pd_qt/i2pd_qt.pro

@ -14,7 +14,7 @@ QMAKE_CXXFLAGS *= -std=c++11
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt
# git clone https://github.com/PuerpleI2P/android-ifaddrs.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own # change to your own
BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt
OPENSSL_PATH = /mnt/media/android/OpenSSL-for-Android-Prebuilt OPENSSL_PATH = /mnt/media/android/OpenSSL-for-Android-Prebuilt
@ -66,9 +66,10 @@ SOURCES += DaemonQT.cpp\
../../TunnelPool.cpp \ ../../TunnelPool.cpp \
../../util.cpp \ ../../util.cpp \
../../i2pd.cpp \ ../../i2pd.cpp \
$$IFADDRS_PATH/ifaddrs.c $$IFADDRS_PATH/ifaddrs.c \
i2pd_qt_gui.cpp
HEADERS += mainwindow.h \ HEADERS += DaemonQT.h mainwindow.h \
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
../../AddressBook.h \ ../../AddressBook.h \
../../api.h \ ../../api.h \
@ -119,7 +120,9 @@ HEADERS += mainwindow.h \
../../TunnelPool.h \ ../../TunnelPool.h \
../../util.h \ ../../util.h \
../../version.h \ ../../version.h \
$$IFADDRS_PATH/ifaddrs.h $$IFADDRS_PATH/ifaddrs.h \
i2pd_qt_gui.h
FORMS += mainwindow.ui FORMS += mainwindow.ui
@ -135,11 +138,14 @@ DEFINES += ANDROID=1
INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
$$OPENSSL_PATH/openssl-1.0.2/include \ $$OPENSSL_PATH/openssl-1.0.2/include \
$$IFADDRS_PATH $$IFADDRS_PATH
DISTFILES += \
android/AndroidManifest.xml
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
equals(ANDROID_TARGET_ARCH, armeabi-v7a){ equals(ANDROID_TARGET_ARCH, armeabi-v7a){
# http://stackoverflow.com/a/30235934/529442 # http://stackoverflow.com/a/30235934/529442
LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libssl.a \
-lboost_system-gcc-mt-1_53 \ -lboost_system-gcc-mt-1_53 \
-lboost_date_time-gcc-mt-1_53 \ -lboost_date_time-gcc-mt-1_53 \
-lboost_filesystem-gcc-mt-1_53 \ -lboost_filesystem-gcc-mt-1_53 \
@ -157,8 +163,6 @@ ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0
equals(ANDROID_TARGET_ARCH, x86){ equals(ANDROID_TARGET_ARCH, x86){
# http://stackoverflow.com/a/30235934/529442 # http://stackoverflow.com/a/30235934/529442
LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libssl.a \
-lboost_system-gcc-mt-1_53 \ -lboost_system-gcc-mt-1_53 \
-lboost_date_time-gcc-mt-1_53 \ -lboost_date_time-gcc-mt-1_53 \
-lboost_filesystem-gcc-mt-1_53 \ -lboost_filesystem-gcc-mt-1_53 \
@ -180,13 +184,3 @@ message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
} }
unix:!macx:
DISTFILES += \
android/AndroidManifest.xml
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

24
qt/i2pd_qt/i2pd_qt_gui.cpp

@ -0,0 +1,24 @@
#if 0
#include "i2pd_qt_gui.h"
#include <QApplication>
#include <QMessageBox>
#include "mainwindow.h"
#include "DaemonQT.h"
int runGUI( int argc, char* argv[] ) {
QApplication app(argc, argv);
bool daemonInitSuccess = i2p::util::DaemonQTImpl::init(argc, argv);
if(!daemonInitSuccess) {
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
MainWindow w;
w.show ();
i2p::util::DaemonQTImpl::start();
int result = app.exec();
//QMessageBox::information(&w, "Debug", "exec finished");
i2p::util::DaemonQTImpl::stop();
//QMessageBox::information(&w, "Debug", "demon stopped");
return result;
}
#endif

2
qt/i2pd_qt/i2pd_qt_gui.h

@ -1,4 +1,6 @@
#ifndef IQPD_QT_GUI_H #ifndef IQPD_QT_GUI_H
#define IQPD_QT_GUI_H #define IQPD_QT_GUI_H
int runGUI( int argc, char* argv[] );
#endif // IQPD_QT_GUI_H #endif // IQPD_QT_GUI_H

51
qt/i2pd_qt/mainwindow.cpp

@ -1,14 +1,55 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" //#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent)/*,
ui(new Ui::MainWindow) ui(new Ui::MainWindow)*/
{ {
ui->setupUi(this); //ui->setupUi(this);
if (objectName().isEmpty())
setObjectName(QStringLiteral("MainWindow"));
resize(800, 480);
centralWidget = new QWidget(this);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
verticalLayoutWidget = new QWidget(centralWidget);
verticalLayoutWidget->setObjectName(QStringLiteral("verticalLayoutWidget"));
//verticalLayoutWidget->setGeometry(QRect(10, 20, 771, 441));
verticalLayout1 = new QVBoxLayout(verticalLayoutWidget);
verticalLayout1->setSpacing(6);
verticalLayout1->setContentsMargins(11, 11, 11, 11);
verticalLayout1->setObjectName(QStringLiteral("verticalLayout1"));
verticalLayout1->setContentsMargins(0, 0, 0, 0);
quitButton = new QPushButton(verticalLayoutWidget);
quitButton->setObjectName(QStringLiteral("quitButton"));
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(quitButton->sizePolicy().hasHeightForWidth());
quitButton->setSizePolicy(sizePolicy);
verticalLayout1->addWidget(quitButton);
setCentralWidget(centralWidget);
setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
quitButton->setText(QApplication::translate("MainWindow", "Quit", 0));
QObject::connect(quitButton, SIGNAL(released()), this, SLOT(handleQuitButton()));
//QMetaObject::connectSlotsByName(this);
}
void MainWindow::handleQuitButton() {
qDebug("Quit pressed. Hiding the main window");
close();
QApplication::instance()->quit();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete ui; qDebug("Destroying main window");
//QMessageBox::information(0, "Debug", "mw destructor 1");
//delete ui;
//QMessageBox::information(0, "Debug", "mw destructor 2");
} }

18
qt/i2pd_qt/mainwindow.h

@ -2,6 +2,16 @@
#define MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow> #include <QMainWindow>
#include <QPushButton>
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -15,8 +25,14 @@ public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
~MainWindow(); ~MainWindow();
private slots:
void handleQuitButton();
private: private:
Ui::MainWindow *ui; QWidget *centralWidget;
QWidget *verticalLayoutWidget;
QVBoxLayout *verticalLayout1;
QPushButton *quitButton;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

60
qt/i2pd_qt/mainwindow.ui

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>MainWindow</class> <class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow" > <widget class="QMainWindow" name="MainWindow">
<property name="geometry" > <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
@ -9,13 +10,58 @@
<height>480</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle">
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralWidget" /> <widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>771</width>
<height>441</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout1">
<item>
<widget class="QPushButton" name="quitButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Quit</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget> </widget>
<layoutDefault spacing="6" margin="11" /> <layoutdefault spacing="6" margin="11"/>
<pixmapfunction></pixmapfunction>
<resources/> <resources/>
<connections/> <connections>
<connection>
<sender>quitButton</sender>
<signal>released()</signal>
<receiver>MainWindow</receiver>
<slot>handleQuitButton()</slot>
<hints>
<hint type="sourcelabel">
<x>384</x>
<y>244</y>
</hint>
<hint type="destinationlabel">
<x>373</x>
<y>419</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>handleQuitButton()</slot>
</slots>
</ui> </ui>

Loading…
Cancel
Save