Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Template for new versions:
## Fixes

## Misc Improvements
- Added ``Coord2d`` and ``Coord3d`` C++ templates, providing a standard set operations for 2-tuples and 3-tuples of any numeric type

## Documentation

Expand Down
3 changes: 2 additions & 1 deletion library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ set(MAIN_HEADERS
include/ColorText.h
include/Commands.h
include/Console.h
include/Coord.h
include/Core.h
include/CoreDefs.h
include/DataDefs.h
Expand Down Expand Up @@ -394,7 +395,7 @@ else()
endif()

add_library(dfhooks_dfhack SHARED Hooks.cpp)
target_link_libraries(dfhooks_dfhack PUBLIC dfhack ${FMTLIB})
target_link_libraries(dfhooks_dfhack PUBLIC dfhack lua ${FMTLIB})

# effectively disables debug builds...
set_target_properties(dfhack PROPERTIES DEBUG_POSTFIX "-debug" )
Expand Down
206 changes: 206 additions & 0 deletions library/include/Coord.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#pragma once

#include <array>
#include <concepts>
#include <span>

#include "DataDefs.h"
#include "DataFuncs.h"
#include "Export.h"

namespace DFHack
{
template <typename T>
constexpr T coord_default_initializer = static_cast<T>(-30000);

template <std::floating_point T>
constexpr T coord_default_initializer<T> = static_cast<T>(std::numeric_limits<T>::infinity());

template <typename T, T initializer = coord_default_initializer<T>>
struct Coord2d
{
T x; T y;

Coord2d() : x(initializer), y(initializer) {}
Coord2d(T x, T y) : x(x), y(y) {}

bool isValid() const { return x >= 0; }

void clear()
{
x = y = initializer;
}

bool operator==(const Coord2d& other) const
{
return x == other.x && y == other.y;
}
bool operator!=(const Coord2d& other) const
{
return x != other.x || y == other.y;
}
bool operator<(const Coord2d& other) const
{
return x < other.x || (x == other.x && y < other.y);
}

Coord2d operator+(const Coord2d& other) const
{
return {T(x + other.x), T(y + other.y)};
}
Coord2d operator-(const Coord2d& other) const
{
return {T(x - other.x), T(y - other.y)};
}
Coord2d operator/(T number) const
{
return {T(x / number), T(y / number)};
}
Coord2d operator*(T number) const
{
return {T(x * number), T(y * number)};
}
Coord2d operator%(T number) const requires std::integral<T>
{
return {T(x % number), T(y % number)};
}
Coord2d operator&(T number) const requires std::integral<T>
{
return {T(x & number), T(y & number)};
}

std::size_t operator()() const
{
size_t r = 17;
const size_t m = 65537;
r = m * (r + x);
r = m * (r + y);
return r;
}
};

template <typename T, T initializer = DFHack::coord_default_initializer<T>, typename U = DFHack::Coord2d<T, initializer>>
static const struct_field_info coord2d_fields[] = {
{ struct_field_info::PRIMITIVE, "x", offsetof(U, x), &df::identity_traits<T>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "y", offsetof(U, y), &df::identity_traits<T>::identity, 0, 0 },
{ struct_field_info::OBJ_METHOD, "isValid", 0, df::wrap_function(&U::isValid), 0, 0 },
{ struct_field_info::OBJ_METHOD, "clear", 0, df::wrap_function(&U::clear), 0, 0 } ,
{ struct_field_info::END }
};

template <typename T, T initializer = DFHack::coord_default_initializer<T>, typename U = DFHack::Coord2d<T, initializer>>
static inline const struct_identity coord2d_identity{sizeof(U), &df::allocator_fn<U>, nullptr, "coord", nullptr, coord2d_fields<T,initializer>};

template <typename T, T initializer = coord_default_initializer<T>>
struct Coord3d
{
T x; T y; T z;

Coord3d() : x(initializer), y(initializer), z(initializer) {}
Coord3d(Coord2d<T,initializer> c, T z) : x(c.x), y(c.y), z(z) {}
Coord3d(T x, T y, T z) : x(x), y(y), z(z) {}

operator Coord2d<T,initializer>() const
{
return {x,y};
}

bool isValid() const { return x >= 0; }

void clear()
{
x = y = z = initializer;
}

bool operator==(const Coord3d& other) const
{
return x == other.x && y == other.y && z == other.z;
}
bool operator!=(const Coord3d& other) const
{
return x != other.x || y == other.y || z == other.z;
}
bool operator<(const Coord3d& other) const
{
return x < other.x || (x == other.x && (y < other.y || (y == other.y && z < other.z)));
}

Coord3d operator+(const Coord3d& other) const
{
return {T(x + other.x), T(y + other.y), T(z + other.z)};
}
Coord3d operator-(const Coord3d& other) const
{
return {T(x - other.x), T(y - other.y), T(z - other.z)};
}
Coord3d operator/(T number) const
{
return {T(x / number), T(y / number), T(z / number)};
}
Coord3d operator*(T number) const
{
return {T(x * number), T(y * number), T(z * number)};
}
Coord3d operator%(T number) const requires std::integral<T>
{
return {T(x % number), T(y % number), T(z % number)};
}
Coord3d operator&(T number) const requires std::integral<T>
{
return {T(x & number), T(y & number), T(z & number)};
}

std::size_t operator()() const
{
size_t r = 17;
const size_t m = 65537;
r = m * (r + x);
r = m * (r + y);
r = m * (r + z);
return r;
}

// special weirdness used by the dig plugin

Coord3d operator-(T number) const
{
return Coord3d(x, y, z - number);
}
Coord3d operator+(T number) const
{
return Coord3d(x, y, z + number);
}
};

template <typename T, T initializer = DFHack::coord_default_initializer<T>, typename U = DFHack::Coord3d<T, initializer>>
static const struct_field_info coord3d_fields[] = {
{ struct_field_info::PRIMITIVE, "x", offsetof(U, x), &df::identity_traits<T>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "y", offsetof(U, y), &df::identity_traits<T>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "z", offsetof(U, y), &df::identity_traits<T>::identity, 0, 0 },
{ struct_field_info::OBJ_METHOD, "isValid", 0, df::wrap_function(&U::isValid), 0, 0 },
{ struct_field_info::OBJ_METHOD, "clear", 0, df::wrap_function(&U::clear), 0, 0 } ,
{ struct_field_info::END }
};

template <typename T, T initializer = DFHack::coord_default_initializer<T>, typename U = DFHack::Coord3d<T, initializer>>
static inline const struct_identity coord3d_identity{sizeof(U), &df::allocator_fn<U>, nullptr, "coord", nullptr, coord3d_fields<T, initializer>};
}

namespace df
{
template <typename T, T initializer>
struct DFHACK_EXPORT identity_traits<DFHack::Coord2d<T, initializer>>
{
static const bool is_primitive = false;
static const compound_identity* get() { return &DFHack::coord2d_identity<T,initializer>; }
};

template <typename T, T initializer>
struct DFHACK_EXPORT identity_traits<DFHack::Coord3d<T, initializer>>
{
static const bool is_primitive = false;
static const compound_identity* get() { return &DFHack::coord3d_identity<T, initializer>;
}
};

}
2 changes: 1 addition & 1 deletion plugins/Plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ macro(dfhack_plugin)
target_include_directories(${PLUGIN_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/proto")
target_link_libraries(${PLUGIN_NAME} protobuf-lite)
endif()
target_link_libraries(${PLUGIN_NAME} dfhack dfhack-version ${FMTLIB} ${PLUGIN_LINK_LIBRARIES})
target_link_libraries(${PLUGIN_NAME} dfhack dfhack-version lua ${FMTLIB} ${PLUGIN_LINK_LIBRARIES})

if(UNIX)
set(PLUGIN_COMPILE_FLAGS "${PLUGIN_COMPILE_FLAGS} ${PLUGIN_COMPILE_FLAGS_GCC}")
Expand Down
4 changes: 2 additions & 2 deletions plugins/blueprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ struct blueprint_options {
};
static const struct_field_info blueprint_options_fields[] = {
{ struct_field_info::PRIMITIVE, "help", offsetof(blueprint_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "start", offsetof(blueprint_options, start), &df::coord::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "start", offsetof(blueprint_options, start), df::identity_traits<df::coord>::get(), 0, 0},
{ struct_field_info::PRIMITIVE, "format", offsetof(blueprint_options, format), df::identity_traits<string>::get(), 0, 0 },
{ struct_field_info::PRIMITIVE, "nometa", offsetof(blueprint_options, nometa), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "playback_start", offsetof(blueprint_options, playback_start), &df::coord2d::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "playback_start", offsetof(blueprint_options, playback_start), df::identity_traits<df::coord2d>::get(),0, 0 },
{ struct_field_info::PRIMITIVE, "playback_start_comment", offsetof(blueprint_options, playback_start_comment), df::identity_traits<string>::get(), 0, 0 },
{ struct_field_info::PRIMITIVE, "split_strategy", offsetof(blueprint_options, split_strategy), df::identity_traits<string>::get(), 0, 0 },
{ struct_field_info::PRIMITIVE, "width", offsetof(blueprint_options, width), &df::identity_traits<int32_t>::identity, 0, 0 },
Expand Down
10 changes: 5 additions & 5 deletions plugins/dig-now.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ struct dig_now_options {
static struct_identity _identity;
};
static const struct_field_info dig_now_options_fields[] = {
{ struct_field_info::PRIMITIVE, "help", offsetof(dig_now_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "start", offsetof(dig_now_options, start), &df::coord::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "end", offsetof(dig_now_options, end), &df::coord::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "boulder_percents", offsetof(dig_now_options, boulder_percents), &boulder_percent_options::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "dump_pos", offsetof(dig_now_options, dump_pos), &df::coord::_identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "help", offsetof(dig_now_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "start", offsetof(dig_now_options, start), df::identity_traits<df::coord>::get(), 0, 0 },
{ struct_field_info::SUBSTRUCT, "end", offsetof(dig_now_options, end), df::identity_traits<df::coord>::get(), 0, 0 },
{ struct_field_info::SUBSTRUCT, "boulder_percents", offsetof(dig_now_options, boulder_percents), &boulder_percent_options::_identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "dump_pos", offsetof(dig_now_options, dump_pos), df::identity_traits<df::coord>::get(), 0, 0 },
{ struct_field_info::END }
};
struct_identity dig_now_options::_identity(sizeof(dig_now_options), &df::allocator_fn<dig_now_options>, NULL, "dig_now_options", NULL, dig_now_options_fields);
Expand Down
7 changes: 4 additions & 3 deletions plugins/tiletypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ using std::set;
#include "modules/MapCache.h"
#include "modules/Maps.h"

#include "df/coord2d.h"
#include "df/tile_dig_designation.h"
#include "df/world.h"

Expand All @@ -68,9 +69,9 @@ struct tiletypes_options {
static struct_identity _identity;
};
static const struct_field_info tiletypes_options_fields[] = {
{ struct_field_info::PRIMITIVE, "help", offsetof(tiletypes_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "quiet", offsetof(tiletypes_options, quiet), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "cursor", offsetof(tiletypes_options, cursor), &df::coord::_identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "help", offsetof(tiletypes_options, help), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::PRIMITIVE, "quiet", offsetof(tiletypes_options, quiet), &df::identity_traits<bool>::identity, 0, 0 },
{ struct_field_info::SUBSTRUCT, "cursor", offsetof(tiletypes_options, cursor), df::identity_traits<df::coord>::get(), 0, 0},
{ struct_field_info::END }
};
struct_identity tiletypes_options::_identity(sizeof(tiletypes_options), &df::allocator_fn<tiletypes_options>, NULL, "tiletypes_options", NULL, tiletypes_options_fields);
Expand Down
Loading