Skip to content

Commit

Permalink
Merge pull request #21 from 4J-company/feature/debug-visualizers
Browse files Browse the repository at this point in the history
Add debug visualization for structs (Visual Studio)
  • Loading branch information
cone-forest authored Feb 1, 2025
2 parents d4c3317 + 0c60408 commit 5074848
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ add_library(${MR_MATH_LIB_NAME} INTERFACE
include/mr-math/math.hpp
include/mr-math/bound_box.hpp
include/mr-math/color.hpp
include/mr-math/debug.hpp
)

target_include_directories(${MR_MATH_LIB_NAME} INTERFACE
Expand Down
114 changes: 114 additions & 0 deletions include/mr-math/debug.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#ifndef __MR_DEBUG_HPP_
#define __MR_DEBUG_HPP_

// This file provides template instantiations used by debug visualizers
// and is intended for debug builds only

#include "vec.hpp"

namespace mr {
namespace debug {

// following functions instantiate methods of template structs desired in debug visualization

inline namespace row {

void instantiate_row_get(const auto& row) {
volatile auto x = row.get(0); (void)x;
}

#define MR_INSTANTIATE_ROW2(T) template void instantiate_row_get(const Row<T, 2>&)
#define MR_INSTANTIATE_ROW3(T) template void instantiate_row_get(const Row<T, 3>&)
#define MR_INSTANTIATE_ROW4(T) template void instantiate_row_get(const Row<T, 4>&)
#define MR_INSTANTIATE_ROW2_ROW3_ROW4(T) MR_INSTANTIATE_ROW2(T); MR_INSTANTIATE_ROW3(T); MR_INSTANTIATE_ROW4(T)

// instantiate types
MR_INSTANTIATE_ROW2_ROW3_ROW4(float);
MR_INSTANTIATE_ROW2_ROW3_ROW4(double);
MR_INSTANTIATE_ROW2_ROW3_ROW4(int);
MR_INSTANTIATE_ROW2_ROW3_ROW4(uint32_t);

} // namespace row

inline namespace vec {

void instantiate_vec_x_y_length(const auto& vec) {
volatile auto x = vec.x(); (void)x;
volatile auto y = vec.y(); (void)y;
volatile auto l = vec.length(); (void)l;
}

void instantiate_vec_x_y_z_length(const auto& vec) {
instantiate_vec_x_y_length(vec);
volatile auto z = vec.z(); (void)z;
}

void instantiate_vec_x_y_z_w_length(const auto& vec) {
instantiate_vec_x_y_z_length(vec);
volatile auto w = vec.w(); (void)w;
}

#define MR_INSTANTIATE_VEC2(T) template void instantiate_vec_x_y_length(const Vec2<T>&)
#define MR_INSTANTIATE_VEC3(T) template void instantiate_vec_x_y_z_length(const Vec3<T>&)
#define MR_INSTANTIATE_VEC4(T) template void instantiate_vec_x_y_z_w_length(const Vec4<T>&)
#define MR_INSTANTIATE_VEC2_VEC3_VEC4(T) MR_INSTANTIATE_VEC2(T); MR_INSTANTIATE_VEC3(T); MR_INSTANTIATE_VEC4(T)

// instantiate types
MR_INSTANTIATE_VEC2_VEC3_VEC4(float);
MR_INSTANTIATE_VEC2_VEC3_VEC4(double);
MR_INSTANTIATE_VEC2_VEC3_VEC4(int);
MR_INSTANTIATE_VEC2_VEC3_VEC4(uint32_t);

} // namespace vec

inline namespace norm {

void instantiate_norm_x_y(const auto& norm) {
volatile auto x = norm.x(); (void)x;
volatile auto y = norm.y(); (void)y;
}

void instantiate_norm_x_y_z(const auto& norm) {
instantiate_norm_x_y(norm);
volatile auto z = norm.z(); (void)z;
}

void instantiate_norm_x_y_z_w(const auto& norm) {
instantiate_norm_x_y_z(norm);
volatile auto w = norm.w(); (void)w;
}

#define MR_INSTANTIATE_NORM2(T) template void instantiate_norm_x_y(const Norm2<T>&)
#define MR_INSTANTIATE_NORM3(T) template void instantiate_norm_x_y_z(const Norm3<T>&)
#define MR_INSTANTIATE_NORM4(T) template void instantiate_norm_x_y_z_w(const Norm4<T>&)
#define MR_INSTANTIATE_NORM2_NORM3_NORM4(T) MR_INSTANTIATE_NORM2(T); MR_INSTANTIATE_NORM3(T); MR_INSTANTIATE_NORM4(T)

// instantiate types
MR_INSTANTIATE_NORM2_NORM3_NORM4(float);
MR_INSTANTIATE_NORM2_NORM3_NORM4(double);
MR_INSTANTIATE_NORM2_NORM3_NORM4(int);
MR_INSTANTIATE_NORM2_NORM3_NORM4(uint32_t);

} // namespace norm

inline namespace bounb_box {

void instantiate_aabb_dimensions(const auto& aabb) {
volatile auto d = aabb.dimensions(); (void)d;
}

#define MR_INSTANTIATE_AABB(T) template void instantiate_aabb_dimensions(const AABB<T>&)

// instantiate types
MR_INSTANTIATE_AABB(float);
MR_INSTANTIATE_AABB(double);
MR_INSTANTIATE_AABB(int);
MR_INSTANTIATE_AABB(uint32_t);

} // namespace norm

} // namespace debug
} // namespace mr

#endif // __MR_DEBUG_HPP_

4 changes: 4 additions & 0 deletions include/mr-math/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@
#include "bound_box.hpp"
#include "color.hpp"

#ifndef NDEBUG
#include "debug.hpp"
#endif

#endif // __MR_MATH_HPP_
1 change: 0 additions & 1 deletion include/mr-math/norm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ namespace mr {

private:
friend struct Vec<T, N>;
friend struct Rotation<T>;
constexpr Norm(const VecT &v) noexcept : Norm(unchecked, v) {}

VecT _data;
Expand Down
4 changes: 4 additions & 0 deletions include/mr-math/row.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ namespace mr {
return _data[i];
}

[[nodiscard]] constexpr T get(std::size_t i) const {
return _data[i];
}

constexpr bool operator==(const Row &other) const noexcept {
return stdx::all_of(_data == other._data);
}
Expand Down
137 changes: 137 additions & 0 deletions mr-math.natvis
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

<!-- mr::Row2 -->
<Type Name="mr::Row&lt;*, 2&gt;">
<DisplayString>{{{get(0)}, {get(1)}}}</DisplayString>
<Expand>
<Item Name="[0]">get(0)</Item>
<Item Name="[1]">get(1)</Item>
</Expand>
</Type>

<!-- mr::Row3 -->
<Type Name="mr::Row&lt;*, 3&gt;">
<DisplayString>{{{get(0)}, {get(1)}, {get(2)}}}</DisplayString>
<Expand>
<Item Name="[0]">get(0)</Item>
<Item Name="[1]">get(1)</Item>
<Item Name="[2]">get(2)</Item>
</Expand>
</Type>

<!-- mr::Row4 -->
<Type Name="mr::Row&lt;*, 4&gt;">
<DisplayString>{{{get(0)}, {get(1)}, {get(2)}, {get(3)}}}</DisplayString>
<Expand>
<Item Name="[0]">get(0)</Item>
<Item Name="[1]">get(1)</Item>
<Item Name="[2]">get(2)</Item>
<Item Name="[3]">get(3)</Item>
</Expand>
</Type>

<!-- mr::Vec2 -->
<Type Name="mr::Vec&lt;*, 2&gt;">
<DisplayString>{{{x()}, {y()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
<Item Name="Length">length()</Item>
</Expand>
</Type>

<!-- mr::Vec3 -->
<Type Name="mr::Vec&lt;*, 3&gt;">
<DisplayString>{{{x()}, {y()}, {z()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
<Item Name="Z">z()</Item>
<Item Name="Length">length()</Item>
</Expand>
</Type>

<!-- mr::Vec4 -->
<Type Name="mr::Vec&lt;*, 4&gt;">
<DisplayString>{{{x()}, {y()}, {z()}, {w()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
<Item Name="Z">z()</Item>
<Item Name="W">w()</Item>
<Item Name="Length">length()</Item>
</Expand>
</Type>

<!-- mr::Norm2 -->
<Type Name="mr::Norm&lt;*, 2&gt;">
<DisplayString>{{{x()}, {y()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
</Expand>
</Type>

<!-- mr::Norm3 -->
<Type Name="mr::Norm&lt;*, 3&gt;">
<DisplayString>{{{x()}, {y()}, {z()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
<Item Name="Z">z()</Item>
</Expand>
</Type>

<!-- mr::Norm4 -->
<Type Name="mr::Norm&lt;*, 4&gt;">
<DisplayString>{{{x()}, {y()}, {z()}, {w()}}}</DisplayString>
<Expand>
<Item Name="X">x()</Item>
<Item Name="Y">y()</Item>
<Item Name="Z">z()</Item>
<Item Name="W">w()</Item>
</Expand>
</Type>

<!-- mr::Radians -->
<Type Name="mr::Radians&lt;*&gt;">
<DisplayString>{_data} rad</DisplayString>
</Type>

<!-- mr::Degrees -->
<Type Name="mr::Degrees&lt;*&gt;">
<DisplayString>{_data} deg</DisplayString>
</Type>

<!-- mr::Color -->
<Type Name="mr::Color">
<DisplayString>R={r()}, G={g()}, B={b()}, A={a()}}</DisplayString>
<Expand>
<Item Name="R">r()</Item>
<Item Name="G">g()</Item>
<Item Name="B">b()</Item>
<Item Name="A">a()</Item>
<Item Name="Hex">(uint32_t(r() * 255) &lt;&lt; 24) + (uint32_t(g() * 255) &lt;&lt; 16) + (uint32_t(b() * 255) &lt;&lt; 8) + (uint32_t(a() * 255)), Xb</Item>
</Expand>
</Type>

<!-- mr::AABB -->
<Type Name="mr::AABB&lt;*&gt;">
<DisplayString>{min} : {max}</DisplayString>
<Expand>
<Item Name="Min">min</Item>
<Item Name="Max">max</Item>
<Item Name="Dimensions">dimensions()</Item>
</Expand>
</Type>

<!-- mr::Matr -->
<Type Name="mr::Matr&lt;*, *&gt;">
<DisplayString>{_data[0]} ...</DisplayString>
<Expand>
<Item Name="Rows">_data</Item>
</Expand>
</Type>

</AutoVisualizer>

0 comments on commit 5074848

Please sign in to comment.