mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
docs(core): Change comment style
This commit is contained in:
parent
1c547fc73f
commit
2696a9265a
|
@ -104,6 +104,9 @@ Core::~Core()
|
|||
deadifyTox();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the global widget's Core instance
|
||||
*/
|
||||
Core* Core::getInstance()
|
||||
{
|
||||
return Nexus::getCore();
|
||||
|
@ -217,6 +220,9 @@ void Core::makeTox(QByteArray savedata)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Initializes the core, must be called before anything else
|
||||
*/
|
||||
void Core::start()
|
||||
{
|
||||
bool isNewProfile = profile.isNewProfile();
|
||||
|
@ -329,6 +335,9 @@ void Core::start()
|
|||
*/
|
||||
#define CORE_DISCONNECT_TOLERANCE 30
|
||||
|
||||
/**
|
||||
@brief Processes toxcore events and ensure we stay connected, called by its own timer
|
||||
*/
|
||||
void Core::process()
|
||||
{
|
||||
if (!isReady())
|
||||
|
@ -383,6 +392,9 @@ bool Core::checkConnection()
|
|||
return isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Connects us to the Tox network
|
||||
*/
|
||||
void Core::bootstrapDht()
|
||||
{
|
||||
const Settings& s = Settings::getInstance();
|
||||
|
@ -720,6 +732,9 @@ void Core::removeGroup(int groupId, bool fake)
|
|||
av->leaveGroupCall(groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns our username, or an empty string on failure
|
||||
*/
|
||||
QString Core::getUsername() const
|
||||
{
|
||||
QString sname;
|
||||
|
@ -769,6 +784,9 @@ void Core::setAvatar(const QByteArray& data)
|
|||
AvatarBroadcaster::enableAutoBroadcast();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns our Tox ID
|
||||
*/
|
||||
ToxId Core::getSelfId() const
|
||||
{
|
||||
uint8_t friendAddress[TOX_ADDRESS_SIZE] = {0};
|
||||
|
@ -776,6 +794,9 @@ ToxId Core::getSelfId() const
|
|||
return ToxId(CFriendAddress::toString(friendAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns our public and private keys
|
||||
*/
|
||||
QPair<QByteArray, QByteArray> Core::getKeypair() const
|
||||
{
|
||||
QPair<QByteArray, QByteArray> keypair;
|
||||
|
@ -790,6 +811,9 @@ QPair<QByteArray, QByteArray> Core::getKeypair() const
|
|||
return keypair;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns our status message, or an empty string on failure
|
||||
*/
|
||||
QString Core::getStatusMessage() const
|
||||
{
|
||||
QString sname;
|
||||
|
@ -803,6 +827,9 @@ QString Core::getStatusMessage() const
|
|||
return sname;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns our user status
|
||||
*/
|
||||
Status Core::getStatus() const
|
||||
{
|
||||
return (Status)tox_self_get_status(tox);
|
||||
|
@ -867,6 +894,9 @@ QString Core::sanitize(QString name)
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the unencrypted tox save data
|
||||
*/
|
||||
QByteArray Core::getToxSaveData()
|
||||
{
|
||||
uint32_t fileSize = tox_get_savedata_size(tox);
|
||||
|
@ -925,6 +955,9 @@ void Core::checkLastOnline(uint32_t friendId) {
|
|||
emit friendLastSeenChanged(friendId, QDateTime::fromTime_t(lastOnline));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the list of friendIds in our friendlist, an empty list on error
|
||||
*/
|
||||
QVector<uint32_t> Core::getFriendList() const
|
||||
{
|
||||
QVector<uint32_t> friends;
|
||||
|
@ -933,11 +966,17 @@ QVector<uint32_t> Core::getFriendList() const
|
|||
return friends;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Return the number of peers in the group chat on success, or -1 on failure
|
||||
*/
|
||||
int Core::getGroupNumberPeers(int groupId) const
|
||||
{
|
||||
return tox_group_number_peers(tox, groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the name of a peer of a group
|
||||
*/
|
||||
QString Core::getGroupPeerName(int groupId, int peerId) const
|
||||
{
|
||||
QString name;
|
||||
|
@ -952,6 +991,9 @@ QString Core::getGroupPeerName(int groupId, int peerId) const
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the public key of a peer of a group
|
||||
*/
|
||||
ToxId Core::getGroupPeerToxId(int groupId, int peerId) const
|
||||
{
|
||||
ToxId peerToxId;
|
||||
|
@ -968,6 +1010,9 @@ ToxId Core::getGroupPeerToxId(int groupId, int peerId) const
|
|||
return peerToxId;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the names of the peers of a group
|
||||
*/
|
||||
QList<QString> Core::getGroupPeerNames(int groupId) const
|
||||
{
|
||||
QList<QString> names;
|
||||
|
@ -999,6 +1044,9 @@ QList<QString> Core::getGroupPeerNames(int groupId) const
|
|||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Accept a groupchat invite
|
||||
*/
|
||||
int Core::joinGroupchat(int32_t friendnumber, uint8_t type, const uint8_t* friend_group_public_key,uint16_t length) const
|
||||
{
|
||||
if (type == TOX_GROUPCHAT_TYPE_TEXT)
|
||||
|
@ -1020,6 +1068,9 @@ int Core::joinGroupchat(int32_t friendnumber, uint8_t type, const uint8_t* frien
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Quit a groupchat
|
||||
*/
|
||||
void Core::quitGroupChat(int groupId) const
|
||||
{
|
||||
tox_del_groupchat(tox, groupId);
|
||||
|
@ -1052,11 +1103,17 @@ int Core::createGroup(uint8_t type)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Checks if a friend is online. Unknown friends are considered offline.
|
||||
*/
|
||||
bool Core::isFriendOnline(uint32_t friendId) const
|
||||
{
|
||||
return tox_friend_get_connection_status(tox, friendId, nullptr) != TOX_CONNECTION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Checks if we have a friend by address
|
||||
*/
|
||||
bool Core::hasFriendWithAddress(const QString &addr) const
|
||||
{
|
||||
// Valid length check
|
||||
|
@ -1069,6 +1126,9 @@ bool Core::hasFriendWithAddress(const QString &addr) const
|
|||
return hasFriendWithPublicKey(pubkey);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Checks if we have a friend by public key
|
||||
*/
|
||||
bool Core::hasFriendWithPublicKey(const QString &pubkey) const
|
||||
{
|
||||
// Valid length check
|
||||
|
@ -1100,6 +1160,9 @@ bool Core::hasFriendWithPublicKey(const QString &pubkey) const
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the full address if known, or public key of a friend
|
||||
*/
|
||||
QString Core::getFriendAddress(uint32_t friendNumber) const
|
||||
{
|
||||
QString id = getFriendPublicKey(friendNumber);
|
||||
|
@ -1110,6 +1173,9 @@ QString Core::getFriendAddress(uint32_t friendNumber) const
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the public key part of the ToxID only
|
||||
*/
|
||||
QString Core::getFriendPublicKey(uint32_t friendNumber) const
|
||||
{
|
||||
uint8_t rawid[TOX_PUBLIC_KEY_SIZE];
|
||||
|
@ -1124,6 +1190,9 @@ QString Core::getFriendPublicKey(uint32_t friendNumber) const
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get the username of a friend
|
||||
*/
|
||||
QString Core::getFriendUsername(uint32_t friendnumber) const
|
||||
{
|
||||
size_t namesize = tox_friend_get_name_size(tox, friendnumber, nullptr);
|
||||
|
@ -1197,6 +1266,9 @@ QString Core::getPeerName(const ToxId& id) const
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Most of the API shouldn't be used until Core is ready, call start() first
|
||||
*/
|
||||
bool Core::isReady()
|
||||
{
|
||||
return av && av->getToxAv() && tox && ready;
|
||||
|
@ -1211,6 +1283,9 @@ void Core::setNospam(uint32_t nospam)
|
|||
emit idSet(getSelfId().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the unencrypted tox save data
|
||||
*/
|
||||
void Core::killTimers(bool onlyStop)
|
||||
{
|
||||
assert(QThread::currentThread() == coreThread);
|
||||
|
@ -1223,6 +1298,10 @@ void Core::killTimers(bool onlyStop)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Reinitialized the core.
|
||||
@warning Must be called from the Core thread, with the GUI thread ready to process events.
|
||||
*/
|
||||
void Core::reset()
|
||||
{
|
||||
assert(QThread::currentThread() == coreThread);
|
||||
|
|
|
@ -46,7 +46,7 @@ class Core : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit Core(QThread* coreThread, Profile& profile);
|
||||
static Core* getInstance(); ///< Returns the global widget's Core instance
|
||||
static Core* getInstance();
|
||||
CoreAV* getAv();
|
||||
~Core();
|
||||
|
||||
|
@ -59,41 +59,42 @@ public:
|
|||
|
||||
QString getPeerName(const ToxId& id) const;
|
||||
|
||||
QVector<uint32_t> getFriendList() const; ///< Returns the list of friendIds in our friendlist, an empty list on error
|
||||
int getGroupNumberPeers(int groupId) const; ///< Return the number of peers in the group chat on success, or -1 on failure
|
||||
QString getGroupPeerName(int groupId, int peerId) const; ///< Get the name of a peer of a group
|
||||
ToxId getGroupPeerToxId(int groupId, int peerId) const; ///< Get the public key of a peer of a group
|
||||
QList<QString> getGroupPeerNames(int groupId) const; ///< Get the names of the peers of a group
|
||||
QString getFriendAddress(uint32_t friendNumber) const; ///< Get the full address if known, or public key of a friend
|
||||
QString getFriendPublicKey(uint32_t friendNumber) const; ///< Get the public key part of the ToxID only
|
||||
QString getFriendUsername(uint32_t friendNumber) const; ///< Get the username of a friend
|
||||
bool isFriendOnline(uint32_t friendId) const; ///< Check if a friend is online. Unknown friends are considered offline.
|
||||
bool hasFriendWithAddress(const QString &addr) const; ///< Check if we have a friend by address
|
||||
bool hasFriendWithPublicKey(const QString &pubkey) const; ///< Check if we have a friend by public key
|
||||
int joinGroupchat(int32_t friendId, uint8_t type, const uint8_t* pubkey,uint16_t length) const; ///< Accept a groupchat invite
|
||||
void quitGroupChat(int groupId) const; ///< Quit a groupchat
|
||||
QVector<uint32_t> getFriendList() const;
|
||||
int getGroupNumberPeers(int groupId) const;
|
||||
QString getGroupPeerName(int groupId, int peerId) const;
|
||||
ToxId getGroupPeerToxId(int groupId, int peerId) const;
|
||||
QList<QString> getGroupPeerNames(int groupId) const;
|
||||
QString getFriendAddress(uint32_t friendNumber) const;
|
||||
QString getFriendPublicKey(uint32_t friendNumber) const;
|
||||
QString getFriendUsername(uint32_t friendNumber) const;
|
||||
|
||||
QString getUsername() const; ///< Returns our username, or an empty string on failure
|
||||
Status getStatus() const; ///< Returns our user status
|
||||
QString getStatusMessage() const; ///< Returns our status message, or an empty string on failure
|
||||
ToxId getSelfId() const; ///< Returns our Tox ID
|
||||
QPair<QByteArray, QByteArray> getKeypair() const; ///< Returns our public and private keys
|
||||
bool isFriendOnline(uint32_t friendId) const;
|
||||
bool hasFriendWithAddress(const QString &addr) const;
|
||||
bool hasFriendWithPublicKey(const QString &pubkey) const;
|
||||
int joinGroupchat(int32_t friendId, uint8_t type, const uint8_t* pubkey,uint16_t length) const;
|
||||
void quitGroupChat(int groupId) const;
|
||||
|
||||
QString getUsername() const;
|
||||
Status getStatus() const;
|
||||
QString getStatusMessage() const;
|
||||
ToxId getSelfId() const;
|
||||
QPair<QByteArray, QByteArray> getKeypair() const;
|
||||
|
||||
static std::unique_ptr<TOX_PASS_KEY> createPasskey(const QString &password, uint8_t* salt = nullptr);
|
||||
static QByteArray encryptData(const QByteArray& data, const TOX_PASS_KEY& encryptionKey);
|
||||
static QByteArray encryptData(const QByteArray& data); ///< Uses the default profile's key
|
||||
static QByteArray encryptData(const QByteArray& data);
|
||||
static QByteArray decryptData(const QByteArray& data, const TOX_PASS_KEY &encryptionKey);
|
||||
static QByteArray decryptData(const QByteArray& data); ///< Uses the default profile's key
|
||||
static QByteArray decryptData(const QByteArray& data);
|
||||
|
||||
bool isReady(); ///< Most of the API shouldn't be used until Core is ready, call start() first
|
||||
bool isReady();
|
||||
|
||||
public slots:
|
||||
void start(); ///< Initializes the core, must be called before anything else
|
||||
void reset(); ///< Reinitialized the core. Must be called from the Core thread, with the GUI thread ready to process events.
|
||||
void process(); ///< Processes toxcore events and ensure we stay connected, called by its own timer
|
||||
void bootstrapDht(); ///< Connects us to the Tox network
|
||||
void start();
|
||||
void reset();
|
||||
void process();
|
||||
void bootstrapDht();
|
||||
|
||||
QByteArray getToxSaveData(); ///< Returns the unencrypted tox save data
|
||||
QByteArray getToxSaveData();
|
||||
|
||||
void acceptFriendRequest(const QString& userId);
|
||||
void requestFriendship(const QString& friendAddress, const QString& message);
|
||||
|
@ -225,7 +226,7 @@ private:
|
|||
void deadifyTox();
|
||||
|
||||
private slots:
|
||||
void killTimers(bool onlyStop); ///< Must only be called from the Core thread
|
||||
void killTimers(bool onlyStop);
|
||||
|
||||
private:
|
||||
Tox* tox;
|
||||
|
|
|
@ -31,7 +31,52 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
|
||||
/**
|
||||
@fn void CoreAV::avInvite(uint32_t friendId, bool video)
|
||||
@brief Sent when a friend calls us.
|
||||
@param friendId Id of friend in call list.
|
||||
@param video False if chat is audio only, true audio and video.
|
||||
|
||||
@fn void CoreAV::avStart(uint32_t friendId, bool video)
|
||||
@brief Sent when a call we initiated has started.
|
||||
@param friendId Id of friend in call list.
|
||||
@param video False if chat is audio only, true audio and video.
|
||||
|
||||
@fn void CoreAV::avEnd(uint32_t friendId)
|
||||
@brief Sent when a call was ended by the peer.
|
||||
@param friendId Id of friend in call list.
|
||||
*/
|
||||
|
||||
/**
|
||||
@var CoreAV::AUDIO_DEFAULT_BITRATE
|
||||
@brief In kb/s. More than enough for Opus.
|
||||
|
||||
@var CoreAV::VIDEO_DEFAULT_BITRATE
|
||||
@brief Picked at random by fair dice roll.
|
||||
*/
|
||||
|
||||
/**
|
||||
@var std::atomic_flag CoreAV::threadSwitchLock
|
||||
@brief This flag is to be acquired before switching in a blocking way between the UI and CoreAV thread.
|
||||
|
||||
The CoreAV thread must have priority for the flag, other threads should back off or release it quickly.
|
||||
CoreAV needs to interface with three threads, the toxcore/Core thread that fires non-payload
|
||||
toxav callbacks, the toxav/CoreAV thread that fires AV payload callbacks and manages
|
||||
most of CoreAV's members, and the UI thread, which calls our [start/answer/cancel]Call functions
|
||||
and which we call via signals.
|
||||
When the UI calls us, we switch from the UI thread to the CoreAV thread to do the processing,
|
||||
when toxcore fires a non-payload av callback, we do the processing in the CoreAV thread and then
|
||||
switch to the UI thread to send it a signal. Both switches block both threads, so this would deadlock.
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Maps friend IDs to ToxFriendCall.
|
||||
*/
|
||||
IndexedList<ToxFriendCall> CoreAV::calls;
|
||||
|
||||
/**
|
||||
@brief Maps group IDs to ToxGroupCalls.
|
||||
*/
|
||||
IndexedList<ToxGroupCall> CoreAV::groupCalls;
|
||||
|
||||
using namespace std;
|
||||
|
@ -76,6 +121,9 @@ const ToxAV *CoreAV::getToxAv() const
|
|||
return toxav;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Starts the CoreAV main loop that calls toxav's main loop
|
||||
*/
|
||||
void CoreAV::start()
|
||||
{
|
||||
// Timers can only be touched from their own thread
|
||||
|
@ -84,6 +132,9 @@ void CoreAV::start()
|
|||
iterateTimer->start();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Stops the main loop
|
||||
*/
|
||||
void CoreAV::stop()
|
||||
{
|
||||
// Timers can only be touched from their own thread
|
||||
|
@ -92,6 +143,9 @@ void CoreAV::stop()
|
|||
iterateTimer->stop();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Calls itself blocking queued on the coreav thread
|
||||
*/
|
||||
void CoreAV::killTimerFromThread()
|
||||
{
|
||||
// Timers can only be touched from their own thread
|
||||
|
@ -106,6 +160,11 @@ void CoreAV::process()
|
|||
iterateTimer->start(toxav_iteration_interval(toxav));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check, that and calls are active now
|
||||
@return True is any calls are currently active, False otherwise
|
||||
@note A call about to start is not yet active
|
||||
*/
|
||||
bool CoreAV::anyActiveCalls()
|
||||
{
|
||||
return !calls.isEmpty();
|
||||
|
@ -234,6 +293,15 @@ void CoreAV::timeoutCall(uint32_t friendNum)
|
|||
emit avEnd(friendNum);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Send audio frame to a friend
|
||||
@param callId Id of friend in call list.
|
||||
@param pcm An array of audio samples (Pulse-code modulation).
|
||||
@param samples Number of samples in this frame.
|
||||
@param chans Number of audio channels.
|
||||
@param rate Audio sampling rate used in this frame.
|
||||
@return False only on error, but not if there's nothing to send.
|
||||
*/
|
||||
bool CoreAV::sendCallAudio(uint32_t callId, const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate)
|
||||
{
|
||||
if (!calls.contains(callId))
|
||||
|
@ -378,6 +446,11 @@ void CoreAV::groupCallCallback(void* tox, int group, int peer,
|
|||
sample_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get a call's video source.
|
||||
@param friendNum Id of friend in call list.
|
||||
@return Video surface to show
|
||||
*/
|
||||
VideoSource *CoreAV::getVideoSourceFromCall(int friendNum)
|
||||
{
|
||||
if (!calls.contains(friendNum))
|
||||
|
@ -389,6 +462,11 @@ VideoSource *CoreAV::getVideoSourceFromCall(int friendNum)
|
|||
return calls[friendNum].videoSource;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Starts a call in an existing AV groupchat.
|
||||
@note Call from the GUI thread.
|
||||
@param groupId Id of group to join
|
||||
*/
|
||||
void CoreAV::joinGroupCall(int groupId)
|
||||
{
|
||||
qDebug() << QString("Joining group call %1").arg(groupId);
|
||||
|
@ -397,6 +475,11 @@ void CoreAV::joinGroupCall(int groupId)
|
|||
call->inactive = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Will not leave the group, just stop the call.
|
||||
@note Call from the GUI thread.
|
||||
@param groupId Id of group to leave
|
||||
*/
|
||||
void CoreAV::leaveGroupCall(int groupId)
|
||||
{
|
||||
qDebug() << QString("Leaving group call %1").arg(groupId);
|
||||
|
@ -450,11 +533,19 @@ bool CoreAV::isGroupCallVolEnabled(int groupId) const
|
|||
return !groupCalls[groupId].muteVol;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check, that group has audio or video stream
|
||||
@param groupId Id of group to check
|
||||
@return True for AV groups, false for text-only groups
|
||||
*/
|
||||
bool CoreAV::isGroupAvEnabled(int groupId) const
|
||||
{
|
||||
return tox_group_get_type(Core::getInstance()->tox, groupId) == TOX_GROUPCHAT_TYPE_AV;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Forces to regenerate each call's audio sources.
|
||||
*/
|
||||
void CoreAV::invalidateCallSources()
|
||||
{
|
||||
for (ToxGroupCall& call : groupCalls)
|
||||
|
@ -468,6 +559,10 @@ void CoreAV::invalidateCallSources()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Signal to all peers that we're not sending video anymore.
|
||||
@note The next frame sent cancels this.
|
||||
*/
|
||||
void CoreAV::sendNoVideo()
|
||||
{
|
||||
// We don't change the audio bitrate, but we signal that we're not sending video anymore
|
||||
|
|
|
@ -46,26 +46,25 @@ public:
|
|||
|
||||
const ToxAV* getToxAv() const;
|
||||
|
||||
bool anyActiveCalls(); ///< true is any calls are currently active (note: a call about to start is not yet active)
|
||||
bool anyActiveCalls();
|
||||
bool isCallVideoEnabled(uint32_t friendNum);
|
||||
/// Returns false only on error, but not if there's nothing to send
|
||||
bool sendCallAudio(uint32_t friendNum, const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate);
|
||||
void sendCallVideo(uint32_t friendNum, std::shared_ptr<VideoFrame> frame);
|
||||
bool sendGroupCallAudio(int groupNum, const int16_t *pcm, size_t samples, uint8_t chans, uint32_t rate);
|
||||
|
||||
VideoSource* getVideoSourceFromCall(int callNumber); ///< Get a call's video source
|
||||
void invalidateCallSources(); ///< Forces to regenerate each call's audio sources
|
||||
void sendNoVideo(); ///< Signal to all peers that we're not sending video anymore. The next frame sent cancels this.
|
||||
VideoSource* getVideoSourceFromCall(int callNumber);
|
||||
void invalidateCallSources();
|
||||
void sendNoVideo();
|
||||
|
||||
void joinGroupCall(int groupNum); ///< Starts a call in an existing AV groupchat. Call from the GUI thread.
|
||||
void leaveGroupCall(int groupNum); ///< Will not leave the group, just stop the call. Call from the GUI thread.
|
||||
void joinGroupCall(int groupNum);
|
||||
void leaveGroupCall(int groupNum);
|
||||
void disableGroupCallMic(int groupNum);
|
||||
void disableGroupCallVol(int groupNum);
|
||||
void enableGroupCallMic(int groupNum);
|
||||
void enableGroupCallVol(int groupNum);
|
||||
bool isGroupCallMicEnabled(int groupNum) const;
|
||||
bool isGroupCallVolEnabled(int groupNum) const;
|
||||
bool isGroupAvEnabled(int groupNum) const; ///< True for AV groups, false for text-only groups
|
||||
bool isGroupAvEnabled(int groupNum) const;
|
||||
|
||||
void micMuteToggle(uint32_t friendNum);
|
||||
void volMuteToggle(uint32_t friendNum);
|
||||
|
@ -80,21 +79,19 @@ public slots:
|
|||
bool answerCall(uint32_t friendNum);
|
||||
bool cancelCall(uint32_t friendNum);
|
||||
void timeoutCall(uint32_t friendNum);
|
||||
/// Starts the CoreAV main loop that calls toxav's main loop
|
||||
void start();
|
||||
/// Stops the main loop
|
||||
void stop();
|
||||
|
||||
signals:
|
||||
void avInvite(uint32_t friendId, bool video); ///< Sent when a friend calls us
|
||||
void avStart(uint32_t friendId, bool video); ///< Sent when a call we initiated has started
|
||||
void avEnd(uint32_t friendId); ///< Sent when a call was ended by the peer
|
||||
void avInvite(uint32_t friendId, bool video);
|
||||
void avStart(uint32_t friendId, bool video);
|
||||
void avEnd(uint32_t friendId);
|
||||
|
||||
private slots:
|
||||
static void callCallback(ToxAV *toxAV, uint32_t friendNum, bool audio, bool video, void* self);
|
||||
static void stateCallback(ToxAV *, uint32_t friendNum, uint32_t state, void* self);
|
||||
static void bitrateCallback(ToxAV *toxAV, uint32_t friendNum, uint32_t arate, uint32_t vrate, void* self);
|
||||
void killTimerFromThread(); ///< Calls itself blocking queued on the coreav thread
|
||||
void killTimerFromThread();
|
||||
|
||||
private:
|
||||
void process();
|
||||
|
@ -105,27 +102,15 @@ private:
|
|||
int32_t ystride, int32_t ustride, int32_t vstride, void* self);
|
||||
|
||||
private:
|
||||
static constexpr uint32_t AUDIO_DEFAULT_BITRATE = 64; ///< In kb/s. More than enough for Opus.
|
||||
static constexpr uint32_t VIDEO_DEFAULT_BITRATE = 6144; ///< Picked at random by fair dice roll.
|
||||
static constexpr uint32_t AUDIO_DEFAULT_BITRATE = 64;
|
||||
static constexpr uint32_t VIDEO_DEFAULT_BITRATE = 6144;
|
||||
|
||||
private:
|
||||
ToxAV* toxav;
|
||||
std::unique_ptr<QThread> coreavThread;
|
||||
std::unique_ptr<QTimer> iterateTimer;
|
||||
static IndexedList<ToxFriendCall> calls;
|
||||
static IndexedList<ToxGroupCall> groupCalls; // Maps group IDs to ToxGroupCalls
|
||||
/**
|
||||
* This flag is to be acquired before switching in a blocking way between the UI and CoreAV thread.
|
||||
* The CoreAV thread must have priority for the flag, other threads should back off or release it quickly.
|
||||
*
|
||||
* CoreAV needs to interface with three threads, the toxcore/Core thread that fires non-payload
|
||||
* toxav callbacks, the toxav/CoreAV thread that fires AV payload callbacks and manages
|
||||
* most of CoreAV's members, and the UI thread, which calls our [start/answer/cancel]Call functions
|
||||
* and which we call via signals.
|
||||
* When the UI calls us, we switch from the UI thread to the CoreAV thread to do the processing,
|
||||
* when toxcore fires a non-payload av callback, we do the processing in the CoreAV thread and then
|
||||
* switch to the UI thread to send it a signal. Both switches block both threads, so this would deadlock.
|
||||
*/
|
||||
static IndexedList<ToxGroupCall> groupCalls;
|
||||
std::atomic_flag threadSwitchLock;
|
||||
|
||||
friend class Audio;
|
||||
|
|
|
@ -51,6 +51,12 @@ std::unique_ptr<TOX_PASS_KEY> Core::createPasskey(const QString& password, uint8
|
|||
return encryptionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Encrypts data.
|
||||
@note Uses the default profile's key.
|
||||
@param data Data to encrypt.
|
||||
@return Encrypted data.
|
||||
*/
|
||||
QByteArray Core::encryptData(const QByteArray &data)
|
||||
{
|
||||
return encryptData(data, Nexus::getProfile()->getPasskey());
|
||||
|
@ -68,6 +74,12 @@ QByteArray Core::encryptData(const QByteArray& data, const TOX_PASS_KEY& encrypt
|
|||
return QByteArray(reinterpret_cast<char*>(encrypted), data.size() + TOX_PASS_ENCRYPTION_EXTRA_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Decrypts data.
|
||||
@note Uses the default profile's key.
|
||||
@param data Data to decrypt.
|
||||
@return Decrypted data.
|
||||
*/
|
||||
QByteArray Core::decryptData(const QByteArray &data)
|
||||
{
|
||||
return decryptData(data, Nexus::getProfile()->getPasskey());
|
||||
|
|
|
@ -30,14 +30,27 @@
|
|||
#include <QDir>
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
@class CoreFile
|
||||
@brief Implements Core's file transfer callbacks.
|
||||
|
||||
Avoids polluting core.h with private internal callbacks.
|
||||
*/
|
||||
|
||||
QMutex CoreFile::fileSendMutex;
|
||||
QHash<uint64_t, ToxFile> CoreFile::fileMap;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
@brief Get corefile iteration interval.
|
||||
|
||||
tox_iterate calls to get good file transfer performances
|
||||
@return The maximum amount of time in ms that Core should wait between two tox_iterate() calls.
|
||||
*/
|
||||
unsigned CoreFile::corefileIterationInterval()
|
||||
{
|
||||
/// Sleep at most 1000ms if we have no FT, 10 for user FTs, 50 for the rest (avatars, ...)
|
||||
constexpr unsigned fastFileInterval=10, slowFileInterval=50, idleInterval=1000;
|
||||
constexpr unsigned fastFileInterval = 10, slowFileInterval = 50, idleInterval = 1000;
|
||||
unsigned interval = idleInterval;
|
||||
|
||||
for (ToxFile& file : fileMap)
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
struct Tox;
|
||||
class Core;
|
||||
|
||||
/// Implements Core's file transfer callbacks
|
||||
/// Avoids polluting core.h with private internal callbacks
|
||||
class CoreFile
|
||||
{
|
||||
friend class Core;
|
||||
|
@ -57,8 +55,6 @@ private:
|
|||
static ToxFile *findFile(uint32_t friendId, uint32_t fileId);
|
||||
static void addFile(uint32_t friendId, uint32_t fileId, const ToxFile& file);
|
||||
static void removeFile(uint32_t friendId, uint32_t fileId);
|
||||
/// Returns the maximum amount of time in ms that Core should wait between two
|
||||
/// tox_iterate calls to get good file transfer performances
|
||||
static unsigned corefileIterationInterval();
|
||||
|
||||
private:
|
||||
|
|
|
@ -6,6 +6,18 @@
|
|||
|
||||
#define TOX_HEX_ID_LENGTH 2*TOX_ADDRESS_SIZE
|
||||
|
||||
/**
|
||||
@file corestructs.h
|
||||
@brief Some headers use Core structs but don't need to include all of core.h
|
||||
|
||||
They should include this file directly instead to reduce compilation times
|
||||
*/
|
||||
|
||||
/**
|
||||
@var uint8_t ToxFile::fileKind
|
||||
@brief Data file (default) or avatar
|
||||
*/
|
||||
|
||||
ToxFile::ToxFile(uint32_t fileNum, uint32_t friendId, QByteArray filename, QString filePath, FileDirection Direction)
|
||||
: fileKind{TOX_FILE_KIND_DATA}, fileNum(fileNum), friendId(friendId), fileName{filename},
|
||||
filePath{filePath}, file{new QFile(filePath)}, bytesSent{0}, filesize{0},
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#ifndef CORESTRUCTS_H
|
||||
#define CORESTRUCTS_H
|
||||
|
||||
// Some headers use Core structs but don't need to include all of core.h
|
||||
// They should include this file directly instead to reduce compilation times
|
||||
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
class QFile;
|
||||
class QTimer;
|
||||
|
||||
|
@ -35,7 +33,7 @@ struct ToxFile
|
|||
RECEIVING
|
||||
};
|
||||
|
||||
ToxFile()=default;
|
||||
ToxFile() = default;
|
||||
ToxFile(uint32_t FileNum, uint32_t FriendId, QByteArray FileName, QString filePath, FileDirection Direction);
|
||||
~ToxFile(){}
|
||||
|
||||
|
@ -45,7 +43,7 @@ struct ToxFile
|
|||
void setFilePath(QString path);
|
||||
bool open(bool write);
|
||||
|
||||
uint8_t fileKind; ///< Data file (default) or avatar
|
||||
uint8_t fileKind;
|
||||
uint32_t fileNum;
|
||||
uint32_t friendId;
|
||||
QByteArray fileName;
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/// More or less a hashmap, indexed by the noexcept move-only value type's operator int
|
||||
/// Really nice to store our ToxCall objects.
|
||||
template <typename T>
|
||||
class IndexedList
|
||||
{
|
||||
|
@ -13,30 +11,72 @@ public:
|
|||
explicit IndexedList() = default;
|
||||
|
||||
// Qt
|
||||
inline bool isEmpty() { return v.empty(); }
|
||||
bool contains(int i) { return std::find_if(begin(), end(), [i](T& t){return (int)t == i;}) != end(); }
|
||||
void remove(int i) { v.erase(std::remove_if(begin(), end(), [i](T& t){return (int)t == i;}), end()); }
|
||||
T& operator[](int i)
|
||||
bool isEmpty()
|
||||
{
|
||||
return v.empty();
|
||||
}
|
||||
|
||||
bool contains(int i)
|
||||
{
|
||||
return std::find_if(begin(), end(), [i](T& t){return (int)t == i;}) != end();
|
||||
}
|
||||
|
||||
void remove(int i)
|
||||
{
|
||||
v.erase(std::remove_if(begin(), end(), [i](T& t){return (int)t == i;}), end());
|
||||
}
|
||||
|
||||
T &operator[](int i)
|
||||
{
|
||||
iterator it = std::find_if(begin(), end(), [i](T& t){return (int)t == i;});
|
||||
if (it == end())
|
||||
it = insert({});
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
|
||||
// STL
|
||||
using iterator = typename std::vector<T>::iterator;
|
||||
using const_iterator = typename std::vector<T>::const_iterator;
|
||||
|
||||
inline iterator begin() { return v.begin(); }
|
||||
inline const_iterator begin() const { return v.begin(); }
|
||||
inline const_iterator cbegin() const { return v.cbegin(); }
|
||||
inline iterator end() { return v.end(); }
|
||||
inline const_iterator end() const { return v.end(); }
|
||||
inline const_iterator cend() const { return v.cend(); }
|
||||
inline iterator erase(iterator pos) { return v.erase(pos); }
|
||||
inline iterator erase(iterator first, iterator last) { return v.erase(first, last); }
|
||||
inline iterator insert(T&& value) { v.push_back(std::move(value)); return --v.end(); }
|
||||
inline iterator begin()
|
||||
{
|
||||
return v.begin();
|
||||
}
|
||||
inline const_iterator begin() const
|
||||
{
|
||||
return v.begin();
|
||||
}
|
||||
inline const_iterator cbegin() const
|
||||
{
|
||||
return v.cbegin();
|
||||
}
|
||||
inline iterator end()
|
||||
{
|
||||
return v.end();
|
||||
}
|
||||
inline const_iterator end() const
|
||||
{
|
||||
return v.end();
|
||||
}
|
||||
inline const_iterator cend() const
|
||||
{
|
||||
return v.cend();
|
||||
}
|
||||
inline iterator erase(iterator pos)
|
||||
{
|
||||
return v.erase(pos);
|
||||
}
|
||||
inline iterator erase(iterator first, iterator last)
|
||||
{
|
||||
return v.erase(first, last);
|
||||
}
|
||||
inline iterator insert(T&& value)
|
||||
{
|
||||
v.push_back(std::move(value));
|
||||
return --v.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> v;
|
||||
|
|
|
@ -7,6 +7,23 @@
|
|||
#include <QTimer>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
/**
|
||||
@var uint32_t ToxCall::callId
|
||||
@brief Could be a friendNum or groupNum, must uniquely identify the call. Do not modify!
|
||||
|
||||
@var bool ToxCall::inactive
|
||||
@brief True while we're not participating. (stopped group call, ringing but hasn't started yet, ...)
|
||||
|
||||
@var bool ToxCall::videoEnabled
|
||||
@brief True if our user asked for a video call, sending and recieving.
|
||||
|
||||
@var bool ToxCall::nullVideoBitrate
|
||||
@brief True if our video bitrate is zero, i.e. if the device is closed.
|
||||
|
||||
@var TOXAV_FRIEND_CALL_STATE ToxCall::state
|
||||
@brief State of the peer (not ours!)
|
||||
*/
|
||||
|
||||
using namespace std;
|
||||
|
||||
ToxCall::ToxCall(uint32_t CallId)
|
||||
|
|
|
@ -32,9 +32,9 @@ protected:
|
|||
QMetaObject::Connection audioInConn;
|
||||
|
||||
public:
|
||||
uint32_t callId; ///< Could be a friendNum or groupNum, must uniquely identify the call. Do not modify!
|
||||
uint32_t callId;
|
||||
quint32 alSource;
|
||||
bool inactive; ///< True while we're not participating. (stopped group call, ringing but hasn't started yet, ...)
|
||||
bool inactive;
|
||||
bool muteMic;
|
||||
bool muteVol;
|
||||
};
|
||||
|
@ -48,10 +48,10 @@ struct ToxFriendCall : public ToxCall
|
|||
|
||||
ToxFriendCall& operator=(ToxFriendCall&& other) noexcept;
|
||||
|
||||
bool videoEnabled; ///< True if our user asked for a video call, sending and recving
|
||||
bool nullVideoBitrate; ///< True if our video bitrate is zero, i.e. if the device is closed
|
||||
bool videoEnabled;
|
||||
bool nullVideoBitrate;
|
||||
CoreVideoSource* videoSource;
|
||||
TOXAV_FRIEND_CALL_STATE state; ///< State of the peer (not ours!)
|
||||
TOXAV_FRIEND_CALL_STATE state;
|
||||
|
||||
void startTimeout();
|
||||
void stopTimeout();
|
||||
|
|
|
@ -30,14 +30,46 @@
|
|||
#define TOX_ID_CHECKSUM_LENGTH 4
|
||||
#define TOX_HEX_ID_LENGTH 2*TOX_ADDRESS_SIZE
|
||||
|
||||
/**
|
||||
@class ToxId
|
||||
@brief This class represents a Tox ID.
|
||||
|
||||
An ID is composed of 32 bytes long public key, 4 bytes long NoSpam
|
||||
and 2 bytes long checksum.
|
||||
|
||||
e.g.
|
||||
@code
|
||||
| C7719C6808C14B77348004956D1D98046CE09A34370E7608150EAD74C3815D30 | C8BA3AB9 | BEB9
|
||||
| / |
|
||||
| / NoSpam | Checksum
|
||||
| Public Key (PK), 32 bytes, 64 characters / 4 bytes | 2 bytes
|
||||
| | 8 characters| 4 characters
|
||||
@endcode
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief The default constructor. Creates an empty Tox ID.
|
||||
*/
|
||||
ToxId::ToxId()
|
||||
: publicKey(), noSpam(), checkSum()
|
||||
{}
|
||||
|
||||
/**
|
||||
@brief The copy constructor.
|
||||
@param other ToxId to copy
|
||||
*/
|
||||
ToxId::ToxId(const ToxId &other)
|
||||
: publicKey(other.publicKey), noSpam(other.noSpam), checkSum(other.checkSum)
|
||||
{}
|
||||
|
||||
/**
|
||||
@brief Create a Tox ID from QString.
|
||||
|
||||
If the given id is not a valid Tox ID, then:
|
||||
publicKey == id and noSpam == "" == checkSum.
|
||||
|
||||
@param id Tox ID string to convert to ToxId object
|
||||
*/
|
||||
ToxId::ToxId(const QString &id)
|
||||
{
|
||||
if (isToxId(id))
|
||||
|
@ -52,26 +84,48 @@ ToxId::ToxId(const QString &id)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Compares, that public key equals.
|
||||
@param other Tox ID to compare.
|
||||
@return True if both Tox ID have same public keys, false otherwise.
|
||||
*/
|
||||
bool ToxId::operator==(const ToxId& other) const
|
||||
{
|
||||
return publicKey == other.publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Compares, that only public key not equals.
|
||||
@param other Tox ID to compare.
|
||||
@return True if both Tox ID have different public keys, false otherwise.
|
||||
*/
|
||||
bool ToxId::operator!=(const ToxId &other) const
|
||||
{
|
||||
return publicKey != other.publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check, that the current user ID is the active user ID
|
||||
@return True if this Tox ID is equals to
|
||||
the Tox ID of the currently active profile.
|
||||
*/
|
||||
bool ToxId::isSelf() const
|
||||
{
|
||||
return *this == Core::getInstance()->getSelfId();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns Tox ID converted to QString.
|
||||
@return The Tox ID as QString.
|
||||
*/
|
||||
QString ToxId::toString() const
|
||||
{
|
||||
return publicKey + noSpam + checkSum;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Clears all elements of the Tox ID.
|
||||
*/
|
||||
void ToxId::clear()
|
||||
{
|
||||
publicKey.clear();
|
||||
|
@ -79,6 +133,11 @@ void ToxId::clear()
|
|||
checkSum.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Check, that id is a valid Tox ID.
|
||||
@param id Tox ID to check.
|
||||
@return True if id is a valid Tox ID, false otherwise.
|
||||
*/
|
||||
bool ToxId::isToxId(const QString &id)
|
||||
{
|
||||
const QRegularExpression hexRegExp("^[A-Fa-f0-9]+$");
|
||||
|
|
|
@ -23,36 +23,20 @@
|
|||
|
||||
#include <QString>
|
||||
|
||||
/*
|
||||
* This class represents a Tox ID.
|
||||
* An ID is composed of 32 bytes long public key, 4 bytes long NoSpam
|
||||
* and 2 bytes long checksum.
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
* | C7719C6808C14B77348004956D1D98046CE09A34370E7608150EAD74C3815D30 | C8BA3AB9 | BEB9
|
||||
* | / |
|
||||
* | / NoSpam | Checksum
|
||||
* | Public Key (PK), 32 bytes, 64 characters / 4 bytes | 2 bytes
|
||||
* | | 8 characters| 4 characters
|
||||
*/
|
||||
class ToxId
|
||||
{
|
||||
public:
|
||||
ToxId(); ///< The default constructor. Creates an empty Tox ID.
|
||||
ToxId(const ToxId& other); ///< The copy constructor.
|
||||
explicit ToxId(const QString& id); ///< Create a Tox ID from QString.
|
||||
/// If the given id is not a valid Tox ID, then:
|
||||
/// publicKey == id and noSpam == "" == checkSum.
|
||||
ToxId();
|
||||
ToxId(const ToxId& other);
|
||||
explicit ToxId(const QString& id);
|
||||
|
||||
bool operator==(const ToxId& other) const; ///< Compares only publicKey.
|
||||
bool operator!=(const ToxId& other) const; ///< Compares only publicKey.
|
||||
bool isSelf() const; ///< Returns true if this Tox ID is equals to
|
||||
/// the Tox ID of the currently active profile.
|
||||
QString toString() const; ///< Returns the Tox ID as QString.
|
||||
void clear(); ///< Clears all elements of the Tox ID.
|
||||
bool operator==(const ToxId& other) const;
|
||||
bool operator!=(const ToxId& other) const;
|
||||
bool isSelf() const;
|
||||
QString toString() const;
|
||||
void clear();
|
||||
|
||||
static bool isToxId(const QString& id); ///< Returns true if id is a valid Tox ID.
|
||||
static bool isToxId(const QString& id);
|
||||
|
||||
public:
|
||||
QString publicKey;
|
||||
|
|
|
@ -51,6 +51,9 @@ Friend::~Friend()
|
|||
delete widget;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Loads the friend's chat history if enabled
|
||||
*/
|
||||
void Friend::loadHistory()
|
||||
{
|
||||
if (Nexus::getProfile()->isHistoryEnabled())
|
||||
|
|
|
@ -37,7 +37,6 @@ public:
|
|||
~Friend();
|
||||
Friend& operator=(const Friend& other)=delete;
|
||||
|
||||
/// Loads the friend's chat history if enabled
|
||||
void loadHistory();
|
||||
|
||||
void setName(QString name);
|
||||
|
|
57
src/ipc.cpp
57
src/ipc.cpp
|
@ -25,6 +25,19 @@
|
|||
#include <random>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
@var time_t IPC::lastEvent
|
||||
@brief When last event was posted.
|
||||
|
||||
@var time_t IPC::lastProcessed
|
||||
@brief When processEvents() ran last time
|
||||
*/
|
||||
|
||||
/**
|
||||
@class IPC
|
||||
@brief Inter-process communication
|
||||
*/
|
||||
|
||||
IPC::IPC()
|
||||
: globalMemory{"qtox-" IPC_PROTOCOL_VERSION}
|
||||
{
|
||||
|
@ -84,13 +97,23 @@ IPC::~IPC()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the singleton instance.
|
||||
*/
|
||||
IPC& IPC::getInstance()
|
||||
{
|
||||
static IPC instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
time_t IPC::postEvent(const QString &name, const QByteArray& data/*=QByteArray()*/, uint32_t dest/*=0*/)
|
||||
/**
|
||||
@brief Post IPC event.
|
||||
@param name Name to set in IPC event.
|
||||
@param data Data to set in IPC event (default QByteArray()).
|
||||
@param dest Settings::getCurrentProfileId() or 0 (main instance, default).
|
||||
@return Time the event finished.
|
||||
*/
|
||||
time_t IPC::postEvent(const QString &name, const QByteArray& data, uint32_t dest)
|
||||
{
|
||||
QByteArray binName = name.toUtf8();
|
||||
if (binName.length() > (int32_t)sizeof(IPCEvent::name))
|
||||
|
@ -101,7 +124,7 @@ time_t IPC::postEvent(const QString &name, const QByteArray& data/*=QByteArray()
|
|||
|
||||
if (globalMemory.lock())
|
||||
{
|
||||
IPCEvent* evt = 0;
|
||||
IPCEvent* evt = nullptr;
|
||||
IPCMemory* mem = global();
|
||||
time_t result = 0;
|
||||
|
||||
|
@ -195,6 +218,10 @@ bool IPC::waitUntilAccepted(time_t postTime, int32_t timeout/*=-1*/)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Only called when global memory IS LOCKED.
|
||||
@return nullptr if no evnts present, IPC event otherwise
|
||||
*/
|
||||
IPC::IPCEvent *IPC::fetchEvent()
|
||||
{
|
||||
IPCMemory* mem = global();
|
||||
|
@ -209,32 +236,28 @@ IPC::IPCEvent *IPC::fetchEvent()
|
|||
(!evt->processed && difftime(time(0), evt->posted) > EVENT_GC_TIMEOUT))
|
||||
memset(evt, 0, sizeof(IPCEvent));
|
||||
|
||||
if (evt->posted && !evt->processed && evt->sender != getpid())
|
||||
{
|
||||
if (evt->dest == Settings::getInstance().getCurrentProfileId() || (evt->dest == 0 && isCurrentOwner()))
|
||||
return evt;
|
||||
}
|
||||
if (evt->posted && !evt->processed && evt->sender != getpid()
|
||||
&& (evt->dest == Settings::getInstance().getCurrentProfileId()
|
||||
|| (evt->dest == 0 && isCurrentOwner())))
|
||||
return evt;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool IPC::runEventHandler(IPCEventHandler handler, const QByteArray& arg)
|
||||
{
|
||||
bool result = false;
|
||||
if (QThread::currentThread() != qApp->thread())
|
||||
{
|
||||
if (QThread::currentThread() == qApp->thread())
|
||||
result = handler(arg);
|
||||
else
|
||||
QMetaObject::invokeMethod(this, "runEventHandler",
|
||||
Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(bool, result),
|
||||
Q_ARG(IPCEventHandler, handler),
|
||||
Q_ARG(const QByteArray&, arg));
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = handler(arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void IPC::processEvents()
|
||||
|
|
|
@ -64,14 +64,11 @@ public:
|
|||
struct IPCMemory
|
||||
{
|
||||
uint64_t globalId;
|
||||
// When last event was posted
|
||||
time_t lastEvent;
|
||||
// When processEvents() ran last time
|
||||
time_t lastProcessed;
|
||||
IPCEvent events[IPC::EVENT_QUEUE_SIZE];
|
||||
};
|
||||
|
||||
// dest: Settings::getCurrentProfileId() or 0 (main instance).
|
||||
time_t postEvent(const QString& name, const QByteArray &data=QByteArray(), uint32_t dest=0);
|
||||
bool isCurrentOwner();
|
||||
void registerEventHandler(const QString& name, IPCEventHandler handler);
|
||||
|
@ -84,7 +81,6 @@ protected slots:
|
|||
protected:
|
||||
IPCMemory* global();
|
||||
bool runEventHandler(IPCEventHandler handler, const QByteArray& arg);
|
||||
// Only called when global memory IS LOCKED, returns 0 if no evnts present
|
||||
IPCEvent* fetchEvent();
|
||||
|
||||
QTimer timer;
|
||||
|
|
|
@ -43,6 +43,14 @@
|
|||
#include <QSignalMapper>
|
||||
#endif
|
||||
|
||||
/**
|
||||
@class Nexus
|
||||
|
||||
This class is in charge of connecting various systems together
|
||||
and forwarding signals appropriately to the right objects,
|
||||
it is in charge of starting the GUI and the Core.
|
||||
*/
|
||||
|
||||
Q_DECLARE_OPAQUE_POINTER(ToxAV*)
|
||||
|
||||
static Nexus* nexus{nullptr};
|
||||
|
@ -66,6 +74,11 @@ Nexus::~Nexus()
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Sets up invariants and calls showLogin
|
||||
Hides the login screen and shows the GUI for the given profile.
|
||||
Will delete the current GUI, if it exists.
|
||||
*/
|
||||
void Nexus::start()
|
||||
{
|
||||
qDebug() << "Starting up";
|
||||
|
@ -131,6 +144,9 @@ void Nexus::start()
|
|||
showLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Hides the main GUI, delete the profile, and shows the login screen
|
||||
*/
|
||||
void Nexus::showLogin()
|
||||
{
|
||||
delete widget;
|
||||
|
@ -201,6 +217,9 @@ void Nexus::showMainGUI()
|
|||
profile->startCore();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Returns the singleton instance.
|
||||
*/
|
||||
Nexus& Nexus::getInstance()
|
||||
{
|
||||
if (!nexus)
|
||||
|
@ -215,6 +234,10 @@ void Nexus::destroyInstance()
|
|||
nexus = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get core instance.
|
||||
@return nullptr if not started, core instance otherwise.
|
||||
*/
|
||||
Core* Nexus::getCore()
|
||||
{
|
||||
Nexus& nexus = getInstance();
|
||||
|
@ -224,11 +247,19 @@ Core* Nexus::getCore()
|
|||
return nexus.profile->getCore();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get current user profile.
|
||||
@return nullptr if not started, profile otherwise.
|
||||
*/
|
||||
Profile* Nexus::getProfile()
|
||||
{
|
||||
return getInstance().profile;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Unload the current profile, if any, and replaces it.
|
||||
@param profile Profile to set.
|
||||
*/
|
||||
void Nexus::setProfile(Profile* profile)
|
||||
{
|
||||
getInstance().profile = profile;
|
||||
|
@ -236,6 +267,10 @@ void Nexus::setProfile(Profile* profile)
|
|||
Settings::getInstance().loadPersonal(profile);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Get desktop GUI widget.
|
||||
@return nullptr if not started, desktop widget otherwise.
|
||||
*/
|
||||
Widget* Nexus::getDesktopGUI()
|
||||
{
|
||||
return getInstance().widget;
|
||||
|
@ -250,6 +285,11 @@ QString Nexus::getSupportedImageFilter()
|
|||
return tr("Images (%1)", "filetype filter").arg(res.left(res.size()-1));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Dangerous way to find out if a path is writable.
|
||||
@param filepath Path to file which should be deleted.
|
||||
@return True, if file writeable, false otherwise.
|
||||
*/
|
||||
bool Nexus::tryRemoveFile(const QString& filepath)
|
||||
{
|
||||
QFile tmp(filepath);
|
||||
|
@ -258,6 +298,9 @@ bool Nexus::tryRemoveFile(const QString& filepath)
|
|||
return writable;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Calls showLogin asynchronously, so we can safely logout from within the main GUI
|
||||
*/
|
||||
void Nexus::showLoginLater()
|
||||
{
|
||||
GUI::setEnabled(false);
|
||||
|
|
21
src/nexus.h
21
src/nexus.h
|
@ -37,30 +37,25 @@ class QActionGroup;
|
|||
class QSignalMapper;
|
||||
#endif
|
||||
|
||||
/// This class is in charge of connecting various systems together
|
||||
/// and forwarding signals appropriately to the right objects
|
||||
/// It is in charge of starting the GUI and the Core
|
||||
class Nexus : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void start(); ///< Sets up invariants and calls showLogin
|
||||
/// Hides the login screen and shows the GUI for the given profile.
|
||||
/// Will delete the current GUI, if it exists.
|
||||
void start();
|
||||
void showMainGUI();
|
||||
|
||||
static Nexus& getInstance();
|
||||
static void destroyInstance();
|
||||
static Core* getCore(); ///< Will return 0 if not started
|
||||
static Profile* getProfile(); ///< Will return 0 if not started
|
||||
static void setProfile(Profile* profile); ///< Delete the current profile, if any, and replaces it
|
||||
static Widget* getDesktopGUI(); ///< Will return 0 if not started
|
||||
static Core* getCore();
|
||||
static Profile* getProfile();
|
||||
static void setProfile(Profile* profile);
|
||||
static Widget* getDesktopGUI();
|
||||
static QString getSupportedImageFilter();
|
||||
static bool tryRemoveFile(const QString& filepath); ///< Dangerous way to find out if a path is writable
|
||||
static bool tryRemoveFile(const QString& filepath);
|
||||
|
||||
public slots:
|
||||
void showLogin(); ///< Hides the man GUI, delete the profile, and shows the login screen
|
||||
void showLoginLater(); ///< Calls showLogin asynchronously, so we can safely logout from within the main GUI
|
||||
void showLogin();
|
||||
void showLoginLater();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue
Block a user