mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-26 08:01:51 +08:00
#31 [Core] Arbitrary values: replaced size_t with uint16_t; [Gui] Added support of arrays to arbitrary values tree
This commit is contained in:
parent
49f000d11a
commit
5e632bedee
@ -129,7 +129,7 @@ void foo(const A& a) {
|
||||
|
||||
\note Also stores a time-stamp of it's occurrence like an Event.
|
||||
|
||||
\note To store an array, please, use EASY_ARRAY macro.
|
||||
\note To store a dynamic array (which size is unknown at compile time), please, use EASY_ARRAY macro.
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
@ -149,6 +149,8 @@ void foo(const A& a) {
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max array size is 4096. Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_TEXT, EASY_STRING
|
||||
|
||||
\ingroup profiler
|
||||
@ -167,6 +169,8 @@ Could be C-string or std::string.
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max string length is 4096 (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_STRING
|
||||
|
||||
\ingroup profiler
|
||||
@ -188,6 +192,8 @@ Use this for C-strings of known length (compile-time or run-time).
|
||||
|
||||
\note Currently arbitrary values support only compile-time names.
|
||||
|
||||
\warning Max string length is 4096 (including trailing '\0'). Passing bigger size has undefined behavior.
|
||||
|
||||
\sa EASY_VALUE, EASY_ARRAY, EASY_TEXT
|
||||
|
||||
\ingroup profiler
|
||||
@ -201,10 +207,10 @@ Use this for C-strings of known length (compile-time or run-time).
|
||||
namespace profiler
|
||||
{
|
||||
|
||||
EASY_CONSTEXPR uint16_t MaxArbitraryValuesArraySize = 65535;
|
||||
EASY_CONSTEXPR uint16_t MaxArbitraryValuesArraySize = 4096;
|
||||
|
||||
extern "C" PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data,
|
||||
size_t _size, bool _isArray, ValueId _vin);
|
||||
uint16_t _size, bool _isArray, ValueId _vin);
|
||||
|
||||
template <class T>
|
||||
inline void setValue(const BaseBlockDescriptor* _desc, T _value, ValueId _vin)
|
||||
@ -217,16 +223,17 @@ namespace profiler
|
||||
static_assert(StdToDataType<Type>::data_type != DataType::TypesCount,
|
||||
"You should use standard builtin scalar types as profiler::Value type!");
|
||||
|
||||
storeValue(_desc, StdToDataType<Type>::data_type, &_value, sizeof(Type), false, _vin);
|
||||
storeValue(_desc, StdToDataType<Type>::data_type, &_value, static_cast<uint16_t>(sizeof(Type)), false, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _arraySize > 4096 may cause undefined behavior!
|
||||
template <class T>
|
||||
inline void setValue(const BaseBlockDescriptor* _desc, const T* _valueArray, ValueId _vin, uint16_t _arraySize)
|
||||
{
|
||||
static_assert(StdToDataType<T>::data_type != DataType::TypesCount,
|
||||
"You should use standard builtin scalar types as profiler::Value type!");
|
||||
|
||||
storeValue(_desc, StdToDataType<T>::data_type, _valueArray, sizeof(T) * _arraySize, true, _vin);
|
||||
storeValue(_desc, StdToDataType<T>::data_type, _valueArray, static_cast<uint16_t>(sizeof(T) * _arraySize), true, _vin);
|
||||
}
|
||||
|
||||
template <class T, size_t N>
|
||||
@ -235,31 +242,34 @@ namespace profiler
|
||||
static_assert(StdToDataType<T>::data_type != DataType::TypesCount,
|
||||
"You should use standard builtin scalar types as profiler::Value type!");
|
||||
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 65535.");
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 4096.");
|
||||
|
||||
storeValue(_desc, StdToDataType<T>::data_type, _value, sizeof(_value), true, _vin);
|
||||
storeValue(_desc, StdToDataType<T>::data_type, _value, static_cast<uint16_t>(sizeof(_value)), true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _textLength > 4096 may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin, uint16_t _textLength)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text, _textLength, true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _text with length > 4096 may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char* _text, ValueId _vin)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text, strlen(_text) + 1, true, _vin);
|
||||
storeValue(_desc, DataType::String, _text, static_cast<uint16_t>(strlen(_text) + 1), true, _vin);
|
||||
}
|
||||
|
||||
///< WARNING: Passing _text with length > 4096 may cause undefined behavior!
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const ::std::string& _text, ValueId _vin)
|
||||
{
|
||||
storeValue(_desc, DataType::String, _text.c_str(), _text.size() + 1, true, _vin);
|
||||
storeValue(_desc, DataType::String, _text.c_str(), static_cast<uint16_t>(_text.size() + 1), true, _vin);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
inline void setText(const BaseBlockDescriptor* _desc, const char (&_text)[N], ValueId _vin)
|
||||
{
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 65535.");
|
||||
storeValue(_desc, DataType::String, &_text[0], N, true, _vin);
|
||||
static_assert(N <= MaxArbitraryValuesArraySize, "Maximum arbitrary values array size is 4096.");
|
||||
storeValue(_desc, DataType::String, &_text[0], static_cast<uint16_t>(N), true, _vin);
|
||||
}
|
||||
|
||||
} // end of namespace profiler.
|
||||
@ -277,7 +287,7 @@ namespace profiler
|
||||
namespace profiler
|
||||
{
|
||||
|
||||
inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {}
|
||||
inline void storeValue(const BaseBlockDescriptor*, DataType, const void*, uint16_t, bool, ValueId) {}
|
||||
|
||||
template <class T>
|
||||
inline void setValue(const BaseBlockDescriptor*, T, ValueId) {}
|
||||
|
@ -202,6 +202,10 @@ namespace profiler {
|
||||
return reinterpret_cast<const char*>(this) + sizeof(ArbitraryValue);
|
||||
}
|
||||
|
||||
uint16_t data_size() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
vin_t value_id() const {
|
||||
return m_value_id;
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ extern "C" {
|
||||
return MANAGER.isEnabled();
|
||||
}
|
||||
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin)
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, uint16_t _size, bool _isArray, ValueId _vin)
|
||||
{
|
||||
MANAGER.storeValue(_desc, _type, _data, _size, _isArray, _vin);
|
||||
}
|
||||
@ -487,7 +487,7 @@ extern "C" {
|
||||
PROFILER_API void endBlock() { }
|
||||
PROFILER_API void setEnabled(bool) { }
|
||||
PROFILER_API bool isEnabled() { return false; }
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor*, DataType, const void*, size_t, bool, ValueId) {}
|
||||
PROFILER_API void storeValue(const BaseBlockDescriptor*, DataType, const void*, uint16_t, bool, ValueId) {}
|
||||
PROFILER_API void storeEvent(const BaseBlockDescriptor*, const char*) { }
|
||||
PROFILER_API void storeBlock(const BaseBlockDescriptor*, const char*, timestamp_t, timestamp_t) { }
|
||||
PROFILER_API void beginBlock(Block&) { }
|
||||
@ -781,7 +781,7 @@ const BaseBlockDescriptor* ProfileManager::addBlockDescriptor(EasyBlockStatus _d
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, size_t _size, bool _isArray, ValueId _vin)
|
||||
void ProfileManager::storeValue(const BaseBlockDescriptor* _desc, DataType _type, const void* _data, uint16_t _size, bool _isArray, ValueId _vin)
|
||||
{
|
||||
if (!isEnabled() || (_desc->m_status & profiler::ON) == 0)
|
||||
return;
|
||||
|
@ -140,7 +140,7 @@ public:
|
||||
profiler::color_t _color,
|
||||
bool _copyName = false);
|
||||
|
||||
void storeValue(const profiler::BaseBlockDescriptor* _desc, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin);
|
||||
void storeValue(const profiler::BaseBlockDescriptor* _desc, profiler::DataType _type, const void* _data, uint16_t _size, bool _isArray, profiler::ValueId _vin);
|
||||
bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName);
|
||||
bool storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, profiler::timestamp_t _beginTime, profiler::timestamp_t _endTime);
|
||||
void beginBlock(profiler::Block& _block);
|
||||
|
@ -57,12 +57,12 @@ ThreadStorage::ThreadStorage()
|
||||
expired = ATOMIC_VAR_INIT(0);
|
||||
}
|
||||
|
||||
void ThreadStorage::storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin)
|
||||
void ThreadStorage::storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, uint16_t _size, bool _isArray, profiler::ValueId _vin)
|
||||
{
|
||||
const uint16_t serializedDataSize = static_cast<uint16_t>(sizeof(profiler::ArbitraryValue) + _size);
|
||||
const uint16_t serializedDataSize = _size + static_cast<uint16_t>(sizeof(profiler::ArbitraryValue));
|
||||
void* data = blocks.closedList.allocate(serializedDataSize);
|
||||
|
||||
::new (data) profiler::ArbitraryValue(_timestamp, _vin.m_id, _id, static_cast<uint16_t>(_size), _type, _isArray);
|
||||
::new (data) profiler::ArbitraryValue(_timestamp, _vin.m_id, _id, _size, _type, _isArray);
|
||||
|
||||
char* cdata = reinterpret_cast<char*>(data);
|
||||
memcpy(cdata + sizeof(profiler::ArbitraryValue), _data, _size);
|
||||
|
@ -114,7 +114,7 @@ struct ThreadStorage EASY_FINAL
|
||||
bool guarded; ///< True if thread has been registered using ThreadGuard
|
||||
bool frameOpened; ///< Is new frame opened (this does not depend on profiling status) \sa profiledFrameOpened
|
||||
|
||||
void storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, size_t _size, bool _isArray, profiler::ValueId _vin);
|
||||
void storeValue(profiler::timestamp_t _timestamp, profiler::block_id_t _id, profiler::DataType _type, const void* _data, uint16_t _size, bool _isArray, profiler::ValueId _vin);
|
||||
void storeBlock(const profiler::Block& _block);
|
||||
void storeBlockForce(const profiler::Block& _block);
|
||||
void storeCSwitch(const CSwitchBlock& _block);
|
||||
|
@ -246,7 +246,7 @@ qreal ArbitraryValuesCollection::maxValue() const
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectValues(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, const char* _valueName, profiler::block_id_t _parentBlockId)
|
||||
, const char* _valueName, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
interrupt();
|
||||
|
||||
@ -262,13 +262,13 @@ void ArbitraryValuesCollection::collectValues(ChartType _chartType, profiler::th
|
||||
}
|
||||
|
||||
if (_valueId == 0)
|
||||
m_worker.enqueue([=] { collectByName(_threadId, _valueName, _parentBlockId); }, m_bInterrupt);
|
||||
m_worker.enqueue([=] { collectByName(_threadId, _valueName, _parentBlockId, _index); }, m_bInterrupt);
|
||||
else
|
||||
m_worker.enqueue([=] { collectById(_threadId, _valueId, _parentBlockId); }, m_bInterrupt);
|
||||
m_worker.enqueue([=] { collectById(_threadId, _valueId, _parentBlockId, _index); }, m_bInterrupt);
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectValuesAndPoints(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, const char* _valueName, profiler::timestamp_t _beginTime, profiler::block_id_t _parentBlockId)
|
||||
, const char* _valueName, profiler::timestamp_t _beginTime, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
interrupt();
|
||||
|
||||
@ -287,9 +287,9 @@ void ArbitraryValuesCollection::collectValuesAndPoints(ChartType _chartType, pro
|
||||
}
|
||||
|
||||
if (_valueId == 0)
|
||||
m_worker.enqueue([=] { collectByName(_threadId, _valueName, _parentBlockId); }, m_bInterrupt);
|
||||
m_worker.enqueue([=] { collectByName(_threadId, _valueName, _parentBlockId, _index); }, m_bInterrupt);
|
||||
else
|
||||
m_worker.enqueue([=] { collectById(_threadId, _valueId, _parentBlockId); }, m_bInterrupt);
|
||||
m_worker.enqueue([=] { collectById(_threadId, _valueId, _parentBlockId, _index); }, m_bInterrupt);
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::calculatePoints(profiler::timestamp_t _beginTime)
|
||||
@ -332,7 +332,7 @@ void ArbitraryValuesCollection::setStatus(JobStatus _status)
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, profiler::block_id_t _parentBlockId)
|
||||
, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
const bool doCalculatePoints = (m_jobType & PointsJob) != 0;
|
||||
|
||||
@ -345,7 +345,7 @@ void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, pro
|
||||
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
if (!collectByIdForThread(it.second, _valueId, calculatePointsInner, _parentBlockId))
|
||||
if (!collectByIdForThread(it.second, _valueId, calculatePointsInner, _parentBlockId, _index))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, pro
|
||||
{
|
||||
const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId);
|
||||
if (t != EASY_GLOBALS.profiler_blocks.end() &&
|
||||
!collectByIdForThread(t->second, _valueId, doCalculatePoints, _parentBlockId))
|
||||
!collectByIdForThread(t->second, _valueId, doCalculatePoints, _parentBlockId, _index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -386,7 +386,7 @@ void ArbitraryValuesCollection::collectById(profiler::thread_id_t _threadId, pro
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::collectByIdForThread(const profiler::BlocksTreeRoot& _threadRoot
|
||||
, profiler::vin_t _valueId, bool _calculatePoints, profiler::block_id_t _parentBlockId)
|
||||
, profiler::vin_t _valueId, bool _calculatePoints, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
if (profiler_gui::is_max(_parentBlockId))
|
||||
{
|
||||
@ -406,20 +406,23 @@ bool ArbitraryValuesCollection::collectByIdForThread(const profiler::BlocksTreeR
|
||||
if (value->value_id() != _valueId)
|
||||
continue;
|
||||
|
||||
if (_index >= 0 && (!value->isArray() || profiler_gui::valueArraySize(*value) <= _index))
|
||||
continue;
|
||||
|
||||
m_values.push_back(value);
|
||||
if (_calculatePoints)
|
||||
addPoint(*value);
|
||||
addPoint(*value, _index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return depthFirstSearch(_threadRoot, _calculatePoints, _parentBlockId
|
||||
return depthFirstSearch(_threadRoot, _calculatePoints, _parentBlockId, _index
|
||||
, [=] (profiler::vin_t _id, const char*) -> bool { return _id == _valueId; });
|
||||
}
|
||||
|
||||
void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, const std::string _valueName
|
||||
, profiler::block_id_t _parentBlockId)
|
||||
, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
const bool doCalculatePoints = (m_jobType & PointsJob) != 0;
|
||||
|
||||
@ -432,7 +435,7 @@ void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, c
|
||||
|
||||
for (const auto& it : EASY_GLOBALS.profiler_blocks)
|
||||
{
|
||||
if (!collectByNameForThread(it.second, _valueName, calculatePointsInner, _parentBlockId))
|
||||
if (!collectByNameForThread(it.second, _valueName, calculatePointsInner, _parentBlockId, _index))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -452,7 +455,7 @@ void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, c
|
||||
{
|
||||
const auto t = EASY_GLOBALS.profiler_blocks.find(_threadId);
|
||||
if (t != EASY_GLOBALS.profiler_blocks.end() &&
|
||||
!collectByNameForThread(t->second, _valueName, doCalculatePoints, _parentBlockId))
|
||||
!collectByNameForThread(t->second, _valueName, doCalculatePoints, _parentBlockId, _index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -473,7 +476,7 @@ void ArbitraryValuesCollection::collectByName(profiler::thread_id_t _threadId, c
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::collectByNameForThread(const profiler::BlocksTreeRoot& _threadRoot
|
||||
, const std::string& _valueName, bool _calculatePoints, profiler::block_id_t _parentBlockId)
|
||||
, const std::string& _valueName, bool _calculatePoints, profiler::block_id_t _parentBlockId, int _index)
|
||||
{
|
||||
if (profiler_gui::is_max(_parentBlockId))
|
||||
{
|
||||
@ -489,20 +492,24 @@ bool ArbitraryValuesCollection::collectByNameForThread(const profiler::BlocksTre
|
||||
if (desc.type() != profiler::BlockType::Value || _valueName != desc.name())
|
||||
continue;
|
||||
|
||||
m_values.push_back(block.value);
|
||||
const auto value = block.value;
|
||||
if (_index >= 0 && (!value->isArray() || profiler_gui::valueArraySize(*value) <= _index))
|
||||
continue;
|
||||
|
||||
m_values.push_back(value);
|
||||
if (_calculatePoints)
|
||||
addPoint(*block.value);
|
||||
addPoint(*value, _index);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return depthFirstSearch(_threadRoot, _calculatePoints, _parentBlockId
|
||||
return depthFirstSearch(_threadRoot, _calculatePoints, _parentBlockId, _index
|
||||
, [&_valueName] (profiler::vin_t, const char* _name) -> bool { return _valueName == _name; });
|
||||
}
|
||||
|
||||
bool ArbitraryValuesCollection::depthFirstSearch(const profiler::BlocksTreeRoot& _threadRoot, bool _calculatePoints
|
||||
, profiler::block_id_t _parentBlockId, std::function<bool(profiler::vin_t, const char*)> _isSuitableValue)
|
||||
, profiler::block_id_t _parentBlockId, int _index, std::function<bool(profiler::vin_t, const char*)> _isSuitableValue)
|
||||
{
|
||||
if (_threadRoot.children.empty())
|
||||
return true;
|
||||
@ -539,17 +546,20 @@ bool ArbitraryValuesCollection::depthFirstSearch(const profiler::BlocksTreeRoot&
|
||||
const auto value = block.value;
|
||||
if (_isSuitableValue(value->value_id(), desc.name()))
|
||||
{
|
||||
m_values.push_back(value);
|
||||
if (_calculatePoints)
|
||||
if (_index < 0 || (value->isArray() && _index < profiler_gui::valueArraySize(*value)))
|
||||
{
|
||||
const auto val = addPoint(*value);
|
||||
if (m_chartType == ChartType::Complexity)
|
||||
m_values.push_back(value);
|
||||
if (_calculatePoints)
|
||||
{
|
||||
m_complexityMap[val].push_back(lastMatchedParentDuration);
|
||||
if (lastMatchedParentDuration < m_minDuration)
|
||||
m_minDuration = lastMatchedParentDuration;
|
||||
if (lastMatchedParentDuration > m_maxDuration)
|
||||
m_maxDuration = lastMatchedParentDuration;
|
||||
const auto val = addPoint(*value, _index);
|
||||
if (m_chartType == ChartType::Complexity)
|
||||
{
|
||||
m_complexityMap[val].push_back(lastMatchedParentDuration);
|
||||
if (lastMatchedParentDuration < m_minDuration)
|
||||
m_minDuration = lastMatchedParentDuration;
|
||||
if (lastMatchedParentDuration > m_maxDuration)
|
||||
m_maxDuration = lastMatchedParentDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -580,9 +590,9 @@ bool ArbitraryValuesCollection::depthFirstSearch(const profiler::BlocksTreeRoot&
|
||||
return true;
|
||||
}
|
||||
|
||||
double ArbitraryValuesCollection::addPoint(const profiler::ArbitraryValue& _value)
|
||||
double ArbitraryValuesCollection::addPoint(const profiler::ArbitraryValue& _value, int _index)
|
||||
{
|
||||
const auto p = point(_value);
|
||||
const auto p = point(_value, _index);
|
||||
|
||||
if (p.y() > m_maxValue)
|
||||
m_maxValue = p.y();
|
||||
@ -595,10 +605,10 @@ double ArbitraryValuesCollection::addPoint(const profiler::ArbitraryValue& _valu
|
||||
return p.y();
|
||||
}
|
||||
|
||||
QPointF ArbitraryValuesCollection::point(const profiler::ArbitraryValue& _value) const
|
||||
QPointF ArbitraryValuesCollection::point(const profiler::ArbitraryValue& _value, int _index) const
|
||||
{
|
||||
const qreal x = PROF_MICROSECONDS(qreal(_value.begin() - m_beginTime));
|
||||
const qreal y = profiler_gui::value2real(_value);
|
||||
const qreal y = profiler_gui::value2real(_value, std::max(_index, 0));
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
@ -1297,12 +1307,9 @@ void ArbitraryValuesChartItem::updateComplexityImageAsync(QRectF _boundingRect,
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto first = leftBounds[i];
|
||||
if (first == complexityMap.end())
|
||||
{
|
||||
++i;
|
||||
const auto first = leftBounds[i++];
|
||||
if (first == complexityMap.end() || first->first > right)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c.selected)
|
||||
{
|
||||
@ -1323,9 +1330,12 @@ void ArbitraryValuesChartItem::updateComplexityImageAsync(QRectF _boundingRect,
|
||||
averages.reserve(complexityMap.size());
|
||||
|
||||
auto it = first;
|
||||
while (it->first < left)
|
||||
while (it != complexityMap.end() && it->first < left)
|
||||
++it;
|
||||
|
||||
if (it == complexityMap.end() || it->first > right)
|
||||
continue;
|
||||
|
||||
qreal x = getx(it->first);
|
||||
|
||||
profiler::timestamp_t average = 0;
|
||||
@ -1667,14 +1677,21 @@ struct UsedValueTypes {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArbitraryTreeWidgetItem::ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, profiler::color_t _color, profiler::vin_t _vin)
|
||||
ArbitraryTreeWidgetItem::ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, profiler::vin_t _vin)
|
||||
: Parent(_parent, ValueItemType)
|
||||
, m_vin(_vin)
|
||||
, m_color(_color)
|
||||
, m_widthHint(0)
|
||||
{
|
||||
setFlags(flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
|
||||
setCheckState(CheckColumn, Qt::Unchecked);
|
||||
if (_checkable)
|
||||
{
|
||||
setFlags(flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
|
||||
setCheckState(CheckColumn, Qt::Unchecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
setFlags(flags() & ~Qt::ItemIsUserCheckable);
|
||||
}
|
||||
}
|
||||
|
||||
ArbitraryTreeWidgetItem::~ArbitraryTreeWidgetItem()
|
||||
@ -1711,6 +1728,35 @@ ArbitraryValuesCollection* ArbitraryTreeWidgetItem::collection()
|
||||
return m_collection.get();
|
||||
}
|
||||
|
||||
bool ArbitraryTreeWidgetItem::isArrayItem() const
|
||||
{
|
||||
return childCount() != 0;
|
||||
}
|
||||
|
||||
profiler::block_id_t ArbitraryTreeWidgetItem::getParentBlockId(QTreeWidgetItem* _item) const
|
||||
{
|
||||
auto parentItem = _item->parent();
|
||||
const auto parentRole = parentItem->data(int_cast(ArbitraryColumns::Type), Qt::UserRole).toInt();
|
||||
switch (parentRole)
|
||||
{
|
||||
case 1:
|
||||
return parentItem->data(int_cast(ArbitraryColumns::Vin), Qt::UserRole).toUInt();
|
||||
|
||||
case 2:
|
||||
return getParentBlockId(parentItem);
|
||||
|
||||
default:
|
||||
return EASY_GLOBALS.selected_block_id;
|
||||
}
|
||||
}
|
||||
|
||||
int ArbitraryTreeWidgetItem::getSelfIndexInArray()
|
||||
{
|
||||
if (data(int_cast(ArbitraryColumns::Type), Qt::UserRole).toInt() != 3)
|
||||
return -1;
|
||||
return parent()->indexOfChild(this);
|
||||
}
|
||||
|
||||
void ArbitraryTreeWidgetItem::collectValues(profiler::thread_id_t _threadId, ChartType _chartType)
|
||||
{
|
||||
if (!m_collection)
|
||||
@ -1718,17 +1764,14 @@ void ArbitraryTreeWidgetItem::collectValues(profiler::thread_id_t _threadId, Cha
|
||||
else
|
||||
m_collection->interrupt();
|
||||
|
||||
auto parentItem = parent();
|
||||
const auto parentBlockId = getParentBlockId(this);
|
||||
const int index = getSelfIndexInArray();
|
||||
|
||||
profiler::block_id_t parentBlockId = 0;
|
||||
if (parentItem->data(int_cast(ArbitraryColumns::Type), Qt::UserRole).toInt() == 1)
|
||||
parentBlockId = parentItem->data(int_cast(ArbitraryColumns::Vin), Qt::UserRole).toUInt();
|
||||
else
|
||||
parentBlockId = EASY_GLOBALS.selected_block_id;
|
||||
EASY_CONSTEXPR auto nameColumn = int_cast(ArbitraryColumns::Name);
|
||||
const auto name = index < 0 ? text(nameColumn).toStdString() : parent()->text(nameColumn).toStdString();
|
||||
|
||||
m_collection->collectValuesAndPoints(_chartType, _threadId, m_vin
|
||||
, text(int_cast(ArbitraryColumns::Name)).toStdString().c_str(), EASY_GLOBALS.begin_time
|
||||
, parentBlockId);
|
||||
m_collection->collectValuesAndPoints(_chartType, _threadId, m_vin, name.c_str(),
|
||||
EASY_GLOBALS.begin_time, parentBlockId, index);
|
||||
}
|
||||
|
||||
void ArbitraryTreeWidgetItem::interrupt()
|
||||
@ -1918,10 +1961,10 @@ void ArbitraryValuesWidget::onSelectedBlockIdChanged(::profiler::block_id_t)
|
||||
|
||||
void ArbitraryValuesWidget::onItemDoubleClicked(QTreeWidgetItem* _item, int)
|
||||
{
|
||||
if (_item == nullptr || _item->type() != ValueItemType)
|
||||
if (_item == nullptr || _item->type() != ValueItemType || (_item->flags() & Qt::ItemIsUserCheckable) == 0)
|
||||
return;
|
||||
|
||||
_item->setCheckState(CheckColumn, _item->checkState(CheckColumn) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
|
||||
_item->setCheckState(CheckColumn, _item->checkState(CheckColumn) != Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
|
||||
}
|
||||
|
||||
void ArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column)
|
||||
@ -1929,15 +1972,61 @@ void ArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column)
|
||||
if (_item == nullptr || _item->type() != ValueItemType || _column != CheckColumn)
|
||||
return;
|
||||
|
||||
if (_item->checkState(CheckColumn) == Qt::PartiallyChecked)
|
||||
return;
|
||||
|
||||
auto item = static_cast<ArbitraryTreeWidgetItem*>(_item);
|
||||
|
||||
if (item->checkState(CheckColumn) == Qt::Checked)
|
||||
{
|
||||
m_exportToCsvAction->setEnabled(true);
|
||||
m_checkedItems.push_back(item);
|
||||
item->collectValues(EASY_GLOBALS.selected_thread, m_chart->chartType());
|
||||
if (!m_collectionsTimer.isActive())
|
||||
m_collectionsTimer.start(100);
|
||||
|
||||
const auto prevSize = m_checkedItems.size();
|
||||
if (!item->isArrayItem())
|
||||
{
|
||||
m_checkedItems.push_back(item);
|
||||
item->collectValues(EASY_GLOBALS.selected_thread, m_chart->chartType());
|
||||
|
||||
if (item->getSelfIndexInArray() >= 0)
|
||||
{
|
||||
Qt::CheckState newState = Qt::Checked;
|
||||
auto parentItem = item->parent();
|
||||
for (int i = 0; i < parentItem->childCount(); ++i)
|
||||
{
|
||||
auto child = parentItem->child(i);
|
||||
if (child->checkState(CheckColumn) != Qt::Checked)
|
||||
{
|
||||
newState = Qt::PartiallyChecked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
parentItem->setCheckState(CheckColumn, newState);
|
||||
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
for (int i = 0; i < item->childCount(); ++i)
|
||||
{
|
||||
auto child = static_cast<ArbitraryTreeWidgetItem*>(item->child(i));
|
||||
if (child->checkState(CheckColumn) != Qt::Checked)
|
||||
{
|
||||
child->setCheckState(CheckColumn, Qt::Checked);
|
||||
m_checkedItems.push_back(child);
|
||||
child->collectValues(EASY_GLOBALS.selected_thread, m_chart->chartType());
|
||||
}
|
||||
}
|
||||
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
}
|
||||
|
||||
if (prevSize != m_checkedItems.size())
|
||||
{
|
||||
if (!m_collectionsTimer.isActive())
|
||||
m_collectionsTimer.start(100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1949,10 +2038,56 @@ void ArbitraryValuesWidget::onItemChanged(QTreeWidgetItem* _item, int _column)
|
||||
// in interrupt().
|
||||
// !!!
|
||||
|
||||
m_checkedItems.removeOne(item);
|
||||
m_exportToCsvAction->setEnabled(!m_checkedItems.empty());
|
||||
onCollectionsTimeout();
|
||||
item->interrupt();
|
||||
decltype(m_checkedItems) uncheckedItems;
|
||||
|
||||
if (!item->isArrayItem())
|
||||
{
|
||||
uncheckedItems.push_back(item);
|
||||
m_checkedItems.removeOne(item);
|
||||
|
||||
if (item->getSelfIndexInArray() >= 0)
|
||||
{
|
||||
Qt::CheckState newState = Qt::Unchecked;
|
||||
auto parentItem = item->parent();
|
||||
for (int i = 0; i < parentItem->childCount(); ++i)
|
||||
{
|
||||
auto child = parentItem->child(i);
|
||||
if (child->checkState(CheckColumn) != Qt::Unchecked)
|
||||
{
|
||||
newState = Qt::PartiallyChecked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
parentItem->setCheckState(CheckColumn, newState);
|
||||
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
disconnect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
for (int i = 0; i < item->childCount(); ++i)
|
||||
{
|
||||
auto child = static_cast<ArbitraryTreeWidgetItem*>(item->child(i));
|
||||
if (child->checkState(CheckColumn) == Qt::Checked)
|
||||
{
|
||||
child->setCheckState(CheckColumn, Qt::Unchecked);
|
||||
uncheckedItems.push_back(child);
|
||||
m_checkedItems.removeOne(child);
|
||||
}
|
||||
}
|
||||
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
|
||||
}
|
||||
|
||||
if (!uncheckedItems.isEmpty())
|
||||
{
|
||||
m_exportToCsvAction->setEnabled(!m_checkedItems.empty());
|
||||
onCollectionsTimeout();
|
||||
|
||||
for (auto uncheckedItem : uncheckedItems)
|
||||
uncheckedItem->interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2214,11 +2349,13 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
|
||||
const auto& desc = easyDescriptor(block.node->id());
|
||||
if (desc.type() == profiler::BlockType::Value)
|
||||
{
|
||||
auto valueItem = new ArbitraryTreeWidgetItem(rootItem, desc.color(), block.value->value_id());
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*block.value));
|
||||
auto value = block.value;
|
||||
const bool isString = value->type() == profiler::DataType::String;
|
||||
auto valueItem = new ArbitraryTreeWidgetItem(rootItem, !isString, desc.color(), value->value_id());
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*value));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(block.value->value_id(), 0, 16));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*block.value));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(value->value_id(), 0, 16));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value));
|
||||
valueItem->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 2);
|
||||
|
||||
const auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width();
|
||||
@ -2311,8 +2448,31 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
|
||||
if (valueItem != nullptr)
|
||||
{
|
||||
if (i == _blockIndex)
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::shortValueString(*value));
|
||||
//continue; // already in set
|
||||
|
||||
if (value->isArray() && value->type() != profiler::DataType::String)
|
||||
{
|
||||
const int size = profiler_gui::valueArraySize(*value);
|
||||
if (valueItem->childCount() < size)
|
||||
{
|
||||
for (int childIndex = valueItem->childCount(); childIndex < size; ++childIndex)
|
||||
{
|
||||
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), vin);
|
||||
item->setText(int_cast(ArbitraryColumns::Name), QString("%1[%2]").arg(desc.name()).arg(childIndex));
|
||||
item->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 3);
|
||||
|
||||
if (i == _blockIndex)
|
||||
item->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value, childIndex));
|
||||
|
||||
const auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width();
|
||||
item->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32);
|
||||
}
|
||||
|
||||
auto typeString = profiler_gui::valueTypeString(*value);
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Type), typeString.replace("[]", "[%1]").arg(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2339,19 +2499,43 @@ QTreeWidgetItem* ArbitraryValuesWidget::buildTreeForThread(const profiler::Block
|
||||
}
|
||||
}
|
||||
|
||||
valueItem = new ArbitraryTreeWidgetItem(blockItem, desc.color(), vin);
|
||||
const bool isString = value->type() == profiler::DataType::String;
|
||||
valueItem = new ArbitraryTreeWidgetItem(blockItem, !isString, desc.color(), vin);
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Type), profiler_gui::valueTypeString(*value));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Name), desc.name());
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Vin), QString("0x%1").arg(vin, 0, 16));
|
||||
valueItem->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 2);
|
||||
|
||||
if (i == _blockIndex)
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value));
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Value), profiler_gui::shortValueString(*value));
|
||||
|
||||
const auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width();
|
||||
auto sizeHintWidth = valueItem->sizeHint(CheckColumn).width();
|
||||
valueItem->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32);
|
||||
|
||||
*(usedItems + typeIndex) = valueItem;
|
||||
|
||||
if (value->isArray() && !isString)
|
||||
{
|
||||
const int size = profiler_gui::valueArraySize(*value);
|
||||
if (valueItem->childCount() < size)
|
||||
{
|
||||
for (int childIndex = valueItem->childCount(); childIndex < size; ++childIndex)
|
||||
{
|
||||
auto item = new ArbitraryTreeWidgetItem(valueItem, true, desc.color(), vin);
|
||||
item->setText(int_cast(ArbitraryColumns::Name), QString("%1[%2]").arg(desc.name()).arg(childIndex));
|
||||
item->setData(int_cast(ArbitraryColumns::Type), Qt::UserRole, 3);
|
||||
|
||||
if (i == _blockIndex)
|
||||
item->setText(int_cast(ArbitraryColumns::Value), profiler_gui::valueString(*value, childIndex));
|
||||
|
||||
sizeHintWidth = valueItem->sizeHint(CheckColumn).width();
|
||||
item->setWidthHint(std::max(sizeHintWidth, fm.width(valueItem->text(CheckColumn))) + 32);
|
||||
}
|
||||
|
||||
auto typeString = profiler_gui::valueTypeString(*value);
|
||||
valueItem->setText(int_cast(ArbitraryColumns::Type), typeString.replace("[]", "[%1]").arg(size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,25 +142,39 @@ public:
|
||||
qreal minValue() const;
|
||||
qreal maxValue() const;
|
||||
|
||||
void collectValues(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName, profiler::block_id_t _parentBlockId);
|
||||
void collectValues(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, const char* _valueName, profiler::block_id_t _parentBlockId, int _index = -1);
|
||||
|
||||
bool calculatePoints(profiler::timestamp_t _beginTime);
|
||||
|
||||
void collectValuesAndPoints(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId, const char* _valueName, profiler::timestamp_t _beginTime, profiler::block_id_t _parentBlockId);
|
||||
void collectValuesAndPoints(ChartType _chartType, profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, const char* _valueName, profiler::timestamp_t _beginTime, profiler::block_id_t _parentBlockId
|
||||
, int _index = -1);
|
||||
|
||||
void interrupt();
|
||||
|
||||
private:
|
||||
|
||||
void setStatus(JobStatus _status);
|
||||
void collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId, profiler::block_id_t _parentBlockId);
|
||||
void collectByName(profiler::thread_id_t _threadId, const std::string _valueName, profiler::block_id_t _parentBlockId);
|
||||
bool collectByIdForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::vin_t _valueId, bool _calculatePoints, profiler::block_id_t _parentBlockId);
|
||||
bool collectByNameForThread(const profiler::BlocksTreeRoot& _threadRoot, const std::string& _valueName, bool _calculatePoints, profiler::block_id_t _parentBlockId);
|
||||
|
||||
void collectById(profiler::thread_id_t _threadId, profiler::vin_t _valueId
|
||||
, profiler::block_id_t _parentBlockId, int _index);
|
||||
|
||||
void collectByName(profiler::thread_id_t _threadId, const std::string _valueName
|
||||
, profiler::block_id_t _parentBlockId, int _index);
|
||||
|
||||
bool collectByIdForThread(const profiler::BlocksTreeRoot& _threadRoot, profiler::vin_t _valueId
|
||||
, bool _calculatePoints, profiler::block_id_t _parentBlockId, int _index);
|
||||
|
||||
bool collectByNameForThread(const profiler::BlocksTreeRoot& _threadRoot, const std::string& _valueName
|
||||
, bool _calculatePoints, profiler::block_id_t _parentBlockId, int _index);
|
||||
|
||||
bool depthFirstSearch(const profiler::BlocksTreeRoot& _threadRoot, bool _calculatePoints
|
||||
, profiler::block_id_t _parentBlockId, std::function<bool(profiler::vin_t, const char*)> _isSuitableValue);
|
||||
, profiler::block_id_t _parentBlockId, int _index
|
||||
, std::function<bool(profiler::vin_t, const char*)> _isSuitableValue);
|
||||
|
||||
double addPoint(const profiler::ArbitraryValue& _value);
|
||||
QPointF point(const profiler::ArbitraryValue& _value) const;
|
||||
double addPoint(const profiler::ArbitraryValue& _value, int _index);
|
||||
QPointF point(const profiler::ArbitraryValue& _value, int _index) const;
|
||||
|
||||
}; // end of class ArbitraryValuesCollection.
|
||||
|
||||
@ -290,7 +304,7 @@ class ArbitraryTreeWidgetItem : public QTreeWidgetItem
|
||||
|
||||
public:
|
||||
|
||||
explicit ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, profiler::color_t _color, profiler::vin_t _vin = 0);
|
||||
explicit ArbitraryTreeWidgetItem(QTreeWidgetItem* _parent, bool _checkable, profiler::color_t _color, profiler::vin_t _vin = 0);
|
||||
~ArbitraryTreeWidgetItem() override;
|
||||
|
||||
QVariant data(int _column, int _role) const override;
|
||||
@ -305,6 +319,13 @@ public:
|
||||
|
||||
profiler::color_t color() const;
|
||||
|
||||
bool isArrayItem() const;
|
||||
int getSelfIndexInArray();
|
||||
|
||||
private:
|
||||
|
||||
profiler::block_id_t getParentBlockId(QTreeWidgetItem* _item) const;
|
||||
|
||||
}; // end of class ArbitraryTreeWidgetItem.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1743,7 +1743,7 @@ void BlocksGraphicsView::onIdleTimeout()
|
||||
++row;
|
||||
|
||||
lay->addWidget(new QLabel("Value:", widget), row, 0, Qt::AlignRight);
|
||||
lay->addWidget(new QLabel(::profiler_gui::valueString(*itemBlock.value), widget), row, 1, Qt::AlignLeft);
|
||||
lay->addWidget(new QLabel(::profiler_gui::shortValueString(*itemBlock.value), widget), row, 1, Qt::AlignLeft);
|
||||
++row;
|
||||
|
||||
lay->addWidget(new QLabel("VIN:", widget), row, 0, Qt::AlignRight);
|
||||
|
@ -54,6 +54,11 @@
|
||||
|
||||
#include "common_functions.h"
|
||||
|
||||
template <class T>
|
||||
static QString toString(const profiler::ArbitraryValue& _serializedValue, int _index) {
|
||||
return QString::number(_serializedValue.toArray<T>()->at(_index));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static QString toString(const profiler::ArbitraryValue& _serializedValue) {
|
||||
return QString::number(_serializedValue.toValue<T>()->value());
|
||||
@ -69,6 +74,58 @@ static double toReal(const profiler::ArbitraryValue& _serializedValue) {
|
||||
return static_cast<double>(_serializedValue.toValue<T>()->value());
|
||||
}
|
||||
|
||||
template <profiler::DataType type>
|
||||
inline EASY_CONSTEXPR_FCN uint16_t sizeOf() {
|
||||
return static_cast<uint16_t>(sizeof(typename profiler::StdType<type>::value_type));
|
||||
}
|
||||
|
||||
QString arrayToString(const profiler::ArbitraryValue& _serializedValue, int _index)
|
||||
{
|
||||
switch (_serializedValue.type())
|
||||
{
|
||||
case profiler::DataType::Bool:
|
||||
{
|
||||
const auto value = _serializedValue.toArray<bool>()->at(_index);
|
||||
return value ? QStringLiteral("true") : QStringLiteral("false");
|
||||
}
|
||||
|
||||
case profiler::DataType::Char: return QChar(_serializedValue.toArray<char> ()->at(_index));
|
||||
case profiler::DataType::Int8: return QChar(_serializedValue.toArray<int8_t>()->at(_index));
|
||||
case profiler::DataType::Uint8: return toString<uint8_t> (_serializedValue, _index);
|
||||
case profiler::DataType::Int16: return toString<int16_t> (_serializedValue, _index);
|
||||
case profiler::DataType::Uint16: return toString<uint16_t>(_serializedValue, _index);
|
||||
case profiler::DataType::Int32: return toString<int32_t> (_serializedValue, _index);
|
||||
case profiler::DataType::Uint32: return toString<uint32_t>(_serializedValue, _index);
|
||||
case profiler::DataType::Int64: return toString<int64_t> (_serializedValue, _index);
|
||||
case profiler::DataType::Uint64: return toString<uint64_t>(_serializedValue, _index);
|
||||
case profiler::DataType::Float: return toString<float> (_serializedValue, _index);
|
||||
case profiler::DataType::Double: return toString<double> (_serializedValue, _index);
|
||||
case profiler::DataType::String: return QChar(_serializedValue.data()[_index]);
|
||||
default: return QStringLiteral("??");
|
||||
}
|
||||
}
|
||||
|
||||
QString singleValueToString(const profiler::ArbitraryValue& _serializedValue)
|
||||
{
|
||||
switch (_serializedValue.type())
|
||||
{
|
||||
case profiler::DataType::Bool: return _serializedValue.toValue<bool>()->value() ? QStringLiteral("true") : QStringLiteral("false");
|
||||
case profiler::DataType::Char: return QChar(_serializedValue.toValue<char> ()->value());
|
||||
case profiler::DataType::Int8: return QChar(_serializedValue.toValue<int8_t>()->value());
|
||||
case profiler::DataType::Uint8: return toString<uint8_t> (_serializedValue);
|
||||
case profiler::DataType::Int16: return toString<int16_t> (_serializedValue);
|
||||
case profiler::DataType::Uint16: return toString<uint16_t>(_serializedValue);
|
||||
case profiler::DataType::Int32: return toString<int32_t> (_serializedValue);
|
||||
case profiler::DataType::Uint32: return toString<uint32_t>(_serializedValue);
|
||||
case profiler::DataType::Int64: return toString<int64_t> (_serializedValue);
|
||||
case profiler::DataType::Uint64: return toString<uint64_t>(_serializedValue);
|
||||
case profiler::DataType::Float: return toString<float> (_serializedValue);
|
||||
case profiler::DataType::Double: return toString<double> (_serializedValue);
|
||||
case profiler::DataType::String: return _serializedValue.data();
|
||||
default: return QStringLiteral("??");
|
||||
}
|
||||
}
|
||||
|
||||
namespace profiler_gui {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -281,26 +338,74 @@ namespace profiler_gui {
|
||||
{
|
||||
if (_serializedValue.type() == ::profiler::DataType::String)
|
||||
return _serializedValue.data();
|
||||
return QStringLiteral("[...] array");
|
||||
|
||||
auto str = QString("[%1").arg(valueString(_serializedValue, 0));
|
||||
const int size = valueArraySize(_serializedValue);
|
||||
for (int i = 1; i < size; ++i)
|
||||
str.append(QString(", %1").arg(valueString(_serializedValue, i)));
|
||||
str.append(QChar(']'));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
switch (_serializedValue.type())
|
||||
return singleValueToString(_serializedValue);
|
||||
}
|
||||
|
||||
QString shortValueString(const ::profiler::ArbitraryValue& _serializedValue)
|
||||
{
|
||||
if (_serializedValue.isArray())
|
||||
{
|
||||
case ::profiler::DataType::Bool: return _serializedValue.toValue<bool>()->value() ? QStringLiteral("true") : QStringLiteral("false");
|
||||
case ::profiler::DataType::Char: return QChar(_serializedValue.toValue<char> ()->value());
|
||||
case ::profiler::DataType::Int8: return QChar(_serializedValue.toValue<int8_t>()->value());
|
||||
case ::profiler::DataType::Uint8: return toString<uint8_t> (_serializedValue);
|
||||
case ::profiler::DataType::Int16: return toString<int16_t> (_serializedValue);
|
||||
case ::profiler::DataType::Uint16: return toString<uint16_t>(_serializedValue);
|
||||
case ::profiler::DataType::Int32: return toString<int32_t> (_serializedValue);
|
||||
case ::profiler::DataType::Uint32: return toString<uint32_t>(_serializedValue);
|
||||
case ::profiler::DataType::Int64: return toString<int64_t> (_serializedValue);
|
||||
case ::profiler::DataType::Uint64: return toString<uint64_t>(_serializedValue);
|
||||
case ::profiler::DataType::Float: return toString<float> (_serializedValue);
|
||||
case ::profiler::DataType::Double: return toString<double> (_serializedValue);
|
||||
case ::profiler::DataType::String: return _serializedValue.data();
|
||||
default: return QStringLiteral("Unknown");
|
||||
if (_serializedValue.type() == ::profiler::DataType::String)
|
||||
return _serializedValue.data();
|
||||
|
||||
auto str = QString("[%1").arg(valueString(_serializedValue, 0));
|
||||
const int size = valueArraySize(_serializedValue);
|
||||
if (size < 7)
|
||||
{
|
||||
for (int i = 1; i < size; ++i)
|
||||
str.append(QString(", %1").arg(valueString(_serializedValue, i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < 6; ++i)
|
||||
str.append(QString(", %1").arg(valueString(_serializedValue, i)));
|
||||
str.append(QString(", ..., %1").arg(valueString(_serializedValue, size - 1)));
|
||||
}
|
||||
|
||||
str.append(QChar(']'));
|
||||
return str;
|
||||
}
|
||||
|
||||
return singleValueToString(_serializedValue);
|
||||
}
|
||||
|
||||
QString valueString(const ::profiler::ArbitraryValue& _serializedValue, int _index)
|
||||
{
|
||||
if (_serializedValue.isArray())
|
||||
return arrayToString(_serializedValue, _index);
|
||||
return singleValueToString(_serializedValue);
|
||||
}
|
||||
|
||||
int valueArraySize(const ::profiler::ArbitraryValue& _serializedValue)
|
||||
{
|
||||
EASY_STATIC_CONSTEXPR uint16_t DataSizes[] = {
|
||||
sizeOf<::profiler::DataType::Bool>(),
|
||||
sizeOf<::profiler::DataType::Char>(),
|
||||
sizeOf<::profiler::DataType::Int8>(),
|
||||
sizeOf<::profiler::DataType::Uint8>(),
|
||||
sizeOf<::profiler::DataType::Int16>(),
|
||||
sizeOf<::profiler::DataType::Uint16>(),
|
||||
sizeOf<::profiler::DataType::Int32>(),
|
||||
sizeOf<::profiler::DataType::Uint32>(),
|
||||
sizeOf<::profiler::DataType::Int64>(),
|
||||
sizeOf<::profiler::DataType::Uint64>(),
|
||||
sizeOf<::profiler::DataType::Float>(),
|
||||
sizeOf<::profiler::DataType::Double>(),
|
||||
sizeOf<::profiler::DataType::String>(),
|
||||
1
|
||||
};
|
||||
|
||||
return _serializedValue.data_size() / DataSizes[int_cast(_serializedValue.type())];
|
||||
}
|
||||
|
||||
double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index)
|
||||
|
@ -204,6 +204,9 @@ inline QFont EFont(const char* _family, int _size, int _weight = -1) {
|
||||
QString valueTypeString(::profiler::DataType _dataType);
|
||||
QString valueTypeString(const ::profiler::ArbitraryValue& _serializedValue);
|
||||
QString valueString(const ::profiler::ArbitraryValue& _serializedValue);
|
||||
QString shortValueString(const ::profiler::ArbitraryValue& _serializedValue);
|
||||
QString valueString(const ::profiler::ArbitraryValue& _serializedValue, int _index);
|
||||
int valueArraySize(const ::profiler::ArbitraryValue& _serializedValue);
|
||||
double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index = 0);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
7
profiler_gui/images/default/check-partial-disabled.svg
Normal file
7
profiler_gui/images/default/check-partial-disabled.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
|
||||
<g>
|
||||
<rect fill="#98CE98" x="16" y="16" width="32" height="32"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 358 B |
7
profiler_gui/images/default/check-partial.svg
Normal file
7
profiler_gui/images/default/check-partial.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="64px" height="64px" viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
|
||||
<g>
|
||||
<rect fill="#237423" x="16" y="16" width="32" height="32"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 358 B |
@ -31,6 +31,8 @@
|
||||
<file alias="check-disabled">images/default/check-disabled.svg</file>
|
||||
<file alias="radio-check">images/default/radio-indicator.svg</file>
|
||||
<file alias="radio-check-disabled">images/default/radio-indicator-disabled.svg</file>
|
||||
<file alias="partial-check">images/default/check-partial.svg</file>
|
||||
<file alias="partial-check-disabled">images/default/check-partial-disabled.svg</file>
|
||||
<file alias="dock-maximize-white">images/default/maximize-white.svg</file>
|
||||
<file alias="dock-maximize-white-hover">images/default/maximize-white-hover.svg</file>
|
||||
<file alias="dock-maximize-white-pressed">images/default/maximize-white-pressed.svg</file>
|
||||
|
@ -175,7 +175,7 @@ QTreeView::indicator {
|
||||
padding: 1px;
|
||||
margin: 0; }
|
||||
|
||||
QTreeView::indicator:hover, QTreeView::indicator:checked {
|
||||
QTreeView::indicator:hover, QTreeView::indicator:checked, QTreeView::indicator:indeterminate {
|
||||
background-color: white;
|
||||
border: 1px solid #cccccc; }
|
||||
|
||||
@ -185,6 +185,12 @@ QTreeView::indicator:checked {
|
||||
QTreeView::indicator:checked:disabled {
|
||||
image: url(":/images/default/check-disabled"); }
|
||||
|
||||
QTreeView::indicator:indeterminate {
|
||||
image: url(":/images/default/partial-check"); }
|
||||
|
||||
QTreeView::indicator:indeterminate:disabled {
|
||||
image: url(":/images/default/partial-check-disabled"); }
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
QMenu {
|
||||
background-color: white;
|
||||
|
@ -200,7 +200,7 @@ QTreeView::indicator {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
QTreeView::indicator:hover, QTreeView::indicator:checked {
|
||||
QTreeView::indicator:hover, QTreeView::indicator:checked, QTreeView::indicator:indeterminate {
|
||||
background-color: $BackgroundColor;
|
||||
border: 1px solid $BorderColor;
|
||||
}
|
||||
@ -208,6 +208,9 @@ QTreeView::indicator:hover, QTreeView::indicator:checked {
|
||||
QTreeView::indicator:checked { image: url(":/images/default/check"); }
|
||||
QTreeView::indicator:checked:disabled { image: url(":/images/default/check-disabled"); }
|
||||
|
||||
QTreeView::indicator:indeterminate { image: url(":/images/default/partial-check"); }
|
||||
QTreeView::indicator:indeterminate:disabled { image: url(":/images/default/partial-check-disabled"); }
|
||||
|
||||
/* ****************************************************************************************************************** */
|
||||
QMenu {
|
||||
background-color: $BackgroundColor;
|
||||
|
@ -185,7 +185,8 @@ void modellingThread(){
|
||||
localSleep(1200000);
|
||||
|
||||
++step;
|
||||
EASY_VALUE("step", sin((double)step), profiler::colors::Gold, EASY_VIN(step));
|
||||
double vals[] = {(double)step, sin((double)step), cos((double)step)};
|
||||
EASY_VALUE("step", vals, profiler::colors::Gold, EASY_VIN(step));
|
||||
if (step > 10000000)
|
||||
step = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user