1 /************************************************************************ 2 * file name : main_window.h 3 * ----------------- : 4 * creation time : 2016/06/26 5 * author : Victor Zarubkin 6 * email : v.s.zarubkin@gmail.com 7 * ----------------- : 8 * description : The file contains declaration of MainWindow for easy_profiler GUI. 9 * ----------------- : 10 * change log : * 2016/06/26 Victor Zarubkin: initial commit. 11 * : * 12 * ----------------- : 13 * license : Lightweight profiler library for c++ 14 * : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin 15 * : 16 * : Licensed under either of 17 * : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) 18 * : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) 19 * : at your option. 20 * : 21 * : The MIT License 22 * : 23 * : Permission is hereby granted, free of charge, to any person obtaining a copy 24 * : of this software and associated documentation files (the "Software"), to deal 25 * : in the Software without restriction, including without limitation the rights 26 * : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 27 * : of the Software, and to permit persons to whom the Software is furnished 28 * : to do so, subject to the following conditions: 29 * : 30 * : The above copyright notice and this permission notice shall be included in all 31 * : copies or substantial portions of the Software. 32 * : 33 * : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 34 * : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 36 * : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 37 * : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 38 * : USE OR OTHER DEALINGS IN THE SOFTWARE. 39 * : 40 * : The Apache License, Version 2.0 (the "License") 41 * : 42 * : You may not use this file except in compliance with the License. 43 * : You may obtain a copy of the License at 44 * : 45 * : http://www.apache.org/licenses/LICENSE-2.0 46 * : 47 * : Unless required by applicable law or agreed to in writing, software 48 * : distributed under the License is distributed on an "AS IS" BASIS, 49 * : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 * : See the License for the specific language governing permissions and 51 * : limitations under the License. 52 ************************************************************************/ 53 54 #ifndef EASY_PROFILER_GUI__MAIN_WINDOW__H 55 #define EASY_PROFILER_GUI__MAIN_WINDOW__H 56 57 #include <string> 58 #include <thread> 59 #include <atomic> 60 #include <sstream> 61 62 #include <QMainWindow> 63 #include <QDockWidget> 64 #include <QTimer> 65 #include <QStringList> 66 67 #include <easy/easy_socket.h> 68 #include <easy/reader.h> 69 70 #ifdef max 71 #undef max 72 #endif 73 74 #ifdef min 75 #undef min 76 #endif 77 78 ////////////////////////////////////////////////////////////////////////// 79 80 #define EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW 0 81 82 namespace profiler { namespace net { struct EasyProfilerStatus; } } 83 84 ////////////////////////////////////////////////////////////////////////// 85 86 class EasyFileReader Q_DECL_FINAL 87 { 88 ::profiler::SerializedData m_serializedBlocks; ///< 89 ::profiler::SerializedData m_serializedDescriptors; ///< 90 ::profiler::descriptors_list_t m_descriptors; ///< 91 ::profiler::blocks_t m_blocks; ///< 92 ::profiler::thread_blocks_tree_t m_blocksTree; ///< 93 ::std::stringstream m_stream; ///< 94 ::std::stringstream m_errorMessage; ///< 95 QString m_filename; ///< 96 uint32_t m_descriptorsNumberInFile = 0; ///< 97 uint32_t m_version = 0; ///< 98 ::std::thread m_thread; ///< 99 ::std::atomic_bool m_bDone; ///< 100 ::std::atomic<int> m_progress; ///< 101 ::std::atomic<unsigned int> m_size; ///< 102 bool m_isFile = false; ///< 103 104 public: 105 106 EasyFileReader(); 107 ~EasyFileReader(); 108 109 const bool isFile() const; 110 bool done() const; 111 int progress() const; 112 unsigned int size() const; 113 const QString& filename() const; 114 115 void load(const QString& _filename); 116 void load(::std::stringstream& _stream); 117 void interrupt(); 118 void get(::profiler::SerializedData& _serializedBlocks, ::profiler::SerializedData& _serializedDescriptors, 119 ::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree, 120 uint32_t& _descriptorsNumberInFile, uint32_t& _version, QString& _filename); 121 122 QString getError(); 123 124 }; // END of class EasyFileReader. 125 126 ////////////////////////////////////////////////////////////////////////// 127 128 enum EasyListenerRegime : uint8_t 129 { 130 LISTENER_IDLE = 0, 131 LISTENER_CAPTURE, 132 LISTENER_CAPTURE_RECEIVE, 133 LISTENER_DESCRIBE 134 }; 135 136 class EasySocketListener Q_DECL_FINAL 137 { 138 EasySocket m_easySocket; ///< 139 ::std::string m_address; ///< 140 ::std::stringstream m_receivedData; ///< 141 ::std::thread m_thread; ///< 142 uint64_t m_receivedSize; ///< 143 uint16_t m_port; ///< 144 ::std::atomic<uint32_t> m_frameMax; ///< 145 ::std::atomic<uint32_t> m_frameAvg; ///< 146 ::std::atomic_bool m_bInterrupt; ///< 147 ::std::atomic_bool m_bConnected; ///< 148 ::std::atomic_bool m_bStopReceive; ///< 149 ::std::atomic_bool m_bCaptureReady; ///< 150 ::std::atomic_bool m_bFrameTimeReady; ///< 151 EasyListenerRegime m_regime; ///< 152 153 public: 154 155 EasySocketListener(); 156 ~EasySocketListener(); 157 158 bool connected() const; 159 bool captured() const; 160 EasyListenerRegime regime() const; 161 uint64_t size() const; 162 const ::std::string& address() const; 163 uint16_t port() const; 164 165 ::std::stringstream& data(); 166 void clearData(); 167 168 void disconnect(); 169 void closeSocket(); 170 bool connect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply, bool _disconnectFirst = false); 171 bool reconnect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply); 172 173 bool startCapture(); 174 void stopCapture(); 175 void finalizeCapture(); 176 void requestBlocksDescription(); 177 178 bool frameTime(uint32_t& _maxTime, uint32_t& _avgTime); 179 bool requestFrameTime(); 180 181 template <class T> send(const T & _message)182 inline void send(const T& _message) 183 { 184 m_easySocket.send(&_message, sizeof(T)); 185 } 186 187 private: 188 189 void listenCapture(); 190 void listenDescription(); 191 void listenFrameTime(); 192 193 }; // END of class EasySocketListener. 194 195 ////////////////////////////////////////////////////////////////////////// 196 197 class EasyDockWidget : public QDockWidget 198 { 199 Q_OBJECT 200 public: 201 explicit EasyDockWidget(const QString& title, QWidget* parent = nullptr); 202 ~EasyDockWidget() override; 203 }; 204 205 class EasyMainWindow : public QMainWindow 206 { 207 Q_OBJECT 208 209 protected: 210 211 typedef EasyMainWindow This; 212 typedef QMainWindow Parent; 213 214 QStringList m_lastFiles; 215 QString m_theme; 216 QString m_lastAddress; 217 QDockWidget* m_treeWidget = nullptr; 218 QDockWidget* m_graphicsView = nullptr; 219 QDockWidget* m_fpsViewer = nullptr; 220 221 #if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0 222 QDockWidget* m_descTreeWidget = nullptr; 223 #endif 224 225 class QProgressDialog* m_progress = nullptr; 226 class QDialog* m_descTreeDialog = nullptr; 227 class EasyDescWidget* m_dialogDescTree = nullptr; 228 class QMessageBox* m_listenerDialog = nullptr; 229 QTimer m_readerTimer; 230 QTimer m_listenerTimer; 231 QTimer m_fpsRequestTimer; 232 ::profiler::SerializedData m_serializedBlocks; 233 ::profiler::SerializedData m_serializedDescriptors; 234 EasyFileReader m_reader; 235 EasySocketListener m_listener; 236 237 class QLineEdit* m_addressEdit = nullptr; 238 class QLineEdit* m_portEdit = nullptr; 239 class QLineEdit* m_frameTimeEdit = nullptr; 240 241 class QMenu* m_loadActionMenu = nullptr; 242 class QAction* m_saveAction = nullptr; 243 class QAction* m_deleteAction = nullptr; 244 245 class QAction* m_captureAction = nullptr; 246 class QAction* m_connectAction = nullptr; 247 class QAction* m_eventTracingEnableAction = nullptr; 248 class QAction* m_eventTracingPriorityAction = nullptr; 249 250 uint32_t m_descriptorsNumberInFile = 0; 251 uint16_t m_lastPort = 0; 252 bool m_bNetworkFileRegime = false; 253 bool m_bOpenedCacheFile = false; 254 255 public: 256 257 explicit EasyMainWindow(); 258 ~EasyMainWindow() override; 259 260 // Public virtual methods 261 262 void closeEvent(QCloseEvent* close_event) override; 263 void dragEnterEvent(QDragEnterEvent* drag_event) override; 264 void dragMoveEvent(QDragMoveEvent* drag_event) override; 265 void dragLeaveEvent(QDragLeaveEvent* drag_event) override; 266 void dropEvent(QDropEvent* drop_event) override; 267 268 protected slots: 269 270 void onThemeChange(bool); 271 void onOpenFileClicked(bool); 272 void onSaveFileClicked(bool); 273 void onDeleteClicked(bool); 274 void onExitClicked(bool); 275 void onEncodingChanged(bool); 276 void onChronoTextPosChanged(bool); 277 void onUnitsChanged(bool); 278 void onEnableDisableStatistics(bool); 279 void onCollapseItemsAfterCloseChanged(bool); 280 void onAllItemsExpandedByDefaultChange(bool); 281 void onBindExpandStatusChange(bool); 282 void onHierarchyFlagChange(bool); 283 void onExpandAllClicked(bool); 284 void onCollapseAllClicked(bool); 285 void onSpacingChange(int _value); 286 void onMinSizeChange(int _value); 287 void onNarrowSizeChange(int _value); 288 void onFpsIntervalChange(int _value); 289 void onFpsHistoryChange(int _value); 290 void onFpsMonitorLineWidthChange(int _value); 291 void onFileReaderTimeout(); 292 void onFrameTimeRequestTimeout(); 293 void onListenerTimerTimeout(); 294 void onFileReaderCancel(); 295 void onEditBlocksClicked(bool); 296 void onDescTreeDialogClose(int); 297 void onListenerDialogClose(int); 298 void onCaptureClicked(bool); 299 void onGetBlockDescriptionsClicked(bool); 300 void onConnectClicked(bool); 301 void onEventTracingPriorityChange(bool _checked); 302 void onEventTracingEnableChange(bool _checked); 303 void onFrameTimeEditFinish(); 304 void onFrameTimeChanged(); 305 306 void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); 307 308 void checkFrameTimeReady(); 309 310 private: 311 312 // Private non-virtual methods 313 314 void clear(); 315 316 void refreshDiagram(); 317 318 void addFileToList(const QString& filename); 319 void loadFile(const QString& filename); 320 void readStream(::std::stringstream& data); 321 322 void loadSettings(); 323 void loadGeometry(); 324 void saveSettingsAndGeometry(); 325 326 void setDisconnected(bool _showMessage = true); 327 328 void destroyProgressDialog(); 329 void createProgressDialog(const QString& text); 330 331 }; // END of class EasyMainWindow. 332 333 ////////////////////////////////////////////////////////////////////////// 334 335 #endif // EASY_PROFILER_GUI__MAIN_WINDOW__H 336