Skip to content

Commit

Permalink
Extract Crawl to a library
Browse files Browse the repository at this point in the history
Also adds a test and a benchmark
  • Loading branch information
glebm committed Aug 4, 2024
1 parent b3863c7 commit 077b51a
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 116 deletions.
8 changes: 8 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ target_link_libraries(libdevilutionx_codec PRIVATE
libdevilutionx_log
)

add_devilutionx_object_library(libdevilutionx_crawl
crawl.cpp
)
target_link_libraries(libdevilutionx_crawl PUBLIC
tl
)

add_devilutionx_object_library(libdevilutionx_file_util
utils/file_util.cpp
)
Expand Down Expand Up @@ -397,6 +404,7 @@ target_link_libraries(libdevilutionx PUBLIC
simpleini::simpleini
tl
libdevilutionx_codec
libdevilutionx_crawl
libdevilutionx_format_int
libdevilutionx_file_util
libdevilutionx_parse_int
Expand Down
74 changes: 74 additions & 0 deletions Source/crawl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "crawl.hpp"

#include <type_traits>

#include <function_ref.hpp>

#include "engine/displacement.hpp"

namespace devilution {
namespace {

bool CrawlFlipsX(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored.flipX(), mirrored }) {
if (!function(displacement))
return false;
}
return true;
}

bool CrawlFlipsY(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored, mirrored.flipY() }) {
if (!function(displacement))
return false;
}
return true;
}

bool CrawlFlipsXY(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored.flipX(), mirrored, mirrored.flipXY(), mirrored.flipY() }) {
if (!function(displacement))
return false;
}
return true;
}

} // namespace

bool DoCrawl(unsigned radius, tl::function_ref<bool(Displacement)> function)
{
if (radius == 0)
return function(Displacement { 0, 0 });

if (!CrawlFlipsY({ 0, static_cast<int>(radius) }, function))
return false;
for (unsigned i = 1; i < radius; i++) {
if (!CrawlFlipsXY({ static_cast<int>(i), static_cast<int>(radius) }, function))
return false;
}
if (radius > 1) {
if (!CrawlFlipsXY({ static_cast<int>(radius) - 1, static_cast<int>(radius) - 1 }, function))
return false;
}
if (!CrawlFlipsX({ static_cast<int>(radius), 0 }, function))
return false;
for (unsigned i = 1; i < radius; i++) {
if (!CrawlFlipsXY({ static_cast<int>(radius), static_cast<int>(i) }, function))
return false;
}
return true;
}

bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref<bool(Displacement)> function)
{
for (unsigned i = minRadius; i <= maxRadius; i++) {
if (!DoCrawl(i, function))
return false;
}
return true;
}

} // namespace devilution
58 changes: 58 additions & 0 deletions Source/crawl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <type_traits>

#include <function_ref.hpp>

#include "engine/displacement.hpp"

namespace devilution {

/**
* CrawlTable specifies X- and Y-coordinate deltas from a missile target coordinate.
*
* n=4
*
* y
* ^
* | 1
* | 3#4
* | 2
* +-----> x
*
* n=16
*
* y
* ^
* | 314
* | B7 8C
* | F # G
* | D9 AE
* | 526
* +-------> x
*/

bool DoCrawl(unsigned radius, tl::function_ref<bool(Displacement)> function);
bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref<bool(Displacement)> function);

template <typename F>
auto Crawl(unsigned radius, F function) -> std::invoke_result_t<decltype(function), Displacement>
{
std::invoke_result_t<decltype(function), Displacement> result;
DoCrawl(radius, [&result, &function](Displacement displacement) -> bool {
result = function(displacement);
return !result;
});
return result;
}

template <typename F>
auto Crawl(unsigned minRadius, unsigned maxRadius, F function) -> std::invoke_result_t<decltype(function), Displacement>
{
std::invoke_result_t<decltype(function), Displacement> result;
DoCrawl(minRadius, maxRadius, [&result, &function](Displacement displacement) -> bool {
result = function(displacement);
return !result;
});
return result;
}

} // namespace devilution
1 change: 1 addition & 0 deletions Source/engine/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <function_ref.hpp>

#include "crawl.hpp"
#include "levels/gendung.h"
#include "lighting.h"
#include "objects.h"
Expand Down
60 changes: 0 additions & 60 deletions Source/lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,33 +113,6 @@ DVL_ALWAYS_INLINE uint8_t GetLight(Point position)
return dLight[position.x][position.y];
}

bool CrawlFlipsX(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored.flipX(), mirrored }) {
if (!function(displacement))
return false;
}
return true;
}

bool CrawlFlipsY(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored, mirrored.flipY() }) {
if (!function(displacement))
return false;
}
return true;
}

bool CrawlFlipsXY(Displacement mirrored, tl::function_ref<bool(Displacement)> function)
{
for (const Displacement displacement : { mirrored.flipX(), mirrored, mirrored.flipXY(), mirrored.flipY() }) {
if (!function(displacement))
return false;
}
return true;
}

bool TileAllowsLight(Point position)
{
if (!InDungeonBounds(position))
Expand All @@ -161,39 +134,6 @@ void DoVisionFlags(Point position, MapExplorationType doAutomap, bool visible)

} // namespace

