Files
2026-08-13 18:33:10 +02:00

207 lines
6.8 KiB
C++
Executable File

/**
* Exercises Handler - checks the avilable exercises
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-04-14
*/
#include "exercises_handler.h"
#include "dds_handler.h"
#include "dds_handler_exercise.h"
#include "main_handler.h"
#include "exercise_handler.h"
#include "audio_video_handler.h"
#include "import_handler.h"
#include "exercise_context.h"
#include "asset_assignment_manager.h"
#include "exercise.h"
#include "default_av_menus.h"
#include <ngldb/dbtransaction.h>
#include <memory>
namespace AudioVideoManagement
{
/**
* Small composite class that holds all parts we need for an exercise.
*/
class ExercisesHandler::ExerciseParts
{
public:
ExerciseParts(MainHandler *mainHandler, Exercise *exercise)
: m_ddsHandler(new DdsHandlerExercise(mainHandler->ddsHandler()->domainParticipant(), exercise->context().id()))
, m_exerciseHandler(new ExerciseHandler(mainHandler, exercise->context().id()))
, m_defaultAvMenus(new DefaultAvMenus(exercise->context(), m_ddsHandler->dts(), mainHandler->videoTeamHandler(), mainHandler->ddsHandler()->ismDtc()))
, m_audioVideoHandler(new AudioVideoHandler(exercise, m_exerciseHandler.get(), m_defaultAvMenus.get(), mainHandler->db(), m_ddsHandler->dts()))
, m_importHandler(ImportHandler::create(m_exerciseHandler.get(), mainHandler->db(), mainHandler->ddsHandler()->asmDtc()))
{}
ExerciseHandler *exerciseHandler() const { return m_exerciseHandler.get(); }
AudioVideoHandler *audioVideoHandler() const { return m_audioVideoHandler.get(); }
ImportHandler *importHandler() const { return m_importHandler.get(); }
private:
std::unique_ptr<DdsHandlerExercise> m_ddsHandler;
std::unique_ptr<ExerciseHandler> m_exerciseHandler;
std::unique_ptr<DefaultAvMenus> m_defaultAvMenus;
std::unique_ptr<AudioVideoHandler> m_audioVideoHandler;
std::unique_ptr<ImportHandler> m_importHandler;
};
ExercisesHandler::ExercisesHandler(MainHandler *mainHandler)
: m_mainHandler(mainHandler)
, m_triggerAvUpdateTimer(new QTimer(this))
, m_assetAssignmentManager(AssetAssignmentManager::create(mainHandler->ddsHandler()->ismDtc()))
, m_logger(getLogger("ExercisesHandler"))
{
m_triggerAvUpdateTimer->setSingleShot(true);
m_triggerAvUpdateTimer->setInterval(1000);
connect(m_triggerAvUpdateTimer, &QTimer::timeout,
m_mainHandler->avControl(), &AVControl::triggerAVUpdate);
}
ExercisesHandler::~ExercisesHandler() = default;
bool ExercisesHandler::init()
{
const auto cbLastSeen = [this] (const Database::AvmExerciseLastSeen &lastSeen)
{
createExerciseHandlerFromLastSeen(lastSeen);
};
if (!db()->select(cbLastSeen))
return false;
// Don't use select with callback here as the callback (body of for-loop below) would use the DB, too.
QVector<Database::AvmDeviceConfig> avmDeviceConfig;
if (!db()->select(avmDeviceConfig))
return false;
DBTransaction trans(db()->database());
for (const Database::AvmDeviceConfig &dc : qAsConst(avmDeviceConfig))
{
// nur hinzufuegen, wenn es record/replay session ist
// alle anderen -> aus DB loeschen
if (dc.type != ExerciseHandler::avTypeRecordSession() && dc.type != ExerciseHandler::avTypePlaybackSession())
{
db()->removeAvmDeviceConfig(dc.id);
continue;
}
const int exerciseId = ExerciseContext::fromString(dc.context).id();
ExerciseHandler *exH = getOrCreateExerciseHandler(exerciseId);
exH->addDeviceConfig(dc);
}
trans.commit();
connect(exmDtc(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
this, &ExercisesHandler::onExerciseChanged);
DEBUG_LOG(m_logger) << LOGFUNCTION << " done";
return true;
}
void ExercisesHandler::exerciseModified(int exerciseId, const ExerciseManagement::ExerciseState &state)
{
ExerciseHandler *exH = getOrCreateExerciseHandler(exerciseId);
exH->setNewExerciseState(state);
}
void ExercisesHandler::onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification modType)
{
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
exerciseModified(data.id(), data.state());
break;
case DataModification::eRemoved:
// nothing to do here
// The removal of an exercise is handled by the corresponding ExerciseHandler itself.
// see ExerciseHandler::onLastSeenTimerTimeout()
break;
}
}
ExerciseHandler *ExercisesHandler::exerciseHandler(int exerciseId) const
{
auto it = m_exercises.find(exerciseId);
if (it == m_exercises.end())
return nullptr;
else
return it->second.exerciseHandler();
}
AudioVideoHandler *ExercisesHandler::audioVideoHandler(int exerciseId) const
{
auto it = m_exercises.find(exerciseId);
if (it == m_exercises.end())
return nullptr;
else
return it->second.audioVideoHandler();
}
void ExercisesHandler::onAvDbReloadNeeded()
{
m_triggerAvUpdateTimer->start();
}
void ExercisesHandler::createExerciseHandlerFromLastSeen(const Database::AvmExerciseLastSeen &lastSeen)
{
ExerciseHandler *exH = createExerciseHandler(ExerciseContext::fromString(lastSeen.context).id());
exH->setLastSeen(lastSeen);
}
ExerciseHandler *ExercisesHandler::getOrCreateExerciseHandler(int exerciseId)
{
ExerciseHandler *exH = exerciseHandler(exerciseId);
if (exH)
return exH;
else
return createExerciseHandler(exerciseId);
}
ExerciseHandler *ExercisesHandler::createExerciseHandler(int exerciseId)
{
DEBUG_LOG(m_logger) << "Creating handler for exercise " << exerciseId;
ExerciseParts parts(m_mainHandler, m_assetAssignmentManager->exercise(exerciseId));
ExerciseHandler *exH = parts.exerciseHandler();
AudioVideoHandler *avH = parts.audioVideoHandler();
ImportHandler *impH = parts.importHandler();
auto insertResult = m_exercises.insert(std::make_pair(exerciseId, std::move(parts)));
Q_ASSERT(insertResult.second);
connect(exH, &ExerciseHandler::removeMeImFinished, this, &ExercisesHandler::exerciseFinished, Qt::QueuedConnection);
connect(exH, &ExerciseHandler::contextActivated, this, [this, exH] { emit contextActivated(exH->context()); });
connect(exH, &ExerciseHandler::contextDeactivated, this, [this, exH] { emit contextDeactivated(exH->context()); });
connect(exH, &ExerciseHandler::avDbReloadNeeded, this, &ExercisesHandler::onAvDbReloadNeeded);
connect(avH, &AudioVideoHandler::avDbReloadNeeded, this, &ExercisesHandler::onAvDbReloadNeeded);
connect(impH, &ImportHandler::avDbReloadNeeded, this, &ExercisesHandler::onAvDbReloadNeeded);
return exH;
}
void ExercisesHandler::exerciseFinished(int exerciseId)
{
auto count = m_exercises.erase(exerciseId);
Q_ASSERT(count == 1);
m_assetAssignmentManager->removeExercise(exerciseId);
}
DatabaseInterface *ExercisesHandler::db()
{
return m_mainHandler->db();
}
ExerciseManagement::Interface::Dtc *ExercisesHandler::exmDtc()
{
return m_mainHandler->ddsHandler()->exmDtc();
}
} // namespace AudioVideoManagement