1
0
mirror of synced 2024-11-28 09:30:51 +01:00

feat: Added debug variables to aid with development

This commit is contained in:
WerWolv 2023-10-13 23:46:48 +02:00
parent 5a71cc2d61
commit da1b53420f
7 changed files with 107 additions and 38 deletions

@ -1 +1 @@
Subproject commit 7a35d84fa35eb7ac71745275c9b0289e1be8535b
Subproject commit c5698ed2cf3ea14382a597cc041fb6fc2674a982

View File

@ -35,6 +35,7 @@ set(LIBIMHEX_SOURCES
source/helpers/logger.cpp
source/helpers/stacktrace.cpp
source/helpers/tar.cpp
source/helpers/debugging.cpp
source/providers/provider.cpp

View File

@ -0,0 +1,48 @@
#pragma once
#include <wolv/types/static_string.hpp>
#include <wolv/utils/preproc.hpp>
#include <hex/ui/imgui_imhex_extensions.h>
#if defined(DEBUG)
#define DBG_DEFINE_DEBUG_VARIABLE(type, name) \
static type name; \
hex::dbg::impl::drawDebugVariable(name, WOLV_STRINGIFY(name));
#else
#define DBG_DEFINE_DEBUG_VARIABLE(type, name) \
static_assert(false, "Debug variables are only intended for use during development.");
#endif
namespace hex::dbg {
namespace impl {
bool &getDebugWindowState();
template<typename T>
static void drawDebugVariable(T &variable, std::string_view name) {
if (!getDebugWindowState())
return;
if (ImGui::Begin("Debug Variables", &getDebugWindowState(), ImGuiWindowFlags_AlwaysAutoResize)) {
using Type = std::remove_cvref_t<T>;
if constexpr (std::same_as<Type, bool>) {
ImGui::Checkbox(name.data(), &variable);
} else if constexpr (std::integral<Type> || std::floating_point<Type>) {
ImGui::InputScalar(name.data(), ImGui::getImGuiDataType<Type>(), &variable);
} else if constexpr (std::same_as<Type, ImVec2>) {
ImGui::InputFloat2(name.data(), &variable.x);
} else if constexpr (std::same_as<Type, std::string>) {
ImGui::InputText(name.data(), variable);
} else if constexpr (std::same_as<Type, ImColor>) {
ImGui::ColorEdit4(name.data(), &variable.Value.x, ImGuiColorEditFlags_AlphaBar);
} else {
static_assert(hex::always_false<Type>::value, "Unsupported type");
}
}
ImGui::End();
}
}
}

View File

@ -11,6 +11,7 @@
#include <imgui_internal.h>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/concepts.hpp>
#include <wolv/utils/string.hpp>
@ -246,4 +247,33 @@ namespace ImGui {
bool DimmedIconToggle(const char *icon, bool *v);
void TextOverlay(const char *text, ImVec2 pos);
template<typename T>
constexpr ImGuiDataType getImGuiDataType() {
if constexpr (std::same_as<T, u8>) return ImGuiDataType_U8;
else if constexpr (std::same_as<T, u16>) return ImGuiDataType_U16;
else if constexpr (std::same_as<T, u32>) return ImGuiDataType_U32;
else if constexpr (std::same_as<T, u64>) return ImGuiDataType_U64;
else if constexpr (std::same_as<T, i8>) return ImGuiDataType_S8;
else if constexpr (std::same_as<T, i16>) return ImGuiDataType_S16;
else if constexpr (std::same_as<T, i32>) return ImGuiDataType_S32;
else if constexpr (std::same_as<T, i64>) return ImGuiDataType_S64;
else if constexpr (std::same_as<T, float>) return ImGuiDataType_Float;
else if constexpr (std::same_as<T, double>) return ImGuiDataType_Double;
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
template<typename T>
constexpr const char *getFormatLengthSpecifier() {
if constexpr (std::same_as<T, u8>) return "hh";
else if constexpr (std::same_as<T, u16>) return "h";
else if constexpr (std::same_as<T, u32>) return "l";
else if constexpr (std::same_as<T, u64>) return "ll";
else if constexpr (std::same_as<T, i8>) return "hh";
else if constexpr (std::same_as<T, i16>) return "h";
else if constexpr (std::same_as<T, i32>) return "l";
else if constexpr (std::same_as<T, i64>) return "ll";
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
}

View File

@ -0,0 +1,15 @@
#include <hex/helpers/debugging.hpp>
namespace hex::dbg {
namespace impl {
bool &getDebugWindowState() {
static bool state = false;
return state;
}
}
}

View File

@ -11,34 +11,6 @@
namespace hex::plugin::builtin {
template<typename T>
constexpr ImGuiDataType getImGuiDataType() {
if constexpr (std::same_as<T, u8>) return ImGuiDataType_U8;
else if constexpr (std::same_as<T, u16>) return ImGuiDataType_U16;
else if constexpr (std::same_as<T, u32>) return ImGuiDataType_U32;
else if constexpr (std::same_as<T, u64>) return ImGuiDataType_U64;
else if constexpr (std::same_as<T, i8>) return ImGuiDataType_S8;
else if constexpr (std::same_as<T, i16>) return ImGuiDataType_S16;
else if constexpr (std::same_as<T, i32>) return ImGuiDataType_S32;
else if constexpr (std::same_as<T, i64>) return ImGuiDataType_S64;
else if constexpr (std::same_as<T, float>) return ImGuiDataType_Float;
else if constexpr (std::same_as<T, double>) return ImGuiDataType_Double;
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
template<typename T>
constexpr const char *getFormatLengthSpecifier() {
if constexpr (std::same_as<T, u8>) return "hh";
else if constexpr (std::same_as<T, u16>) return "h";
else if constexpr (std::same_as<T, u32>) return "l";
else if constexpr (std::same_as<T, u64>) return "ll";
else if constexpr (std::same_as<T, i8>) return "hh";
else if constexpr (std::same_as<T, i16>) return "h";
else if constexpr (std::same_as<T, i32>) return "l";
else if constexpr (std::same_as<T, i64>) return "ll";
else static_assert(hex::always_false<T>::value, "Invalid data type!");
}
template<std::integral T>
class DataVisualizerHexadecimal : public hex::ContentRegistry::HexEditor::DataVisualizer {
public:
@ -57,7 +29,7 @@ namespace hex::plugin::builtin {
hex::unused(address, startedEditing);
if (size == ByteCount) {
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), getImGuiDataType<T>(), data, ImGuiInputTextFlags_CharsHexadecimal);
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), ImGui::getImGuiDataType<T>(), data, ImGuiInputTextFlags_CharsHexadecimal);
}
else
return false;
@ -67,8 +39,8 @@ namespace hex::plugin::builtin {
constexpr static inline auto ByteCount = sizeof(T);
constexpr static inline auto CharCount = ByteCount * 2;
const static inline auto FormattingUpperCase = hex::format("%0{}{}X", CharCount, getFormatLengthSpecifier<T>());
const static inline auto FormattingLowerCase = hex::format("%0{}{}x", CharCount, getFormatLengthSpecifier<T>());
const static inline auto FormattingUpperCase = hex::format("%0{}{}X", CharCount, ImGui::getFormatLengthSpecifier<T>());
const static inline auto FormattingLowerCase = hex::format("%0{}{}x", CharCount, ImGui::getFormatLengthSpecifier<T>());
const char *getFormatString(bool upperCase) {
if (upperCase)
@ -110,7 +82,7 @@ namespace hex::plugin::builtin {
hex::unused(address, startedEditing);
if (size == ByteCount) {
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), getImGuiDataType<u8>(), data, ImGuiInputTextFlags_None);
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), ImGui::getImGuiDataType<u8>(), data, ImGuiInputTextFlags_None);
}
else
return false;
@ -120,8 +92,8 @@ namespace hex::plugin::builtin {
constexpr static inline auto ByteCount = 1;
constexpr static inline auto CharCount = ByteCount * 2;
const static inline auto FormattingUpperCase = hex::format("%0{}{}X", CharCount, getFormatLengthSpecifier<u8>());
const static inline auto FormattingLowerCase = hex::format("%0{}{}x", CharCount, getFormatLengthSpecifier<u8>());
const static inline auto FormattingUpperCase = hex::format("%0{}{}X", CharCount, ImGui::getFormatLengthSpecifier<u8>());
const static inline auto FormattingLowerCase = hex::format("%0{}{}x", CharCount, ImGui::getFormatLengthSpecifier<u8>());
static const char *getFormatString(bool upperCase) {
if (upperCase)
@ -153,7 +125,7 @@ namespace hex::plugin::builtin {
hex::unused(address, upperCase, startedEditing);
if (size == ByteCount) {
return drawDefaultScalarEditingTextBox(address, FormatString.c_str(), getImGuiDataType<T>(), data, ImGuiInputTextFlags_None);
return drawDefaultScalarEditingTextBox(address, FormatString.c_str(), ImGui::getImGuiDataType<T>(), data, ImGuiInputTextFlags_None);
}
else
return false;
@ -163,7 +135,7 @@ namespace hex::plugin::builtin {
constexpr static inline auto ByteCount = sizeof(T);
constexpr static inline auto CharCount = std::numeric_limits<T>::digits10 + 2;
const static inline auto FormatString = hex::format("%{}{}{}", CharCount, getFormatLengthSpecifier<T>(), std::is_signed<T>::value ? "d" : "u");
const static inline auto FormatString = hex::format("%{}{}{}", CharCount, ImGui::getFormatLengthSpecifier<T>(), std::is_signed<T>::value ? "d" : "u");
const char *getFormatString() {
return FormatString.c_str();
@ -190,7 +162,7 @@ namespace hex::plugin::builtin {
hex::unused(address, upperCase, startedEditing);
if (size == ByteCount) {
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), getImGuiDataType<u8>(), data, ImGuiInputTextFlags_CharsScientific);
return drawDefaultScalarEditingTextBox(address, getFormatString(upperCase), ImGui::getImGuiDataType<u8>(), data, ImGuiInputTextFlags_CharsScientific);
}
else
return false;

View File

@ -10,6 +10,7 @@
#include <hex/helpers/crypto.hpp>
#include <hex/helpers/patches.hpp>
#include <hex/helpers/debugging.hpp>
#include <content/global_actions.hpp>
#include <content/popups/popup_notification.hpp>
@ -441,6 +442,8 @@ namespace hex::plugin::builtin {
#if defined(DEBUG)
ImGui::MenuItem("hex.builtin.menu.view.demo"_lang, "", &g_demoWindowOpen);
ImGui::MenuItem("hex.builtin.menu.view.debug"_lang, "", &hex::dbg::impl::getDebugWindowState());
#endif
});