bool DoCrawl(unsigned radius, tl::function_ref<bool(Displacement)> function)
{
if (radius == 0)
return function(Displacement { 0, 0 });

if (!CrawlFlipsY({ 0, static_cast<int>(radius) }, function))
return false;
for (unsigned i = 1; i < radius; i++) {
if (!CrawlFlipsXY({ static_cast<int>(i), static_cast<int>(radius) }, function))
return false;
}
if (radius > 1) {
if (!CrawlFlipsXY({ static_cast<int>(radius) - 1, static_cast<int>(radius) - 1 }, function))
return false;
}
if (!CrawlFlipsX({ static_cast<int>(radius), 0 }, function))
return false;
for (unsigned i = 1; i < radius; i++) {
if (!CrawlFlipsXY({ static_cast<int>(radius), static_cast<int>(i) }, function))
return false;
}
return true;
}

bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref<bool(Displacement)> function)
{
for (unsigned i = minRadius; i <= maxRadius; i++) {
if (!DoCrawl(i, function))
return false;
}
return true;
}

void DoUnLight(Point position, uint8_t radius)
{
radius++;
Expand Down
49 changes: 0 additions & 49 deletions Source/lighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,53 +86,4 @@ void lighting_color_cycling();

constexpr int MaxCrawlRadius = 18;

/**
* CrawlTable specifies X- and Y-coordinate deltas from a missile target coordinate.
*
* n=4
*
* y
* ^
* | 1
* | 3#4
* | 2
* +-----> x
*
* n=16
*
* y
* ^
* | 314
* | B7 8C
* | F # G
* | D9 AE
* | 526
* +-------> x
*/

bool DoCrawl(unsigned radius, tl::function_ref<bool(Displacement)> function);
bool DoCrawl(unsigned minRadius, unsigned maxRadius, tl::function_ref<bool(Displacement)> function);

template <typename F>
auto Crawl(unsigned radius, F function) -> std::invoke_result_t<decltype(function), Displacement>
{
std::invoke_result_t<decltype(function), Displacement> result;
DoCrawl(radius, [&result, &function](Displacement displacement) -> bool {
result = function(displacement);
return !result;
});
return result;
}

template <typename F>
auto Crawl(unsigned minRadius, unsigned maxRadius, F function) -> std::invoke_result_t<decltype(function), Displacement>
{
std::invoke_result_t<decltype(function), Displacement> result;
DoCrawl(minRadius, maxRadius, [&result, &function](Displacement displacement) -> bool {
result = function(displacement);
return !result;
});
return result;
}

} // namespace devilution
1 change: 1 addition & 0 deletions Source/lua/modules/dev/monsters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <sol/sol.hpp>

#include "crawl.hpp"
#include "levels/gendung.h"
#include "lighting.h"
#include "lua/metadoc.hpp"
Expand Down
1 change: 1 addition & 0 deletions Source/missiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "control.h"
#include "controls/plrctrls.h"
#include "crawl.hpp"
#include "cursor.h"
#include "dead.h"
#ifdef _DEBUG
Expand Down
1 change: 1 addition & 0 deletions Source/monster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <fmt/format.h>

#include "control.h"
#include "crawl.hpp"
#include "cursor.h"
#include "dead.h"
#include "engine/load_cl2.hpp"
Expand Down
18 changes: 15 additions & 3 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ set(tests
drlg_l4_test
effects_test
inv_test
lighting_test
math_test
missiles_test
pack_test
Expand All @@ -40,24 +39,30 @@ set(tests
)
set(standalone_tests
codec_test
crawl_test
file_util_test
format_int_test
parse_int_test
str_cat_test
utf8_test
)
set(benchmarks
crawl_benchmark)

include(Fixtures.cmake)

foreach(test_target ${tests} ${standalone_tests})
foreach(test_target ${tests} ${standalone_tests} ${benchmarks})
add_executable(${test_target} "${test_target}.cpp")
gtest_discover_tests(${test_target})
set_target_properties(${test_target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
if(GPERF)
target_link_libraries(${test_target} PUBLIC ${GPERFTOOLS_LIBRARIES})
endif()
endforeach()

foreach(test_target ${tests} ${standalone_tests})
gtest_discover_tests(${test_target})
endforeach()

foreach(test_target ${tests})
target_link_libraries(${test_target} PRIVATE test_main)
endforeach()
Expand All @@ -67,13 +72,20 @@ foreach(test_target ${standalone_tests})
target_include_directories(${test_target} PRIVATE "${PROJECT_SOURCE_DIR}/Source")
endforeach()

foreach(target ${benchmarks})
target_link_libraries(${target} PRIVATE benchmark::benchmark benchmark::benchmark_main)
target_include_directories(${target} PRIVATE "${PROJECT_SOURCE_DIR}/Source")
endforeach()

add_library(app_fatal_for_testing OBJECT app_fatal_for_testing.cpp)
target_sources(app_fatal_for_testing INTERFACE $<TARGET_OBJECTS:app_fatal_for_testing>)

add_library(language_for_testing OBJECT language_for_testing.cpp)
target_sources(language_for_testing INTERFACE $<TARGET_OBJECTS:language_for_testing>)

target_link_libraries(codec_test PRIVATE libdevilutionx_codec app_fatal_for_testing)
target_link_libraries(crawl_test PRIVATE libdevilutionx_crawl)
target_link_libraries(crawl_benchmark PRIVATE libdevilutionx_crawl)
target_link_libraries(file_util_test PRIVATE libdevilutionx_file_util app_fatal_for_testing)
target_link_libraries(format_int_test PRIVATE libdevilutionx_format_int language_for_testing)
target_link_libraries(parse_int_test PRIVATE libdevilutionx_parse_int)
Expand Down
Loading

0 comments on commit 077b51a

Please sign in to comment.