diff --git a/src/osgEarth/URI.cpp b/src/osgEarth/URI.cpp index 6700ba9792..d7d427dfa0 100644 --- a/src/osgEarth/URI.cpp +++ b/src/osgEarth/URI.cpp @@ -533,7 +533,7 @@ namespace //osg::Timer_t startTime = osg::Timer::instance()->tick(); - unsigned long handle = NetworkMonitor::begin(inputURI.full(), "pending", "URI"); + unsigned long handle = NetworkMonitor::begin(inputURI.full(), "Pending", "URI"); ReadResult result; if (osgEarth::Registry::instance()->isBlacklisted(inputURI.full())) diff --git a/src/osgEarthImGui/NetworkMonitorGUI b/src/osgEarthImGui/NetworkMonitorGUI index 35dc66cde6..7cf96780d6 100644 --- a/src/osgEarthImGui/NetworkMonitorGUI +++ b/src/osgEarthImGui/NetworkMonitorGUI @@ -24,11 +24,30 @@ namespace osgEarth { class NetworkMonitorGUI : public ImGuiPanel { + + enum TypeFilter + { + TYPEFILTER_ALL = 0, + TYPEFILTER_URI = 1, + TYPEFILTER_CACHE = 2 + }; + + enum RequestStatus + { + REQUESTSTATUS_ALL = 0, + REQUESTSTATUS_OK = 1, + REQUESTSTATUS_NOTFOUND = 2, + REQUESTSTATUS_ERROR = 3, + REQUESTSTATUS_BLACKLISTED = 4, + REQUESTSTATUS_CANCELED = 5, + REQUESTSTATUS_PENDING = 6 + }; + public: NetworkMonitorGUI() : ImGuiPanel("Network Monitor"), - _showOnlyActiveRequests(true), - _showOnlyFailedRequests(false) + _typeFilter(TYPEFILTER_ALL), + _statusFilter(REQUESTSTATUS_ALL) { memset(_filter, 0, sizeof(_filter)); } @@ -49,12 +68,26 @@ namespace osgEarth std::set< std::string > uniqueURLs; double minTime = DBL_MAX; - double maxTime = 0.0; + double maxTime = 0.0; + + double now = osg::Timer::instance()->tick(); + std::string filterLower = osgEarth::toLower(_filter); - ImGui::Checkbox("Active", &_showOnlyActiveRequests); + ImGui::SameLine(); + ImGui::SetNextItemWidth(500); + ImGui::InputText("Filter", _filter, 128); + const float combo_buffer = 50; + + const char* requestStatus[] = { "All", "OK", "Not Found", "Error", "Blacklisted", "Canceled", "Pending"}; ImGui::SameLine(); - ImGui::Checkbox("Failed", &_showOnlyFailedRequests); + ImGui::SetNextItemWidth(ImGui::CalcTextSize("Blacklisted").x + combo_buffer); + ImGui::Combo("Status", &_statusFilter, requestStatus, IM_ARRAYSIZE(requestStatus)); + + const char* requestTypes[] = { "All", "URI", "Cache" }; + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::CalcTextSize("Cache").x + combo_buffer); + ImGui::Combo("Type", &_typeFilter, requestTypes, IM_ARRAYSIZE(requestTypes)); ImGui::SameLine(); if (ImGui::Button("Clear")) @@ -66,48 +99,56 @@ namespace osgEarth if (ImGui::Button("Save")) { NetworkMonitor::saveCSV(requests, "network_requests.csv"); - } - - ImGui::SameLine(); - ImGui::InputText("Filter", _filter, 128); + } ImVec2 availableContent = ImGui::GetContentRegionAvail(); ImVec2 textSize = ImGui::CalcTextSize("A"); - ImGui::BeginChild("Columns", ImVec2(0, availableContent.y - textSize.y)); + ImVec2 tableSize(0, availableContent.y - textSize.y); - ImGui::Columns(5, "requests"); + if (ImGui::BeginTable("RequestTable", 5, ImGuiTableFlags_ScrollY | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders, tableSize)) + { + ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible + ImGui::TableSetupColumn("Layer", ImGuiTableColumnFlags_WidthFixed, 300.0f); + ImGui::TableSetupColumn("Time(ms)", ImGuiTableColumnFlags_WidthFixed, 100.0f); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, 100.0f); + ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 100.0f); + ImGui::TableSetupColumn("Path", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableHeadersRow(); + + for (NetworkMonitor::Requests::iterator itr = requests.begin(); itr != requests.end(); ++itr) + { + // Compute the min and max time for all requests + double requestStartTime = itr->second.startTime; + double requestEndTime = itr->second.isComplete ? itr->second.endTime : now; + if (requestStartTime < minTime) + minTime = requestStartTime; - ImGui::SetColumnWidth(0, 300.f); - ImGui::SetColumnWidth(1, 100.f); - ImGui::SetColumnWidth(2, 100.f); - ImGui::SetColumnWidth(3, 100.f); + if (requestEndTime > maxTime) + maxTime = requestEndTime; - ImGui::Separator(); - ImGui::Text("Layer"); ImGui::NextColumn(); - ImGui::Text("Time(ms)"); ImGui::NextColumn(); - ImGui::Text("Type"); ImGui::NextColumn(); - ImGui::Text("Status"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Separator(); + // Filter based on status + if (_statusFilter != REQUESTSTATUS_ALL) + { + if (_statusFilter == REQUESTSTATUS_OK && itr->second.status.find("OK") == std::string::npos) + continue; - double now = osg::Timer::instance()->tick(); + if (_statusFilter == REQUESTSTATUS_NOTFOUND && itr->second.status.find("Target not found") == std::string::npos) + continue; - std::string filterLower = osgEarth::toLower(_filter); + if (_statusFilter == REQUESTSTATUS_BLACKLISTED && itr->second.status.find("Blacklisted") == std::string::npos) + continue; - for (NetworkMonitor::Requests::iterator itr = requests.begin(); itr != requests.end(); ++itr) - { - // Compute the min and max time for all requests - double requestStartTime = itr->second.startTime; - double requestEndTime = itr->second.isComplete ? itr->second.endTime : now; - if (requestStartTime < minTime) - minTime = requestStartTime; + if (_statusFilter == REQUESTSTATUS_ERROR && itr->second.status.find("error") == std::string::npos) + continue; - if (requestEndTime > maxTime) - maxTime = requestEndTime; + if (_statusFilter == REQUESTSTATUS_CANCELED && itr->second.status.find("Canceled") == std::string::npos) + continue; + + if (_statusFilter == REQUESTSTATUS_PENDING && itr->second.status.find("Pending") == std::string::npos) + continue; + } - if (!_showOnlyActiveRequests || !itr->second.isComplete) - { if (!filterLower.empty()) { std::string uriLower = osgEarth::toLower(itr->second.uri); @@ -124,8 +165,18 @@ namespace osgEarth } } - uniqueURLs.insert(itr->second.uri); - ++filteredCount; + bool showCache = _typeFilter == TYPEFILTER_ALL || _typeFilter == TYPEFILTER_CACHE; + bool showURI = _typeFilter == TYPEFILTER_ALL || _typeFilter == TYPEFILTER_URI; + + if (!showCache && itr->second.type == "Cache") + { + continue; + } + + if (!showURI && itr->second.type == "URI") + { + continue; + } ImVec4 color = ImVec4(1.0, 1.0, 1.0, 1.0); bool failed = false; @@ -149,20 +200,27 @@ namespace osgEarth } } - if (_showOnlyFailedRequests && !failed) - continue; - - ImGui::PushID(itr->first); + uniqueURLs.insert(itr->second.uri); + ++filteredCount; + ImGui::PushID(itr->first); + ImGui::TableNextColumn(); ImGui::Text(itr->second.layer.c_str()); ImGui::NextColumn(); char buf[64]; sprintf(buf, "%.1lf", itr->second.getDuration()); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetColumnWidth() - ImGui::CalcTextSize(buf).x - ImGui::GetScrollX() - 2 * ImGui::GetStyle().ItemSpacing.x); - ImGui::Text(buf); ImGui::NextColumn(); - ImGui::Text(itr->second.type.c_str()); ImGui::NextColumn(); - ImGui::Text(itr->second.status.c_str()); ImGui::NextColumn(); + ImGui::TableNextColumn(); + ImGui::Text(buf); + + ImGui::TableNextColumn(); + ImGui::Text(itr->second.type.c_str()); + + ImGui::TableNextColumn(); + ImGui::Text(itr->second.status.c_str()); + + ImGui::TableNextColumn(); if (ImGui::SmallButton("Copy")) { ImGui::SetClipboardText(itr->second.uri.c_str()); @@ -170,28 +228,26 @@ namespace osgEarth ImGui::SameLine(); ImGui::TextColored(color, "%s (%d)", itr->second.uri.c_str(), itr->second.count); ImGui::NextColumn(); ImGui::PopID(); - } - } - ImGui::Columns(1); - ImGui::Separator(); + } - // Keep scroll position at the bottom so we can see new network requests as they come in if they are scrolled to the bottom already - if (ImGui::GetScrollY() == ImGui::GetScrollMaxY()) - { - ImGui::SetScrollHereY(1.0); + // Keep scroll position at the bottom so we can see new network requests as they come in if they are scrolled to the bottom already + if (ImGui::GetScrollY() == ImGui::GetScrollMaxY()) + { + ImGui::SetScrollHereY(1.0); + } + ImGui::EndTable(); } - ImGui::EndChild(); double totalTime = maxTime > minTime ? osg::Timer::instance()->delta_s(minTime, maxTime) : 0.0; - if (filterLower.empty()) + if (filterLower.empty() && _typeFilter == TYPEFILTER_ALL && _statusFilter == REQUESTSTATUS_ALL) { ImGui::Text("%d requests | unique %d | %.1f s", requests.size(), uniqueURLs.size(), totalTime); } else { ImGui::Text("%d / %d requests | unique %d | %.1f s", filteredCount, requests.size(), uniqueURLs.size(), totalTime); - } + } ImGui::End(); } @@ -201,8 +257,8 @@ namespace osgEarth } } - bool _showOnlyActiveRequests; - bool _showOnlyFailedRequests; + int _typeFilter; + int _statusFilter; char _filter[128]; }; }