diff options
Diffstat (limited to 'plugins/warp/ui')
| -rw-r--r-- | plugins/warp/ui/matches.cpp | 71 | ||||
| -rw-r--r-- | plugins/warp/ui/matches.h | 9 | ||||
| -rw-r--r-- | plugins/warp/ui/plugin.cpp | 3 |
3 files changed, 83 insertions, 0 deletions
diff --git a/plugins/warp/ui/matches.cpp b/plugins/warp/ui/matches.cpp index fad729d6..ed77085a 100644 --- a/plugins/warp/ui/matches.cpp +++ b/plugins/warp/ui/matches.cpp @@ -5,6 +5,7 @@ #include <QClipboard> #include <QFormLayout> +#include <thread> #include "theme.h" #include "warp.h" @@ -15,6 +16,8 @@ WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(FunctionRef current) // NOTE: Might be nullptr if the no selected function. m_current = current; + m_logger = new BinaryNinja::Logger("WARP"); + // Create the QT stuff QGridLayout *layout = new QGridLayout(this); layout->setContentsMargins(2, 2, 2, 2); @@ -110,6 +113,26 @@ void WarpCurrentFunctionWidget::SetCurrentFunction(FunctionRef current) return; m_current = current; m_infoWidget->SetAnalysisFunction(m_current); + + if (current) + { + // Add the function to the processing list only if we have no already done so. + // If a user goes to a function, then navigates away, they do not want to + // have us try and send a network request! + { + std::lock_guard<std::mutex> lock(m_requestMutex); + uint64_t funcStart = current->GetStart(); + if (m_processedFunctions.find(funcStart) == m_processedFunctions.end()) { + m_pendingRequests.push_back(current); + } + } + if (!m_requestInProgress.exchange(true)) { + BinaryNinja::WorkerPriorityEnqueue([this]() { + ProcessPendingFetchRequests(); + }); + } + } + UpdateMatches(); } @@ -162,3 +185,51 @@ void WarpCurrentFunctionWidget::UpdateMatches() m_tableWidget->SetFunctions(matches); } + +void WarpCurrentFunctionWidget::ProcessPendingFetchRequests() +{ + std::vector<FunctionRef> requests; + { + std::lock_guard<std::mutex> lock(m_requestMutex); + requests = std::move(m_pendingRequests); + m_pendingRequests.clear(); + } + + if (requests.empty()) { + m_requestInProgress = false; + return; + } + + auto start_time = std::chrono::high_resolution_clock::now(); + + std::vector<Warp::FunctionGUID> guids; + Warp::Ref<Warp::Target> target; + for (const auto& func : requests) { + // TODO: Need to send multiple requests if there is multiple targets. + if (!target) + target = Warp::Target::FromPlatform(*func->GetPlatform()); + if (const auto guid = Warp::GetAnalysisFunctionGUID(*func); guid.has_value()) + guids.push_back(guid.value()); + } + + // Actually fetch the data! + if (!guids.empty()) + for (const auto &container: Warp::Container::All()) + container->FetchFunctions(*target, guids); + + { + std::lock_guard<std::mutex> lock(m_requestMutex); + for (const auto& func : requests) { + m_processedFunctions.insert(func->GetStart()); + } + } + + // TODO: Update the matches, make sure there was stuff added first lol. + // TODO: UpdateMatches(); + + const auto end_time = std::chrono::high_resolution_clock::now(); + const std::chrono::duration<double> elapsed_time = end_time - start_time; + m_logger->LogDebug("ProcessPendingRequests took %f seconds", elapsed_time.count()); + + m_requestInProgress = false; +} diff --git a/plugins/warp/ui/matches.h b/plugins/warp/ui/matches.h index 4021f10c..251dcb89 100644 --- a/plugins/warp/ui/matches.h +++ b/plugins/warp/ui/matches.h @@ -16,6 +16,13 @@ class WarpCurrentFunctionWidget : public QWidget WarpFunctionTableWidget *m_tableWidget; WarpFunctionInfoWidget *m_infoWidget; + LoggerRef m_logger; + + std::mutex m_requestMutex; + std::vector<FunctionRef> m_pendingRequests; + std::atomic<bool> m_requestInProgress {false}; + std::unordered_set<uint64_t> m_processedFunctions; + public: explicit WarpCurrentFunctionWidget(FunctionRef current); @@ -26,4 +33,6 @@ public: FunctionRef GetCurrentFunction() { return m_current; }; void UpdateMatches(); + + void ProcessPendingFetchRequests(); }; diff --git a/plugins/warp/ui/plugin.cpp b/plugins/warp/ui/plugin.cpp index 69aaaf34..923a79b3 100644 --- a/plugins/warp/ui/plugin.cpp +++ b/plugins/warp/ui/plugin.cpp @@ -170,6 +170,9 @@ void WarpSidebarWidget::notifyViewChanged(ViewFrame *view) void WarpSidebarWidget::notifyViewLocationChanged(View *view, const ViewLocation &location) { + // Warp sidebar really should only update if it is visible, otherwise its a waste of cycles. + if (!this->isVisible()) + return; auto function = location.getFunction(); // TODO: Only update if the function exists? // NOTE: The function called will exit early if it is the same function. |
