diff options
Diffstat (limited to 'plugins/warp/ui/matches.cpp')
| -rw-r--r-- | plugins/warp/ui/matches.cpp | 89 |
1 files changed, 25 insertions, 64 deletions
diff --git a/plugins/warp/ui/matches.cpp b/plugins/warp/ui/matches.cpp index 7e22e224..2345a7ea 100644 --- a/plugins/warp/ui/matches.cpp +++ b/plugins/warp/ui/matches.cpp @@ -11,12 +11,12 @@ #include "warp.h" #include "shared/misc.h" -WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(FunctionRef current) +WarpCurrentFunctionWidget::WarpCurrentFunctionWidget() { - // NOTE: Might be nullptr if the no selected function. - m_current = current; + // We must explicitly support no current function. + m_current = nullptr; - m_logger = new BinaryNinja::Logger("WARP"); + m_logger = new BinaryNinja::Logger("WARP UI"); // Create the QT stuff QGridLayout *layout = new QGridLayout(this); @@ -107,6 +107,18 @@ WarpCurrentFunctionWidget::WarpCurrentFunctionWidget(FunctionRef current) }); } +void WarpCurrentFunctionWidget::SetFetcher(std::shared_ptr<WarpFetcher> fetcher) +{ + m_fetcher = fetcher; + // TODO: We need to remove the completion callback from the previously set fetcher. + m_fetcher->AddCompletionCallback([this]() { + // TODO: This is a little bit underspecified, we may end up updating more than strictly necessary. + // Once this function has been fetched, we need to update the matches for this widget. + UpdateMatches(); + return KeepCallback; + }); +} + void WarpCurrentFunctionWidget::SetCurrentFunction(FunctionRef current) { if (m_current == current) @@ -114,21 +126,18 @@ void WarpCurrentFunctionWidget::SetCurrentFunction(FunctionRef current) m_current = current; m_infoWidget->SetAnalysisFunction(m_current); - if (current) + // If we have a fetcher we should also let it know to try and fetch the possible functions from the containers. + if (current && m_fetcher) { - // 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! + m_fetcher->AddPendingFunction(current); + + // TODO: Automatically fetch the function, I need to figure out how to make this debounce correctly so that all requests are processed in line. + if (!m_fetcher->m_requestInProgress.exchange(true)) { - 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(); + BinaryNinja::Ref bgTask = new BinaryNinja::BackgroundTask("Fetching WARP Functions...", true); + m_fetcher->FetchPendingFunctions(); + bgTask->Finish(); }); } } @@ -185,51 +194,3 @@ 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; -} |
