Files
BloomPatched/src/Insight/InsightWorker.cpp

104 lines
4.2 KiB
C++
Raw Normal View History

2021-04-04 21:04:12 +01:00
#include <thread>
#include <filesystem>
#include <typeindex>
#include <QObject>
#include <QTimer>
#include "InsightWorker.hpp"
#include "src/Logger/Logger.hpp"
#include "src/Helpers/Thread.hpp"
#include "src/Exceptions/InvalidConfig.hpp"
using namespace Bloom;
using namespace Bloom::Events;
using namespace Bloom::Exceptions;
using Bloom::Targets::TargetState;
2021-04-04 21:04:12 +01:00
void InsightWorker::startup() {
Logger::debug("Starting InsightWorker thread");
this->eventManager.registerListener(this->eventListener);
this->eventListener->registerCallbackForEventType<TargetExecutionStopped>(
std::bind(&InsightWorker::onTargetStoppedEvent, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<TargetExecutionResumed>(
std::bind(&InsightWorker::onTargetResumedEvent, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<TargetPinStatesRetrieved>(
std::bind(&InsightWorker::onTargetPinStatesRetrievedEvent, this, std::placeholders::_1)
);
this->eventListener->registerCallbackForEventType<TargetIoPortsUpdated>(
std::bind(&InsightWorker::onTargetIoPortsUpdatedEvent, this, std::placeholders::_1)
);
this->eventDispatchTimer = new QTimer(this);
QTimer::connect(this->eventDispatchTimer, &QTimer::timeout, this, &InsightWorker::dispatchEvents);
2021-04-14 23:18:37 +01:00
this->eventDispatchTimer->start(5);
2021-04-04 21:04:12 +01:00
this->eventManager.triggerEvent(
std::make_shared<Events::InsightThreadStateChanged>(ThreadState::READY)
2021-04-04 21:04:12 +01:00
);
}
void InsightWorker::requestPinStates(int variantId) {
this->targetControllerConsole.requestPinStates(variantId);
2021-04-04 21:04:12 +01:00
}
void InsightWorker::requestPinStateUpdate(
int variantId,
Bloom::Targets::TargetPinDescriptor pinDescriptor,
Bloom::Targets::TargetPinState pinState
) {
this->targetControllerConsole.setPinState(variantId, pinDescriptor, pinState);
2021-04-04 21:04:12 +01:00
}
void InsightWorker::onTargetStoppedEvent(EventPointer<TargetExecutionStopped> event) {
2021-05-25 21:50:17 +01:00
/*
* When we report a target halt to Insight, Insight will immediately seek more data from the target (such as GPIO
* pin states). This can be problematic for cases where the target had halted due to a conditional breakpoint.
*
* For conditional breakpoints, a software breakpoint is employed to halt target execution and give the debug
* client an opportunity to check the condition. In cases where the condition is not met, the client will
* immediately request for execution to be resumed. It's important that Insight does not get in the way of this
* process, as it could end up slowing things down significantly.
*
* For the above reason, we don't want to report any target halts to Insight, unless we can be sure that the client
* isn't going to immediately resume execution upon checking the condition.
*
* We do this by providing a time window for the TargetExecutionResumed event. If the event is triggered within
* that time window, we won't report the target halt to Insight, thus preventing Insight from needlessly seeking
* data from the target and slowing things down.
*
* This isn't the best approach, TBH, as it introduces a delay to Insight's response to the target halting. The
* problem is, we cannot differentiate a conditional breakpoint with a software breakpoint, so this seems to be the
* only way. It would be nice if the debug client gave us some form of indication of whether the breakpoint is a
* conditional one.
*/
auto resumedEvent = this->eventListener->waitForEvent<TargetExecutionResumed>(
std::chrono::milliseconds(650)
);
2021-04-04 21:04:12 +01:00
if (!resumedEvent.has_value()) {
emit this->targetStateUpdated(TargetState::STOPPED);
emit this->targetProgramCounterUpdated(event->programCounter);
}
}
void InsightWorker::onTargetResumedEvent(EventPointer<TargetExecutionResumed> event) {
emit this->targetStateUpdated(TargetState::RUNNING);
}
void InsightWorker::onTargetPinStatesRetrievedEvent(EventPointer<TargetPinStatesRetrieved> event) {
emit this->targetPinStatesUpdated(event->variantId, event->pinSatesByNumber);
}
void InsightWorker::onTargetIoPortsUpdatedEvent(EventPointer<TargetIoPortsUpdated> event) {
emit this->targetIoPortsUpdated();
}