Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract Crawl to a library, add a test and a benchmark #7216

Merged
merged 3 commits into from
Aug 7, 2024
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
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install tar curl zip unzip bash-completion build-essential ripgrep htop \
ninja-build ccache g++ mold gdb clang-format clang-tidy \
rpm pkg-config cmake git smpq gettext libsdl2-dev libsdl2-image-dev libsodium-dev \
libpng-dev libbz2-dev libfmt-dev libgtest-dev libgmock-dev libsimpleini-dev zsh \
libpng-dev libbz2-dev libfmt-dev libgtest-dev libgmock-dev libbenchmark-dev libsimpleini-dev zsh \
qtbase5-dev qt6-base-dev ristretto \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

Expand Down
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,6 @@ end_of_line = lf

[devilutionx.spec]
end_of_line = lf

[Dockerfile]
end_of_line = lf
6 changes: 4 additions & 2 deletions .github/workflows/Linux_x86_64_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,19 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y cmake curl g++ git lcov libgtest-dev libgmock-dev libfmt-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
sudo apt-get install -y cmake curl g++ git lcov libgtest-dev libgmock-dev libbenchmark-dev libfmt-dev libsdl2-dev libsodium-dev libpng-dev libbz2-dev wget
- name: Cache CMake build folder
uses: actions/cache@v4
with:
path: build
key: ${{ github.workflow }}-v1-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v1-

# We specify `-DDEVILUTIONX_SYSTEM_BENCHMARK=OFF` to work around the following error:
# lto1: fatal error: bytecode stream in file ‘/usr/lib/x86_64-linux-gnu/libbenchmark_main.a’ generated with LTO version 11.2 instead of the expected 11.3
- name: Build tests
run: |
cmake -S. -Bbuild -DENABLE_CODECOVERAGE=ON
cmake -S. -Bbuild -DENABLE_CODECOVERAGE=ON -DDEVILUTIONX_SYSTEM_BENCHMARK=OFF
wget -nc https://github.com/diasurgical/devilutionx-assets/releases/download/v2/spawn.mpq -P build
cmake --build build -j $(nproc)

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/src_dist_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Create Build Environment
run: >
sudo apt-get update &&
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev git smpq gettext python-is-python3
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3

- name: Build
working-directory: ${{github.workspace}}
Expand Down Expand Up @@ -55,7 +55,7 @@ jobs:
- name: Create Build Environment
run: >
sudo apt-get update &&
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev git smpq gettext python-is-python3
sudo apt-get install -y cmake curl libsdl2-dev libsdl2-image-dev libfmt-dev libsodium-dev libbz2-dev libgtest-dev libgmock-dev libbenchmark-dev git smpq gettext python-is-python3

- name: Build
working-directory: ${{github.workspace}}
Expand Down
16 changes: 16 additions & 0 deletions 3rdParty/benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
include(functions/FetchContent_MakeAvailableExcludeFromAll)

FetchContent_Declare(
benchmark
URL https://github.com/google/benchmark/archive/refs/tags/v1.8.5.tar.gz
URL_HASH MD5=708d91ce255e8af4c1d7dfec50dff178
)

set(INSTALL_GTEST OFF)

set(BENCHMARK_ENABLE_TESTING OFF)
set(BENCHMARK_ENABLE_EXCEPTIONS OFF)
set(BENCHMARK_ENABLE_WERROR OFF)
set(BENCHMARK_ENABLE_INSTALL OFF)

FetchContent_MakeAvailable(benchmark)
1 change: 1 addition & 0 deletions Brewfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ brew "sdl2"
brew "libsodium"
brew "pkg-config"
brew "googletest"
brew "google-benchmark"
7 changes: 7 additions & 0 deletions CMake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ if(BUILD_TESTING)
else()
add_subdirectory(3rdParty/googletest)
endif()

dependency_options("benchmark" DEVILUTIONX_SYSTEM_BENCHMARK ON DEVILUTIONX_STATIC_BENCHMARK)
if(DEVILUTIONX_SYSTEM_BENCHMARK)
find_package(benchmark REQUIRED)
else()
add_subdirectory(3rdParty/benchmark)
endif()
endif()

if(GPERF)
Expand Down
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
Loading
Loading