feat: Added debug variables to aid with development
This commit is contained in:
parent
5a71cc2d61
commit
da1b53420f
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
@ -1 +1 @@
|
||||
Subproject commit 7a35d84fa35eb7ac71745275c9b0289e1be8535b
|
||||
Subproject commit c5698ed2cf3ea14382a597cc041fb6fc2674a982
|
@ -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
|
||||
|
||||
|
48
lib/libimhex/include/hex/helpers/debugging.hpp
Normal file
48
lib/libimhex/include/hex/helpers/debugging.hpp
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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!");
|
||||
}
|
||||
|
||||
}
|
15
lib/libimhex/source/helpers/debugging.cpp
Normal file
15
lib/libimhex/source/helpers/debugging.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include <hex/helpers/debugging.hpp>
|
||||
|
||||
namespace hex::dbg {
|
||||
|
||||
namespace impl {
|
||||
|
||||
bool &getDebugWindowState() {
|
||||
static bool state = false;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user