mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 08:01:51 +08:00
#31 [GUI] Arbitrary values viewer progress
This commit is contained in:
parent
ef7d9f0bad
commit
d24e4a9e7e
@ -141,7 +141,7 @@ namespace profiler {
|
||||
BlocksTree(const This&) = delete;
|
||||
This& operator = (const This&) = delete;
|
||||
|
||||
BlocksTree()
|
||||
BlocksTree() EASY_NOEXCEPT
|
||||
: node(nullptr)
|
||||
, per_parent_stats(nullptr)
|
||||
, per_frame_stats(nullptr)
|
||||
@ -151,32 +151,33 @@ namespace profiler {
|
||||
|
||||
}
|
||||
|
||||
BlocksTree(This&& that) : BlocksTree()
|
||||
BlocksTree(This&& that) EASY_NOEXCEPT
|
||||
: BlocksTree()
|
||||
{
|
||||
make_move(::std::forward<This&&>(that));
|
||||
}
|
||||
|
||||
This& operator = (This&& that)
|
||||
This& operator = (This&& that) EASY_NOEXCEPT
|
||||
{
|
||||
make_move(::std::forward<This&&>(that));
|
||||
return *this;
|
||||
}
|
||||
|
||||
~BlocksTree()
|
||||
~BlocksTree() EASY_NOEXCEPT
|
||||
{
|
||||
release_stats(per_thread_stats);
|
||||
release_stats(per_parent_stats);
|
||||
release_stats(per_frame_stats);
|
||||
}
|
||||
|
||||
bool operator < (const This& other) const
|
||||
bool operator < (const This& other) const EASY_NOEXCEPT
|
||||
{
|
||||
if (node == nullptr || other.node == nullptr)
|
||||
return false;
|
||||
return node->begin() < other.node->begin();
|
||||
}
|
||||
|
||||
void shrink_to_fit()
|
||||
void shrink_to_fit() EASY_NOEXCEPT
|
||||
{
|
||||
//for (auto& child : children)
|
||||
// child.shrink_to_fit();
|
||||
@ -193,7 +194,7 @@ namespace profiler {
|
||||
|
||||
private:
|
||||
|
||||
void make_move(This&& that)
|
||||
void make_move(This&& that) EASY_NOEXCEPT
|
||||
{
|
||||
if (per_thread_stats != that.per_thread_stats)
|
||||
release_stats(per_thread_stats);
|
||||
@ -241,11 +242,12 @@ namespace profiler {
|
||||
BlocksTreeRoot(const This&) = delete;
|
||||
This& operator = (const This&) = delete;
|
||||
|
||||
BlocksTreeRoot() : profiled_time(0), wait_time(0), thread_id(0), frames_number(0), blocks_number(0), depth(0)
|
||||
BlocksTreeRoot() EASY_NOEXCEPT
|
||||
: profiled_time(0), wait_time(0), thread_id(0), frames_number(0), blocks_number(0), depth(0)
|
||||
{
|
||||
}
|
||||
|
||||
BlocksTreeRoot(This&& that)
|
||||
BlocksTreeRoot(This&& that) EASY_NOEXCEPT
|
||||
: children(::std::move(that.children))
|
||||
, sync(::std::move(that.sync))
|
||||
, events(::std::move(that.events))
|
||||
@ -259,7 +261,7 @@ namespace profiler {
|
||||
{
|
||||
}
|
||||
|
||||
This& operator = (This&& that)
|
||||
This& operator = (This&& that) EASY_NOEXCEPT
|
||||
{
|
||||
children = ::std::move(that.children);
|
||||
sync = ::std::move(that.sync);
|
||||
@ -274,26 +276,25 @@ namespace profiler {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool got_name() const
|
||||
inline bool got_name() const EASY_NOEXCEPT
|
||||
{
|
||||
return !thread_name.empty();
|
||||
}
|
||||
|
||||
inline const char* name() const
|
||||
inline const char* name() const EASY_NOEXCEPT
|
||||
{
|
||||
return thread_name.c_str();
|
||||
}
|
||||
|
||||
bool operator < (const This& other) const
|
||||
bool operator < (const This& other) const EASY_NOEXCEPT
|
||||
{
|
||||
return thread_id < other.thread_id;
|
||||
}
|
||||
|
||||
}; // END of class BlocksTreeRoot.
|
||||
|
||||
typedef ::profiler::BlocksTree::blocks_t blocks_t;
|
||||
|
||||
typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::profiler::passthrough_hash<::profiler::thread_id_t> > thread_blocks_tree_t;
|
||||
using blocks_t = ::profiler::BlocksTree::blocks_t;
|
||||
using thread_blocks_tree_t = ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::profiler::passthrough_hash<::profiler::thread_id_t> >;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -388,7 +389,7 @@ namespace profiler {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef ::std::vector<SerializedBlockDescriptor*> descriptors_list_t;
|
||||
using descriptors_list_t = ::std::vector<SerializedBlockDescriptor*>;
|
||||
|
||||
} // END of namespace profiler.
|
||||
|
||||
|
@ -193,6 +193,9 @@ namespace profiler {
|
||||
|
||||
public:
|
||||
|
||||
using BaseBlockData::id;
|
||||
using Event::begin;
|
||||
|
||||
~ArbitraryValue() = delete;
|
||||
|
||||
const char* data() const {
|
||||
|
@ -12,6 +12,8 @@ if (Qt5Widgets_FOUND)
|
||||
endif ()
|
||||
add_executable(profiler_gui ${APPLICATION_PLATFORM}
|
||||
main.cpp
|
||||
arbitrary_value_inspector.h
|
||||
arbitrary_value_inspector.cpp
|
||||
blocks_graphics_view.h
|
||||
blocks_graphics_view.cpp
|
||||
blocks_tree_widget.h
|
||||
|
345
profiler_gui/arbitrary_value_inspector.cpp
Normal file
345
profiler_gui/arbitrary_value_inspector.cpp
Normal file
@ -0,0 +1,345 @@
|
||||
/************************************************************************
|
||||
* file name : arbitrary_value_inspector.cpp
|
||||
* ----------------- :
|
||||
* creation time : 2017/11/30
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains implementation of .
|
||||
* ----------------- :
|
||||
* change log : * 2017/11/30 Victor Zarubkin: initial commit.
|
||||
* :
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* : at your option.
|
||||
* :
|
||||
* : The MIT License
|
||||
* :
|
||||
* : Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* : of this software and associated documentation files (the "Software"), to deal
|
||||
* : in the Software without restriction, including without limitation the rights
|
||||
* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* : of the Software, and to permit persons to whom the Software is furnished
|
||||
* : to do so, subject to the following conditions:
|
||||
* :
|
||||
* : The above copyright notice and this permission notice shall be included in all
|
||||
* : copies or substantial portions of the Software.
|
||||
* :
|
||||
* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* : USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* :
|
||||
* : The Apache License, Version 2.0 (the "License")
|
||||
* :
|
||||
* : You may not use this file except in compliance with the License.
|
||||
* : You may obtain a copy of the License at
|
||||
* :
|
||||
* : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* :
|
||||
* : Unless required by applicable law or agreed to in writing, software
|
||||
* : distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* : See the License for the specific language governing permissions and
|
||||
* : limitations under the License.
|
||||
************************************************************************/
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsScene>
|
||||
#include <QColor>
|
||||
#include <list>
|
||||
#include "arbitrary_value_inspector.h"
|
||||
#include "globals.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArbitraryValuesCollection::ArbitraryValuesCollection()
|
||||
{
|
||||
m_bReady = ATOMIC_VAR_INIT(false);
|
||||
m_bInterrupt = ATOMIC_VAR_INIT(false);
|
||||
}
|
||||
|
||||
ArbitraryValuesCollection::~ArbitraryValuesCollection()
|
||||
{
|
||||
interrupt();
|
||||
}
|
||||
|
||||
const ArbitraryValuesMap& ArbitraryValuesCollection::valuesMap() const
|
||||
{
|
||||
return m_values;
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::ready() const
|
||||
{
|
||||
return m_bReady.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
size_t ArbitraryValuesCollection::size() const
|
||||
{
|
||||
size_t totalSize = 0;
|
||||
for (const auto& it : m_values)
|
||||
totalSize += it.second.size();
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName)
|
||||
{
|
||||
using This = ArbitraryValuesCollection;
|
||||
|
||||
interrupt();
|
||||
setReady(false);
|
||||
m_values.clear();
|
||||
|
||||
if (_valueId == 0)
|
||||
m_collectorThread = std::thread(&This::collectByName, this, _threadId, _valueName);
|
||||
else
|
||||
m_collectorThread = std::thread(&This::collectById, this, _threadId, _valueId);
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::interrupt()
|
||||
{
|
||||
if (!m_collectorThread.joinable())
|
||||
return;
|
||||
|
||||
m_bInterrupt.store(true, std::memory_order_release);
|
||||
m_collectorThread.join();
|
||||
m_bInterrupt.store(false, std::memory_order_release);
|
||||
|
||||
setReady(true);
|
||||
m_values.clear();
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::setReady(bool _ready)
|
||||
{
|
||||
m_bReady.store(_ready, std::memory_order_release);
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId)
|
||||
{
|
||||
if (_threadId == 0)
|
||||
{
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
if (!collectByIdForThread(it.first, _valueId))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!collectByIdForThread(_threadId, _valueId))
|
||||
return;
|
||||
}
|
||||
|
||||
setReady(true);
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::collectByIdForThread(profiler::thread_id_t _threadId, profiler::vin_t _valueId)
|
||||
{
|
||||
const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId);
|
||||
if (t == EASY_GLOBALS.profiler_blocks.end())
|
||||
return true;
|
||||
|
||||
const auto& profThread = t->second;
|
||||
auto& valuesList = m_values[_threadId];
|
||||
|
||||
for (auto i : profThread.events)
|
||||
{
|
||||
if (m_bInterrupt.load(std::memory_order_acquire))
|
||||
return false;
|
||||
|
||||
const auto& block = easyBlock(i).tree;
|
||||
const auto& desc = easyDescriptor(block.node->id());
|
||||
if (desc.type() != profiler::BlockType::Value)
|
||||
continue;
|
||||
|
||||
const auto value = block.value;
|
||||
if (value->value_id() != _valueId)
|
||||
continue;
|
||||
|
||||
valuesList.push_back(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, const std::string _valueName)
|
||||
{
|
||||
if (_threadId == 0)
|
||||
{
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
if (!collectByNameForThread(it.first, _valueName))
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!collectByNameForThread(_threadId, _valueName))
|
||||
return;
|
||||
}
|
||||
|
||||
setReady(true);
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::collectByNameForThread(profiler::thread_id_t _threadId, const std::string& _valueName)
|
||||
{
|
||||
const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId);
|
||||
if (t == EASY_GLOBALS.profiler_blocks.end())
|
||||
return true;
|
||||
|
||||
const auto& profThread = t->second;
|
||||
auto& valuesList = m_values[_threadId];
|
||||
|
||||
for (auto i : profThread.events)
|
||||
{
|
||||
if (m_bInterrupt.load(std::memory_order_acquire))
|
||||
return false;
|
||||
|
||||
const auto& block = easyBlock(i).tree;
|
||||
const auto& desc = easyDescriptor(block.node->id());
|
||||
if (desc.type() != profiler::BlockType::Value || _valueName != desc.name())
|
||||
continue;
|
||||
|
||||
valuesList.push_back(block.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EasyArbitraryValueInspector::EasyArbitraryValueInspector(QWidget* _parent)
|
||||
: Parent(_parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
EasyArbitraryValueInspector::~EasyArbitraryValueInspector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EasyArbitraryValueItem::EasyArbitraryValueItem(const ::profiler::ArbitraryValue& _value, profiler::thread_id_t _threadId)
|
||||
: Parent(nullptr)
|
||||
, m_scale(1)
|
||||
, m_color(0)
|
||||
{
|
||||
QObject::connect(&m_timer, &QTimer::timeout, [this] { onTimeout(); });
|
||||
m_collection.collectValues(_threadId, _value.value_id(), easyDescriptor(_value.id()).name());
|
||||
m_timer.start(40);
|
||||
}
|
||||
|
||||
EasyArbitraryValueItem::~EasyArbitraryValueItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EasyArbitraryValueItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*, QWidget*)
|
||||
{
|
||||
if (m_points.empty())
|
||||
return;
|
||||
|
||||
_painter->save();
|
||||
|
||||
auto pen = _painter->pen();
|
||||
pen.setColor(QColor::fromRgba(m_color));
|
||||
pen.setWidth(2);
|
||||
_painter->setPen(pen);
|
||||
|
||||
if (m_points.size() == 1)
|
||||
_painter->drawPoint(m_points.front());
|
||||
else
|
||||
_painter->drawPolyline(m_points.data(), static_cast<int>(m_points.size()));
|
||||
|
||||
_painter->restore();
|
||||
}
|
||||
|
||||
void EasyArbitraryValueItem::onScaleChanged(qreal _scale)
|
||||
{
|
||||
const auto k = _scale / m_scale;
|
||||
for (auto& p : m_points)
|
||||
p.setX(p.x() * k);
|
||||
m_scale = _scale;
|
||||
}
|
||||
|
||||
void EasyArbitraryValueItem::onTimeout()
|
||||
{
|
||||
if (!m_collection.ready())
|
||||
return;
|
||||
|
||||
m_timer.stop();
|
||||
|
||||
const auto size = m_collection.size();
|
||||
m_points.clear();
|
||||
m_points.reserve(size);
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
const auto& valuesByThread = m_collection.valuesMap();
|
||||
|
||||
if (valuesByThread.size() == 1)
|
||||
{
|
||||
const auto& values = valuesByThread.begin()->second;
|
||||
|
||||
m_color = 0;
|
||||
for (auto value : values)
|
||||
{
|
||||
if (m_color == 0)
|
||||
m_color = easyDescriptor(values.front()->id()).color();
|
||||
|
||||
// TODO: calculate y
|
||||
const auto x = sceneX(value->begin());
|
||||
m_points.emplace_back(x, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<profiler::thread_id_t> threadIds;
|
||||
for (const auto& it : valuesByThread)
|
||||
threadIds.push_back(it.first);
|
||||
|
||||
m_color = 0;
|
||||
size_t i = 0;
|
||||
while (!threadIds.empty())
|
||||
{
|
||||
for (auto it = threadIds.begin(); it != threadIds.end();)
|
||||
{
|
||||
const auto& values = valuesByThread.at(*it);
|
||||
if (i >= values.size())
|
||||
{
|
||||
it = threadIds.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_color == 0)
|
||||
m_color = easyDescriptor(values.front()->id()).color();
|
||||
|
||||
// TODO: calculate y
|
||||
const auto x = sceneX(values[i]->begin());
|
||||
m_points.emplace_back(x, 0);
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_points.begin(), m_points.end(), [](const QPointF& lhs, const QPointF& rhs) -> bool {
|
||||
return lhs.x() < rhs.x();
|
||||
});
|
||||
}
|
||||
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
151
profiler_gui/arbitrary_value_inspector.h
Normal file
151
profiler_gui/arbitrary_value_inspector.h
Normal file
@ -0,0 +1,151 @@
|
||||
/************************************************************************
|
||||
* file name : arbitrary_value_inspector.h
|
||||
* ----------------- :
|
||||
* creation time : 2017/11/30
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains declaration of .
|
||||
* ----------------- :
|
||||
* change log : * 2017/11/30 Victor Zarubkin: initial commit.
|
||||
* :
|
||||
* : *
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016-2017 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : Licensed under either of
|
||||
* : * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT)
|
||||
* : * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* : at your option.
|
||||
* :
|
||||
* : The MIT License
|
||||
* :
|
||||
* : Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* : of this software and associated documentation files (the "Software"), to deal
|
||||
* : in the Software without restriction, including without limitation the rights
|
||||
* : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* : of the Software, and to permit persons to whom the Software is furnished
|
||||
* : to do so, subject to the following conditions:
|
||||
* :
|
||||
* : The above copyright notice and this permission notice shall be included in all
|
||||
* : copies or substantial portions of the Software.
|
||||
* :
|
||||
* : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* : PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* : TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* : USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* :
|
||||
* : The Apache License, Version 2.0 (the "License")
|
||||
* :
|
||||
* : You may not use this file except in compliance with the License.
|
||||
* : You may obtain a copy of the License at
|
||||
* :
|
||||
* : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* :
|
||||
* : Unless required by applicable law or agreed to in writing, software
|
||||
* : distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* : See the License for the specific language governing permissions and
|
||||
* : limitations under the License.
|
||||
************************************************************************/
|
||||
|
||||
#ifndef EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H
|
||||
#define EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QGraphicsItem>
|
||||
#include <QTimer>
|
||||
#include <QPointF>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <easy/serialized_block.h>
|
||||
#include <easy/reader.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using ArbitraryValues = std::vector<const profiler::ArbitraryValue*>;
|
||||
using ArbitraryValuesMap = std::unordered_map<profiler::thread_id_t, ArbitraryValues, profiler::passthrough_hash<profiler::thread_id_t> >;
|
||||
|
||||
class ArbitraryValuesCollection EASY_FINAL
|
||||
{
|
||||
ArbitraryValuesMap m_values;
|
||||
std::thread m_collectorThread;
|
||||
std::atomic_bool m_bReady;
|
||||
std::atomic_bool m_bInterrupt;
|
||||
|
||||
public:
|
||||
|
||||
explicit ArbitraryValuesCollection();
|
||||
~ArbitraryValuesCollection();
|
||||
|
||||
const ArbitraryValuesMap& valuesMap() const;
|
||||
bool ready() const;
|
||||
size_t size() const;
|
||||
|
||||
void collectValues(profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName);
|
||||
void interrupt();
|
||||
|
||||
private:
|
||||
|
||||
void setReady(bool _ready);
|
||||
void collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId);
|
||||
void collectByName(profiler::thread_id_t _threadId, const std::string _valueName);
|
||||
bool collectByIdForThread(profiler::thread_id_t _threadId, profiler::vin_t _valueId);
|
||||
bool collectByNameForThread(profiler::thread_id_t _threadId, const std::string& _valueName);
|
||||
|
||||
}; // end of class ArbitraryValuesCollection.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EasyArbitraryValueInspector : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using Parent = QWidget;
|
||||
using This = EasyArbitraryValueInspector;
|
||||
|
||||
public:
|
||||
|
||||
explicit EasyArbitraryValueInspector(QWidget* _parent = nullptr);
|
||||
~EasyArbitraryValueInspector() override;
|
||||
|
||||
}; // end of class EasyArbitraryValueInspector.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EasyArbitraryValueItem : public QGraphicsItem
|
||||
{
|
||||
using Parent = QGraphicsItem;
|
||||
using This = EasyArbitraryValueItem;
|
||||
using Points = std::vector<QPointF>;
|
||||
|
||||
ArbitraryValuesCollection m_collection;
|
||||
Points m_points;
|
||||
QTimer m_timer;
|
||||
qreal m_scale;
|
||||
QRgb m_color;
|
||||
|
||||
public:
|
||||
|
||||
explicit EasyArbitraryValueItem(const profiler::ArbitraryValue& _value, profiler::thread_id_t _threadId);
|
||||
~EasyArbitraryValueItem() override;
|
||||
|
||||
void paint(QPainter* _painter, const QStyleOptionGraphicsItem* _option, QWidget* _widget = nullptr) override;
|
||||
|
||||
void onScaleChanged(qreal _scale);
|
||||
|
||||
private:
|
||||
|
||||
void onTimeout();
|
||||
|
||||
}; // end of class EasyArbitraryValueItem.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // EASY_PROFILER_GUI_ARBITRARY_VALUE_INSPECTOR_H
|
@ -238,6 +238,10 @@ inline ::profiler::BlocksTree& blocksTree(::profiler::block_index_t i) {
|
||||
return easyBlock(i).tree;
|
||||
}
|
||||
|
||||
inline qreal sceneX(profiler::timestamp_t _time) {
|
||||
return PROF_MICROSECONDS(qreal(_time - EASY_GLOBALS.begin_time));
|
||||
}
|
||||
|
||||
inline QString imagePath(const QString& _resource) {
|
||||
return QString(":/images/%1/%2").arg(EASY_GLOBALS.theme).arg(_resource);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user