210 lines
4.2 KiB
C++
210 lines
4.2 KiB
C++
/* Copyright (c) 2019-2025, Arm Limited and Contributors
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "common/error.h"
|
|
|
|
#include "common/glm_common.h"
|
|
|
|
#include "common/helpers.h"
|
|
|
|
namespace vkb
|
|
{
|
|
namespace field
|
|
{
|
|
/**
|
|
* @brief Base Field Interface class
|
|
*/
|
|
struct Base
|
|
{
|
|
std::string label;
|
|
|
|
Base(const std::string &label) :
|
|
label{label}
|
|
{}
|
|
|
|
virtual ~Base() = default;
|
|
|
|
virtual const std::string to_string() = 0;
|
|
};
|
|
|
|
/**
|
|
* @brief Static Field Implementation
|
|
*
|
|
* To be used for values that do not change often.
|
|
*/
|
|
template <typename T>
|
|
struct Static : public Base
|
|
{
|
|
T value;
|
|
|
|
Static(const std::string &label, const T &value) :
|
|
Base(label),
|
|
value{value}
|
|
{}
|
|
|
|
virtual ~Static() = default;
|
|
|
|
const std::string to_string() override
|
|
{
|
|
return vkb::to_string(value);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Dynamic Field Implementation
|
|
*
|
|
* To be used for values that change frequently.
|
|
*/
|
|
template <typename T>
|
|
struct Dynamic : public Base
|
|
{
|
|
T &value;
|
|
|
|
Dynamic(const std::string &label, T &value) :
|
|
Base(label),
|
|
value{value}
|
|
{}
|
|
|
|
virtual ~Dynamic() = default;
|
|
|
|
const std::string to_string() override
|
|
{
|
|
return vkb::to_string(value);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Vector Field Implementation
|
|
*
|
|
* To be used for values that have an X, Y and Z value.
|
|
*/
|
|
template <typename T>
|
|
struct Vector final : public Static<T>
|
|
{
|
|
T x, y, z;
|
|
|
|
Vector(const std::string &label, const glm::vec3 &vec) :
|
|
Vector(label, vec.x, vec.y, vec.z)
|
|
{}
|
|
Vector(const std::string &label, T x, T y, T z) :
|
|
Static<T>(label, x),
|
|
x{x},
|
|
y{y},
|
|
z{z}
|
|
{}
|
|
|
|
virtual ~Vector() = default;
|
|
|
|
const std::string to_string() override
|
|
{
|
|
return "x: " + vkb::to_string(x) + " " +
|
|
"y: " + vkb::to_string(y) + " " +
|
|
"z: " + vkb::to_string(z);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief MinMax Field Implementation
|
|
*
|
|
* To be used for numbers that change a lot, keeping track of the high/low values.
|
|
*/
|
|
template <typename T>
|
|
struct MinMax final : public Dynamic<T>
|
|
{
|
|
T min, max;
|
|
|
|
MinMax(const std::string &label, T &value) :
|
|
Dynamic<T>(label, value),
|
|
min{value},
|
|
max{value}
|
|
{
|
|
static_assert(std::is_arithmetic<T>::value, "MinMax must be templated to a numeric type.");
|
|
}
|
|
|
|
virtual ~MinMax() = default;
|
|
|
|
const std::string to_string() override
|
|
{
|
|
if (Dynamic<T>::value > max)
|
|
{
|
|
max = Dynamic<T>::value;
|
|
}
|
|
if (Dynamic<T>::value < min)
|
|
{
|
|
min = Dynamic<T>::value;
|
|
}
|
|
if (min == 0)
|
|
{
|
|
min = Dynamic<T>::value;
|
|
}
|
|
|
|
return "current: " + vkb::to_string(Dynamic<T>::value) + " min: " + vkb::to_string(min) + " max: " + vkb::to_string(max);
|
|
}
|
|
};
|
|
} // namespace field
|
|
|
|
/**
|
|
* @brief Manages the debug information
|
|
*/
|
|
class DebugInfo
|
|
{
|
|
public:
|
|
const std::vector<std::unique_ptr<field::Base>> &get_fields() const;
|
|
|
|
/**
|
|
* @brief Calculates the field label with the most amount of characters
|
|
* @returns The length of the longest label
|
|
*/
|
|
float get_longest_label() const;
|
|
|
|
/**
|
|
* @brief Constructs and inserts a new field of type C<T>
|
|
*
|
|
* Replaces the field if it is of type static.
|
|
*/
|
|
template <template <typename> class C, typename T, typename... A>
|
|
void insert(const std::string &label, A &&...args)
|
|
{
|
|
static_assert(std::is_base_of<field::Base, C<T>>::value, "C is not a type of field::Base.");
|
|
|
|
for (auto &field : fields)
|
|
{
|
|
if (field->label == label)
|
|
{
|
|
if (dynamic_cast<typename field::template Static<T> *>(field.get()))
|
|
{
|
|
field = std::make_unique<C<T>>(label, args...);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
auto field = std::make_unique<C<T>>(label, std::forward<A>(args)...);
|
|
fields.push_back(std::move(field));
|
|
}
|
|
|
|
private:
|
|
std::vector<std::unique_ptr<field::Base>> fields;
|
|
};
|
|
} // namespace vkb
|