forked from blue/squawk
DONT TAKE, BROKEN! first application of delay manager in code, reception of bundles
This commit is contained in:
parent
5ba97ecc25
commit
927bdf0dab
16 changed files with 261 additions and 139 deletions
366
core/delayManager/manager.cpp
Normal file
366
core/delayManager/manager.cpp
Normal file
|
@ -0,0 +1,366 @@
|
|||
// Squawk messenger.
|
||||
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "manager.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "cardinternal.h"
|
||||
#include "infoforuser.h"
|
||||
#include "owncardinternal.h"
|
||||
#include "owninfoforuser.h"
|
||||
|
||||
Core::DelayManager::Manager::Manager(const QString& poj, Job::Id mpj, QObject* parent) :
|
||||
QObject(parent),
|
||||
maxParallelJobs(mpj),
|
||||
nextJobId(1),
|
||||
scheduledJobs(),
|
||||
scheduledJobsById(scheduledJobs.get<id>()),
|
||||
jobSequence(scheduledJobs.get<sequence>()),
|
||||
runningJobs(),
|
||||
ownVCardJobId(0),
|
||||
ownInfoJobId(0),
|
||||
scheduledVCards(),
|
||||
requestedVCards(),
|
||||
#ifdef WITH_OMEMO
|
||||
requestedBundles(),
|
||||
#endif
|
||||
ownJid(poj)
|
||||
{
|
||||
}
|
||||
|
||||
Core::DelayManager::Manager::~Manager() {
|
||||
for (const std::pair<const Job::Id, Job*>& pair : runningJobs) {
|
||||
delete pair.second;
|
||||
}
|
||||
|
||||
for (Job* job : jobSequence) {
|
||||
delete job;
|
||||
}
|
||||
}
|
||||
|
||||
Core::DelayManager::Job::Id Core::DelayManager::Manager::getNextJobId() {
|
||||
Job::Id id = nextJobId++;
|
||||
if (id == 0)
|
||||
id = nextJobId++;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::getInfo(const QString& jid) {
|
||||
if (jid == ownJid)
|
||||
return getOwnInfo();
|
||||
|
||||
Job* job = nullptr;
|
||||
#ifdef WITH_OMEMO
|
||||
std::map<QString, Job::Id>::const_iterator bitr = requestedBundles.find(jid);
|
||||
if (bitr != requestedBundles.end())
|
||||
job = runningJobs.at(bitr->second);
|
||||
else
|
||||
#endif
|
||||
job = getVCardJob(jid);
|
||||
|
||||
if (job != nullptr) {
|
||||
if (job->type == Job::Type::cardInternal)
|
||||
replaceJob(new InfoForUser(job->id, jid));
|
||||
} else
|
||||
scheduleJob(new InfoForUser(getNextJobId(), jid));
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::getOwnInfo() {
|
||||
if (ownInfoJobId == 0) {
|
||||
if (ownVCardJobId != 0)
|
||||
replaceJob(new OwnInfoForUser(ownVCardJobId));
|
||||
else
|
||||
scheduleJob(new OwnInfoForUser(getNextJobId()));
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::getVCard(const QString& jid) {
|
||||
Job* job = getVCardJob(jid);
|
||||
if (job == nullptr)
|
||||
scheduleJob(new CardInternal(getNextJobId(), jid));
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::getOwnVCard() {
|
||||
if (ownVCardJobId == 0)
|
||||
scheduleJob(new OwnCardInternal(getNextJobId()));
|
||||
}
|
||||
|
||||
bool Core::DelayManager::Manager::isOwnVCardPending() const {
|
||||
return ownVCardJobId != 0;
|
||||
}
|
||||
|
||||
Core::DelayManager::Job* Core::DelayManager::Manager::getVCardJob(const QString& jid) {
|
||||
Job* job = nullptr;
|
||||
std::map<QString, Job::Id>::const_iterator sitr = scheduledVCards.find(jid);
|
||||
if (sitr == scheduledVCards.end()) {
|
||||
std::map<QString, Job::Id>::const_iterator ritr = requestedVCards.find(jid);
|
||||
if (ritr != requestedVCards.end())
|
||||
job = runningJobs.at(ritr->second);
|
||||
} else {
|
||||
job = *(scheduledJobsById.find(sitr->second));
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
void Core::DelayManager::Manager::preScheduleJob(Job* job) {
|
||||
switch (job->type) {
|
||||
case Job::Type::cardInternal:
|
||||
scheduledVCards.emplace(dynamic_cast<CardInternal*>(job)->jid, job->id);
|
||||
break;
|
||||
case Job::Type::ownCardInternal:
|
||||
ownVCardJobId = job->id;
|
||||
break;
|
||||
case Job::Type::infoForUser:
|
||||
scheduledVCards.emplace(dynamic_cast<InfoForUser*>(job)->jid, job->id);
|
||||
break;
|
||||
case Job::Type::ownInfoForUser:
|
||||
ownVCardJobId = job->id;
|
||||
ownInfoJobId = job->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::scheduleJob(Job* job) {
|
||||
preScheduleJob(job);
|
||||
if (runningJobs.size() < maxParallelJobs) {
|
||||
executeJob(job);
|
||||
} else {
|
||||
scheduledJobs.push_back(job);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::preExecuteJob(Job* job) {
|
||||
switch (job->type) {
|
||||
case Job::Type::cardInternal:
|
||||
case Job::Type::infoForUser: {
|
||||
Contact* cij = dynamic_cast<Contact*>(job);
|
||||
requestedVCards.emplace(cij->jid, job->id);
|
||||
scheduledVCards.erase(cij->jid);
|
||||
}
|
||||
break;
|
||||
case Job::Type::ownInfoForUser:
|
||||
case Job::Type::ownCardInternal:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::executeJob(Job* job) {
|
||||
preExecuteJob(job);
|
||||
runningJobs.emplace(job->id, job);
|
||||
switch (job->type) {
|
||||
case Job::Type::cardInternal:
|
||||
case Job::Type::infoForUser:
|
||||
emit requestVCard(dynamic_cast<Contact*>(job)->jid);
|
||||
break;
|
||||
case Job::Type::ownInfoForUser:
|
||||
case Job::Type::ownCardInternal:
|
||||
emit requestOwnVCard();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::jobIsDone(Job::Id jobId) {
|
||||
std::map<Job::Id, Job*>::const_iterator itr = runningJobs.find(jobId);
|
||||
if (itr == runningJobs.end()) {
|
||||
throw 8573; //not supposed to happen, ever
|
||||
}
|
||||
Job* job = itr->second;
|
||||
delete job;
|
||||
runningJobs.erase(itr);
|
||||
if (scheduledJobs.size() > 0) {
|
||||
Job* job = scheduledJobs.front();
|
||||
scheduledJobs.pop_front();
|
||||
executeJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::replaceJob(Job* job) {
|
||||
preScheduleJob(job);
|
||||
std::map<Job::Id, Job*>::iterator itr = runningJobs.find(job->id);
|
||||
if (itr != runningJobs.end()) {
|
||||
preExecuteJob(job);
|
||||
delete itr->second;
|
||||
itr->second = job;
|
||||
} else {
|
||||
StorageById::iterator sitr = scheduledJobsById.find(job->id);
|
||||
if (sitr != scheduledJobsById.end()) {
|
||||
delete *(sitr);
|
||||
scheduledJobsById.replace(sitr, job);
|
||||
} else {
|
||||
throw 8574; //not supposed to happen, ever
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::jobIsCanceled(Job* job, bool wasRunning) {
|
||||
switch (job->type) {
|
||||
case Job::Type::cardInternal: {
|
||||
CardInternal* jb = dynamic_cast<CardInternal*>(job);
|
||||
if (wasRunning)
|
||||
requestedVCards.erase(jb->jid);
|
||||
else
|
||||
scheduledVCards.erase(jb->jid);
|
||||
|
||||
emit gotVCard(jb->jid, Shared::VCard());
|
||||
}
|
||||
break;
|
||||
case Job::Type::infoForUser: {
|
||||
InfoForUser* jb = dynamic_cast<InfoForUser*>(job);
|
||||
switch (jb->getStage()) {
|
||||
case InfoForUser::Stage::waitingForVCard:
|
||||
if (wasRunning)
|
||||
requestedVCards.erase(jb->jid);
|
||||
else
|
||||
scheduledVCards.erase(jb->jid);
|
||||
|
||||
emit gotVCard(jb->jid, Shared::VCard());
|
||||
break;
|
||||
case InfoForUser::Stage::waitingForBundles:
|
||||
requestedBundles.erase(jb->jid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
emit gotInfo(Shared::Info(jb->jid));
|
||||
}
|
||||
break;
|
||||
case Job::Type::ownInfoForUser: {
|
||||
OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job);
|
||||
if (jb->getStage() == OwnInfoForUser::Stage::waitingForVCard) {
|
||||
ownVCardJobId = 0;
|
||||
emit gotOwnVCard(Shared::VCard());
|
||||
}
|
||||
ownInfoJobId = 0;
|
||||
emit gotOwnInfo(Shared::Info (ownJid));
|
||||
}
|
||||
|
||||
break;
|
||||
case Job::Type::ownCardInternal:
|
||||
ownVCardJobId = 0;
|
||||
emit gotOwnVCard(Shared::VCard());
|
||||
break;
|
||||
}
|
||||
|
||||
delete job;
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::disconnected() {
|
||||
for (const std::pair<const Job::Id, Job*> pair : runningJobs)
|
||||
jobIsCanceled(pair.second, true);
|
||||
|
||||
for (Job* job : scheduledJobs)
|
||||
jobIsCanceled(job, false);
|
||||
|
||||
runningJobs.clear();
|
||||
scheduledJobs.clear();
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared::VCard& card) {
|
||||
std::map<QString, Job::Id>::const_iterator cardItr = requestedVCards.find(jid);
|
||||
if (cardItr == requestedVCards.end()) {
|
||||
qDebug() << "received VCard for" << jid << "but it was never requested through manager, ignoring";
|
||||
return;
|
||||
}
|
||||
Job::Id jobId = cardItr->second;
|
||||
requestedVCards.erase(cardItr);
|
||||
Job* job = runningJobs.at(jobId);
|
||||
switch (job->type) {
|
||||
case Job::Type::cardInternal:
|
||||
jobIsDone(jobId);
|
||||
emit gotVCard(jid, card);
|
||||
break;
|
||||
case Job::Type::infoForUser: {
|
||||
#ifdef WITH_OMEMO
|
||||
requestedBundles.emplace(jid, jobId);
|
||||
InfoForUser* jb = dynamic_cast<InfoForUser*>(job);
|
||||
jb->receivedVCard(card);
|
||||
emit requestBundles(jid);
|
||||
#else
|
||||
Shared::Info info(jid);
|
||||
info.turnIntoContact(card);
|
||||
emit gotInfo(info);
|
||||
jobIsDone(jobId);
|
||||
#endif
|
||||
emit gotVCard(jid, card);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 8576;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::receivedOwnVCard(const Shared::VCard& card) {
|
||||
Job::Id jobId = ownVCardJobId;
|
||||
ownVCardJobId = 0;
|
||||
Job* job = runningJobs.at(jobId);
|
||||
switch (job->type) {
|
||||
case Job::Type::ownCardInternal:
|
||||
jobIsDone(jobId);
|
||||
emit gotOwnVCard(card);
|
||||
break;
|
||||
case Job::Type::ownInfoForUser: {
|
||||
#ifdef WITH_OMEMO
|
||||
OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job);
|
||||
jb->receivedVCard(card);
|
||||
emit requestOwnBundles();
|
||||
#else
|
||||
Shared::Info info(ownJid);
|
||||
info.turnIntoOwnAccount(card);
|
||||
emit gotOwnInfo(info);
|
||||
jobIsDone(jobId);
|
||||
#endif
|
||||
emit gotOwnVCard(card);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw 8576;
|
||||
}
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::receivedBundles(const QString& jid, const std::list<Shared::KeyInfo>& keys) {
|
||||
std::map<QString, Job::Id>::const_iterator itr = requestedBundles.find(jid);
|
||||
if (itr == requestedBundles.end()) {
|
||||
throw 8577; //never supposed to happen, the state is not correct;
|
||||
}
|
||||
|
||||
Job::Id jobId = itr->second;
|
||||
requestedBundles.erase(itr);
|
||||
Job* jb = runningJobs.at(jobId);
|
||||
InfoForUser* job = dynamic_cast<InfoForUser*>(jb);
|
||||
|
||||
Shared::Info info(jid);
|
||||
info.turnIntoContact(job->claim(), new std::list<Shared::KeyInfo>(keys));
|
||||
emit gotInfo(info);
|
||||
jobIsDone(jobId);
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::receivedOwnBundles(const std::list<Shared::KeyInfo>& keys) {
|
||||
Job::Id jobId = ownInfoJobId;
|
||||
ownInfoJobId = 0;
|
||||
Job* jb = runningJobs.at(jobId);
|
||||
OwnInfoForUser* job = dynamic_cast<OwnInfoForUser*>(jb);
|
||||
|
||||
Shared::Info info(ownJid);
|
||||
info.turnIntoOwnAccount(job->claim(), new std::list<Shared::KeyInfo>(keys));
|
||||
emit gotOwnInfo(info);
|
||||
jobIsDone(jobId);
|
||||
}
|
||||
|
||||
void Core::DelayManager::Manager::setOwnJid(const QString& jid) {
|
||||
ownJid = jid;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue