/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2018 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #pragma once #include #include namespace osgEarth { class NetworkMonitorGUI : public ImGuiPanel { public: NetworkMonitorGUI() : ImGuiPanel("Network Monitor"), _showOnlyActiveRequests(true), _showOnlyFailedRequests(false) { memset(_filter, 0, sizeof(_filter)); } void draw(osg::RenderInfo& ri) override { if (!isVisible()) return; if (ImGui::Begin(name(), visible())) { NetworkMonitor::setEnabled(true); NetworkMonitor::Requests requests; NetworkMonitor::getRequests(requests); // Compute the time duration for all of the requests osg::Timer_t startTime; double totalTime = 0.0; if (!requests.empty()) { startTime = requests.begin()->second.startTime; if (requests.rbegin()->second.isComplete) { totalTime = osg::Timer::instance()->delta_m(startTime, requests.rbegin()->second.endTime); } else { totalTime = osg::Timer::instance()->delta_m(startTime, osg::Timer::instance()->tick()); } } ImGui::Checkbox("Active", &_showOnlyActiveRequests); ImGui::SameLine(); ImGui::Checkbox("Failed", &_showOnlyFailedRequests); ImGui::SameLine(); if (ImGui::Button("Clear")) { NetworkMonitor::clear(); } ImGui::SameLine(); if (ImGui::Button("Save")) { NetworkMonitor::saveCSV(requests, "network_requests.csv"); } ImGui::SameLine(); ImGui::InputText("Filter", _filter, 128); ImGui::Text("%d requests", requests.size()); ImGui::SameLine(); ImGui::Text("Total time = %.1f s", totalTime / 1000.0); ImGui::BeginChild("Columns"); ImGui::Columns(5, "requests"); ImGui::SetColumnWidth(0, 300.f); ImGui::SetColumnWidth(1, 100.f); ImGui::SetColumnWidth(2, 100.f); ImGui::SetColumnWidth(3, 100.f); //ImGui::SetColumnWidth(0, 100.f); ImGui::Separator(); //ImGui::Text("Start time"); ImGui::NextColumn(); //ImGui::Text("End time"); ImGui::NextColumn(); 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(); std::string filterLower = osgEarth::toLower(_filter); for (NetworkMonitor::Requests::iterator itr = requests.begin(); itr != requests.end(); ++itr) { if (!_showOnlyActiveRequests || !itr->second.isComplete) { if (!filterLower.empty()) { std::string uriLower = osgEarth::toLower(itr->second.uri); std::string statusLower = osgEarth::toLower(itr->second.status); std::string layerLower = osgEarth::toLower(itr->second.layer); std::string typeLower = osgEarth::toLower(itr->second.type); if (strstr(uriLower.c_str(), filterLower.c_str()) == NULL && strstr(statusLower.c_str(), filterLower.c_str()) == NULL && strstr(layerLower.c_str(), filterLower.c_str()) == NULL && strstr(typeLower.c_str(), filterLower.c_str()) == NULL) { continue; } } ImVec4 color = ImVec4(1.0, 1.0, 1.0, 1.0); bool failed = false; bool canceled = false; if (itr->second.isComplete) { if (itr->second.status.find("OK") != std::string::npos) { color = ImVec4(0, 1, 0, 1); // green } else if (itr->second.status.find("Canceled") != std::string::npos) { color = ImVec4(.5, .5, .5, 1); // grey canceled = true; } else { // Color bad requests red color = ImVec4(1, 0, 0, 1); failed = true; } } if (_showOnlyFailedRequests && !failed) continue; ImGui::PushID(itr->first); //double startMS = osg::Timer::instance()->delta_m(startTime, itr->second.startTime); //double endMS = 0.0; //if (itr->second.isComplete) //{ // endMS = osg::Timer::instance()->delta_m(startTime, itr->second.endTime); //} //else //{ // endMS = osg::Timer::instance()->delta_m(startTime, osg::Timer::instance()->tick()); //} 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("%.2lf ms", startMS); ImGui::NextColumn(); //ImGui::Text("%.2lf ms", endMS); ImGui::NextColumn(); ImGui::Text(itr->second.type.c_str()); ImGui::NextColumn(); ImGui::Text(itr->second.status.c_str()); ImGui::NextColumn(); if (ImGui::SmallButton("Copy")) { ImGui::SetClipboardText(itr->second.uri.c_str()); } 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); } ImGui::EndChild(); ImGui::End(); } else { NetworkMonitor::setEnabled(false); } } bool _showOnlyActiveRequests; bool _showOnlyFailedRequests; char _filter[128]; }; }