Improved register written event
This commit is contained in:
@@ -21,3 +21,15 @@ void EventManager::triggerEvent(const std::shared_ptr<const Events::Event>& even
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EventManager::isEventTypeListenedFor(Events::EventType eventType) {
|
||||
auto registerListenersLock = std::unique_lock(this->registerListenerMutex);
|
||||
|
||||
for(auto const& [listenerId, listener] : this->registeredListeners) {
|
||||
if (listener->isEventTypeRegistered(eventType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -54,5 +54,13 @@ namespace Bloom
|
||||
* @param event
|
||||
*/
|
||||
void triggerEvent(const Events::SharedGenericEventPointer& event);
|
||||
|
||||
/**
|
||||
* Checks if any registered listener is listening for a particular event type.
|
||||
*
|
||||
* @param eventType
|
||||
* @return
|
||||
*/
|
||||
bool isEventTypeListenedFor(Events::EventType eventType);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Bloom::Events
|
||||
static inline EventType type = EventType::REGISTERS_WRITTEN_TO_TARGET;
|
||||
static inline const std::string name = "RegistersWrittenToTarget";
|
||||
|
||||
Targets::TargetRegisterDescriptors descriptors;
|
||||
Targets::TargetRegisters registers;
|
||||
|
||||
[[nodiscard]] EventType getType() const override {
|
||||
return RegistersWrittenToTarget::type;
|
||||
|
||||
@@ -122,7 +122,7 @@ void InsightWorker::onTargetIoPortsUpdatedEvent(const Events::TargetIoPortsUpdat
|
||||
}
|
||||
|
||||
void InsightWorker::onTargetRegistersWrittenEvent(const Events::RegistersWrittenToTarget& event) {
|
||||
emit this->targetRegistersWritten(event.descriptors);
|
||||
emit this->targetRegistersWritten(event.registers);
|
||||
}
|
||||
|
||||
void InsightWorker::onTargetControllerStateReportedEvent(const Events::TargetControllerStateReported& event) {
|
||||
|
||||
@@ -66,6 +66,6 @@ namespace Bloom
|
||||
void targetIoPortsUpdated();
|
||||
void targetControllerSuspended();
|
||||
void targetControllerResumed(const Bloom::Targets::TargetDescriptor& targetDescriptor);
|
||||
void targetRegistersWritten(const Bloom::Targets::TargetRegisterDescriptors& descriptors);
|
||||
void targetRegistersWritten(const Bloom::Targets::TargetRegisters& targetRegisters);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ TargetRegistersPaneWidget::TargetRegistersPaneWidget(
|
||||
&insightWorker,
|
||||
&InsightWorker::targetRegistersWritten,
|
||||
this,
|
||||
&TargetRegistersPaneWidget::onRegistersWritten
|
||||
&TargetRegistersPaneWidget::onRegistersRead
|
||||
);
|
||||
}
|
||||
|
||||
@@ -162,30 +162,6 @@ void TargetRegistersPaneWidget::onRegistersRead(const Targets::TargetRegisters&
|
||||
}
|
||||
}
|
||||
|
||||
void TargetRegistersPaneWidget::onRegistersWritten(const Bloom::Targets::TargetRegisterDescriptors& descriptors) {
|
||||
if (this->targetState != Targets::TargetState::STOPPED) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't bother refreshing individual registers if it will involve more than two refresh calls - In this case, it
|
||||
* will be faster to just refresh all of them at once.
|
||||
*/
|
||||
if (descriptors.size() <= 2) {
|
||||
for (const auto& descriptor : descriptors) {
|
||||
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
|
||||
if (registerGroupWidget->registerWidgetsMappedByDescriptor.contains(descriptor)) {
|
||||
registerGroupWidget->registerWidgetsMappedByDescriptor.at(descriptor)->refreshValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
this->refreshRegisterValues();
|
||||
}
|
||||
}
|
||||
|
||||
void TargetRegistersPaneWidget::filterRegisters(const QString& keyword) {
|
||||
auto stdKeyword = keyword.toLower().toStdString();
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace Bloom::Widgets
|
||||
private slots:
|
||||
void onTargetStateChanged(Targets::TargetState newState);
|
||||
void onRegistersRead(const Targets::TargetRegisters& registers);
|
||||
void onRegistersWritten(const Bloom::Targets::TargetRegisterDescriptors& descriptors);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
@@ -578,15 +578,7 @@ void TargetController::onWriteRegistersEvent(const Events::WriteRegistersToTarge
|
||||
|
||||
auto registersWrittenEvent = std::make_shared<Events::RegistersWrittenToTarget>();
|
||||
registersWrittenEvent->correlationId = event.id;
|
||||
|
||||
std::transform(
|
||||
event.registers.begin(),
|
||||
event.registers.end(),
|
||||
std::inserter(registersWrittenEvent->descriptors, registersWrittenEvent->descriptors.begin()),
|
||||
[] (const TargetRegister& targetRegister) {
|
||||
return targetRegister.descriptor;
|
||||
}
|
||||
);
|
||||
registersWrittenEvent->registers = event.registers;
|
||||
|
||||
this->eventManager.triggerEvent(registersWrittenEvent);
|
||||
|
||||
@@ -612,27 +604,49 @@ void TargetController::onReadMemoryEvent(const Events::RetrieveMemoryFromTarget&
|
||||
|
||||
void TargetController::onWriteMemoryEvent(const Events::WriteMemoryToTarget& event) {
|
||||
try {
|
||||
const auto& buffer = event.buffer;
|
||||
const auto bufferSize = event.buffer.size();
|
||||
const auto bufferStartAddress = event.startAddress;
|
||||
|
||||
this->target->writeMemory(event.memoryType, event.startAddress, event.buffer);
|
||||
|
||||
auto memoryWrittenEvent = std::make_shared<Events::MemoryWrittenToTarget>();
|
||||
memoryWrittenEvent->correlationId = event.id;
|
||||
this->eventManager.triggerEvent(memoryWrittenEvent);
|
||||
|
||||
if (this->registerDescriptorsByMemoryType.contains(event.memoryType)) {
|
||||
if (this->eventManager.isEventTypeListenedFor(Events::RegistersWrittenToTarget::type)
|
||||
&& this->registerDescriptorsByMemoryType.contains(event.memoryType)
|
||||
) {
|
||||
/*
|
||||
* The memory type we just wrote to contains some number of registers - if we've written to any address
|
||||
* that is known to store the value of a register, trigger a RegistersWrittenToTarget event
|
||||
*/
|
||||
const auto bufferEndAddress = static_cast<std::uint32_t>(bufferStartAddress + (bufferSize - 1));
|
||||
auto registerDescriptors = this->getRegisterDescriptorsWithinAddressRange(
|
||||
event.startAddress,
|
||||
static_cast<std::uint32_t>(event.startAddress + (event.buffer.size() - 1)),
|
||||
bufferStartAddress,
|
||||
bufferEndAddress,
|
||||
event.memoryType
|
||||
);
|
||||
|
||||
if (!registerDescriptors.empty()) {
|
||||
auto registersWrittenEvent = std::make_shared<Events::RegistersWrittenToTarget>();
|
||||
registersWrittenEvent->correlationId = event.id;
|
||||
registersWrittenEvent->descriptors = registerDescriptors;
|
||||
|
||||
for (const auto& registerDescriptor : registerDescriptors) {
|
||||
const auto registerSize = registerDescriptor.size;
|
||||
const auto registerStartAddress = registerDescriptor.startAddress.value();
|
||||
const auto registerEndAddress = registerStartAddress + (registerSize - 1);
|
||||
|
||||
if (registerStartAddress < bufferStartAddress || registerEndAddress > bufferEndAddress) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto bufferBeginIt = buffer.begin() + (registerStartAddress - bufferStartAddress);
|
||||
registersWrittenEvent->registers.emplace_back(TargetRegister(
|
||||
registerDescriptor,
|
||||
TargetMemoryBuffer(bufferBeginIt, bufferBeginIt + registerSize)
|
||||
));
|
||||
}
|
||||
|
||||
this->eventManager.triggerEvent(registersWrittenEvent);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user