2017-12-07 22:36:53 +03:00
|
|
|
/************************************************************************
|
|
|
|
* file name : common_functions.cpp
|
|
|
|
* ----------------- :
|
|
|
|
* creation time : 2017/12/06
|
|
|
|
* author : Victor Zarubkin
|
|
|
|
* email : v.s.zarubkin@gmail.com
|
|
|
|
* ----------------- :
|
|
|
|
* description : The file contains implementaion of common functions used by different UI widgets.
|
|
|
|
* ----------------- :
|
|
|
|
* change log : * 2017/12/06 Victor Zarubkin: Initial commit. Moved sources from common_types.h
|
|
|
|
* :
|
|
|
|
* : *
|
|
|
|
* ----------------- :
|
|
|
|
* 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 "common_functions.h"
|
|
|
|
|
|
|
|
namespace profiler_gui {
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
qreal timeFactor(qreal _interval)
|
|
|
|
{
|
|
|
|
if (_interval < 1) // interval in nanoseconds
|
|
|
|
return 1e3;
|
|
|
|
|
|
|
|
if (_interval < 1e3) // interval in microseconds
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (_interval < 1e6) // interval in milliseconds
|
|
|
|
return 1e-3;
|
|
|
|
|
|
|
|
// interval in seconds
|
|
|
|
return 1e-6;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
QString autoTimeStringReal(qreal _interval, int _precision)
|
|
|
|
{
|
|
|
|
if (_interval < 1) // interval in nanoseconds
|
|
|
|
return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3));
|
|
|
|
|
|
|
|
if (_interval < 1e3) // interval in microseconds
|
|
|
|
return QString("%1 us").arg(_interval, 0, 'f', _precision);
|
|
|
|
|
|
|
|
if (_interval < 1e6) // interval in milliseconds
|
|
|
|
return QString("%1 ms").arg(_interval * 1e-3, 0, 'f', _precision);
|
|
|
|
|
|
|
|
// interval in seconds
|
|
|
|
return QString("%1 s").arg(_interval * 1e-6, 0, 'f', _precision);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString autoTimeStringInt(qreal _interval)
|
|
|
|
{
|
|
|
|
if (_interval < 1) // interval in nanoseconds
|
|
|
|
return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
|
|
|
|
|
|
|
|
if (_interval < 1e3) // interval in microseconds
|
|
|
|
return QString("%1 us").arg(static_cast<quint32>(_interval + 0.5));
|
|
|
|
|
|
|
|
if (_interval < 1e6) // interval in milliseconds
|
|
|
|
return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
|
|
|
|
|
|
|
|
// interval in seconds
|
|
|
|
return QString("%1 s").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
|
|
|
|
}
|
|
|
|
|
|
|
|
QString autoTimeStringRealNs(::profiler::timestamp_t _interval, int _precision)
|
|
|
|
{
|
|
|
|
if (_interval < 1000) // interval in nanoseconds
|
|
|
|
return QString("%1 ns").arg(_interval);
|
|
|
|
|
|
|
|
if (_interval < 1000000) // interval in microseconds
|
|
|
|
return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision);
|
|
|
|
|
|
|
|
if (_interval < 1000000000U) // interval in milliseconds
|
|
|
|
return QString("%1 ms").arg(_interval * 1e-6, 0, 'f', _precision);
|
|
|
|
|
|
|
|
// interval in seconds
|
|
|
|
return QString("%1 s").arg(_interval * 1e-9, 0, 'f', _precision);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString autoTimeStringIntNs(::profiler::timestamp_t _interval)
|
|
|
|
{
|
|
|
|
if (_interval < 1000) // interval in nanoseconds
|
|
|
|
return QString("%1 ns").arg(_interval);
|
|
|
|
|
|
|
|
if (_interval < 1000000) // interval in microseconds
|
|
|
|
return QString("%1 us").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
|
|
|
|
|
|
|
|
if (_interval < 1000000000U) // interval in milliseconds
|
|
|
|
return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
|
|
|
|
|
|
|
|
// interval in seconds
|
|
|
|
return QString("%1 s").arg(static_cast<quint32>(_interval * 1e-9 + 0.5));
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
QString timeStringReal(TimeUnits _units, qreal _interval, int _precision)
|
|
|
|
{
|
|
|
|
switch (_units)
|
|
|
|
{
|
|
|
|
case TimeUnits_ms:{
|
|
|
|
const char fmt = _interval <= 1 ? 'g' : 'f';
|
|
|
|
return QString("%1 ms").arg(_interval * 1e-3, 0, fmt, _precision);
|
|
|
|
}
|
|
|
|
|
|
|
|
case TimeUnits_us:
|
|
|
|
return QString("%1 us").arg(_interval, 0, 'f', _precision);
|
|
|
|
|
|
|
|
case TimeUnits_ns:
|
|
|
|
return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_auto:
|
|
|
|
default:
|
|
|
|
return autoTimeStringReal(_interval, _precision);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString timeStringRealNs(TimeUnits _units, ::profiler::timestamp_t _interval, int _precision)
|
|
|
|
{
|
|
|
|
switch (_units)
|
|
|
|
{
|
|
|
|
case TimeUnits_ms:{
|
|
|
|
const char fmt = _interval <= 1000 ? 'g' : 'f';
|
|
|
|
return QString("%1 ms").arg(_interval * 1e-6, 0, fmt, _precision);
|
|
|
|
}
|
|
|
|
|
|
|
|
case TimeUnits_us:
|
|
|
|
return QString("%1 us").arg(_interval * 1e-3, 0, 'f', _precision);
|
|
|
|
|
|
|
|
case TimeUnits_ns:
|
|
|
|
return QString("%1 ns").arg(_interval);
|
|
|
|
|
|
|
|
case TimeUnits_auto:
|
|
|
|
default:
|
|
|
|
return autoTimeStringRealNs(_interval, _precision);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString timeStringInt(TimeUnits _units, qreal _interval)
|
|
|
|
{
|
|
|
|
switch (_units)
|
|
|
|
{
|
|
|
|
case TimeUnits_ms:
|
|
|
|
return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_us:
|
|
|
|
return QString("%1 us").arg(static_cast<quint32>(_interval + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_ns:
|
|
|
|
return QString("%1 ns").arg(static_cast<quint64>(_interval * 1e3 + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_auto:
|
|
|
|
default:
|
|
|
|
return autoTimeStringInt(_interval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString timeStringIntNs(TimeUnits _units, ::profiler::timestamp_t _interval)
|
|
|
|
{
|
|
|
|
switch (_units)
|
|
|
|
{
|
|
|
|
case TimeUnits_ms:
|
|
|
|
return QString("%1 ms").arg(static_cast<quint32>(_interval * 1e-6 + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_us:
|
|
|
|
return QString("%1 us").arg(static_cast<quint32>(_interval * 1e-3 + 0.5));
|
|
|
|
|
|
|
|
case TimeUnits_ns:
|
|
|
|
return QString("%1 ns").arg(_interval);
|
|
|
|
|
|
|
|
case TimeUnits_auto:
|
|
|
|
default:
|
|
|
|
return autoTimeStringIntNs(_interval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
QFont EFont(QFont::StyleHint _hint, const char* _family, int _size, int _weight)
|
|
|
|
{
|
|
|
|
QFont f;
|
|
|
|
f.setStyleHint(_hint, QFont::PreferMatch);
|
|
|
|
f.setFamily(_family);
|
|
|
|
f.setPointSize(_size);
|
|
|
|
f.setWeight(_weight);
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
QString valueTypeString(::profiler::DataType _dataType)
|
|
|
|
{
|
|
|
|
switch (_dataType)
|
|
|
|
{
|
|
|
|
case ::profiler::DataType::Bool: return QStringLiteral("bool");
|
|
|
|
case ::profiler::DataType::Char: return QStringLiteral("char");
|
|
|
|
case ::profiler::DataType::Int8: return QStringLiteral("int8");
|
|
|
|
case ::profiler::DataType::Uint8: return QStringLiteral("unsigned int8");
|
|
|
|
case ::profiler::DataType::Int16: return QStringLiteral("int16");
|
|
|
|
case ::profiler::DataType::Uint16: return QStringLiteral("unsigned int16");
|
|
|
|
case ::profiler::DataType::Int32: return QStringLiteral("int32");
|
|
|
|
case ::profiler::DataType::Uint32: return QStringLiteral("unsigned int32");
|
|
|
|
case ::profiler::DataType::Int64: return QStringLiteral("int64");
|
|
|
|
case ::profiler::DataType::Uint64: return QStringLiteral("unsigned int64");
|
|
|
|
case ::profiler::DataType::Float: return QStringLiteral("float");
|
|
|
|
case ::profiler::DataType::Double: return QStringLiteral("double");
|
|
|
|
case ::profiler::DataType::String: return QStringLiteral("string");
|
|
|
|
default: return QStringLiteral("unknown");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString valueTypeString(const ::profiler::ArbitraryValue& _serializedValue)
|
|
|
|
{
|
|
|
|
const auto type = _serializedValue.type();
|
|
|
|
if (_serializedValue.isArray() && type != ::profiler::DataType::String)
|
|
|
|
return valueTypeString(type) + QStringLiteral("[]");
|
|
|
|
return valueTypeString(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString valueString(const ::profiler::ArbitraryValue& _serializedValue)
|
|
|
|
{
|
|
|
|
if (_serializedValue.isArray())
|
|
|
|
{
|
|
|
|
if (_serializedValue.type() == ::profiler::DataType::String)
|
|
|
|
return _serializedValue.data();
|
|
|
|
return QStringLiteral("[...] array");
|
|
|
|
}
|
|
|
|
|
|
|
|
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 QString::number(_serializedValue.toValue<uint8_t>()->value());
|
|
|
|
case ::profiler::DataType::Int16: return QString::number(_serializedValue.toValue<int16_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint16: return QString::number(_serializedValue.toValue<uint16_t>()->value());
|
|
|
|
case ::profiler::DataType::Int32: return QString::number(_serializedValue.toValue<int32_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint32: return QString::number(_serializedValue.toValue<uint32_t>()->value());
|
|
|
|
case ::profiler::DataType::Int64: return QString::number(_serializedValue.toValue<int64_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint64: return QString::number(_serializedValue.toValue<uint64_t>()->value());
|
|
|
|
case ::profiler::DataType::Float: return QString::number(_serializedValue.toValue<float>()->value());
|
|
|
|
case ::profiler::DataType::Double: return QString::number(_serializedValue.toValue<double>()->value());
|
|
|
|
case ::profiler::DataType::String: return _serializedValue.data();
|
|
|
|
default: return QStringLiteral("Unknown");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-28 00:23:14 +03:00
|
|
|
double value2real(const ::profiler::ArbitraryValue& _serializedValue, int _index)
|
|
|
|
{
|
|
|
|
if (_serializedValue.isArray())
|
|
|
|
{
|
|
|
|
switch (_serializedValue.type())
|
|
|
|
{
|
|
|
|
case ::profiler::DataType::Bool:
|
|
|
|
{
|
|
|
|
const auto value = _serializedValue.toArray<bool>()->at(_index);
|
|
|
|
return value ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ::profiler::DataType::Char: return static_cast<double>(_serializedValue.toArray<char>()->at(_index));
|
|
|
|
case ::profiler::DataType::Int8: return static_cast<double>(_serializedValue.toArray<int8_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Uint8: return static_cast<double>(_serializedValue.toArray<uint8_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Int16: return static_cast<double>(_serializedValue.toArray<int16_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Uint16: return static_cast<double>(_serializedValue.toArray<uint16_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Int32: return static_cast<double>(_serializedValue.toArray<int32_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Uint32: return static_cast<double>(_serializedValue.toArray<uint32_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Int64: return static_cast<double>(_serializedValue.toArray<int64_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Uint64: return static_cast<double>(_serializedValue.toArray<uint64_t>()->at(_index));
|
|
|
|
case ::profiler::DataType::Float: return static_cast<double>(_serializedValue.toArray<float>()->at(_index));
|
|
|
|
case ::profiler::DataType::Double: return _serializedValue.toArray<double>()->at(_index);
|
|
|
|
case ::profiler::DataType::String: return static_cast<double>(_serializedValue.data()[_index]);
|
|
|
|
default: return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (_serializedValue.type())
|
|
|
|
{
|
|
|
|
case ::profiler::DataType::Bool:
|
|
|
|
{
|
|
|
|
const auto value = _serializedValue.toValue<bool>()->value();
|
|
|
|
return value ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ::profiler::DataType::Char: return static_cast<double>(_serializedValue.toValue<char>()->value());
|
|
|
|
case ::profiler::DataType::Int8: return static_cast<double>(_serializedValue.toValue<int8_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint8: return static_cast<double>(_serializedValue.toValue<uint8_t>()->value());
|
|
|
|
case ::profiler::DataType::Int16: return static_cast<double>(_serializedValue.toValue<int16_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint16: return static_cast<double>(_serializedValue.toValue<uint16_t>()->value());
|
|
|
|
case ::profiler::DataType::Int32: return static_cast<double>(_serializedValue.toValue<int32_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint32: return static_cast<double>(_serializedValue.toValue<uint32_t>()->value());
|
|
|
|
case ::profiler::DataType::Int64: return static_cast<double>(_serializedValue.toValue<int64_t>()->value());
|
|
|
|
case ::profiler::DataType::Uint64: return static_cast<double>(_serializedValue.toValue<uint64_t>()->value());
|
|
|
|
case ::profiler::DataType::Float: return static_cast<double>(_serializedValue.toValue<float>()->value());
|
|
|
|
case ::profiler::DataType::Double: return _serializedValue.toValue<double>()->value();
|
|
|
|
case ::profiler::DataType::String: return static_cast<double>(_serializedValue.data()[_index]);
|
|
|
|
default: return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-07 22:36:53 +03:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
} // end of namespace profiler_gui.
|