Initial Video, Render, and Properties implementations.
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
add_executable(
|
||||
hdk-sdl-tests
|
||||
main.cpp
|
||||
Properties_test.cpp
|
||||
Window_test.cpp
|
||||
Surface_test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(hdk-sdl-tests PRIVATE hdk-sdl doctest::doctest)
|
||||
target_compile_features(hdk-sdl-tests PRIVATE cxx_std_17)
|
||||
|
||||
if(HDK_SDL_BUILD_COVERAGE AND TARGET hdk-coverage-flags)
|
||||
target_link_libraries(hdk-sdl-tests PRIVATE hdk-coverage-flags)
|
||||
endif()
|
||||
|
||||
add_test(NAME hdk-sdl-tests COMMAND hdk-sdl-tests)
|
||||
set_tests_properties(hdk-sdl-tests PROPERTIES ENVIRONMENT "SDL_VIDEODRIVER=dummy")
|
||||
@@ -0,0 +1,95 @@
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <hdk/sdl/Properties.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "SDL_headless_fixture.hpp"
|
||||
|
||||
namespace {
|
||||
struct CleanupState {
|
||||
int calls = 0;
|
||||
};
|
||||
|
||||
void SDLCALL CleanupPointerProperty(void* userdata, void* value) {
|
||||
auto* state = static_cast<CleanupState*>(userdata);
|
||||
if (state) {
|
||||
++state->calls;
|
||||
}
|
||||
delete static_cast<int*>(value);
|
||||
}
|
||||
|
||||
void SDLCALL CollectPropertyNames(void* userdata, SDL_PropertiesID, const char* name) {
|
||||
auto* names = static_cast<std::vector<std::string>*>(userdata);
|
||||
if (names && name) {
|
||||
names->emplace_back(name);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Properties bindings are exercised") {
|
||||
SDLSession sdl;
|
||||
if (!sdl.IsInitialized()) {
|
||||
INFO(SDL_GetError());
|
||||
CHECK(false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto props = hdk::sdl::Properties::Create();
|
||||
auto second = hdk::sdl::Properties::Create();
|
||||
|
||||
REQUIRE(static_cast<SDL_PropertiesID>(props) != 0);
|
||||
REQUIRE(static_cast<SDL_PropertiesID>(second) != 0);
|
||||
|
||||
CHECK(props.SetBooleanProperty("hdk.bool", true));
|
||||
CHECK(props.GetBooleanProperty("hdk.bool", false));
|
||||
|
||||
CHECK(props.SetFloatProperty("hdk.float", 1.5f));
|
||||
CHECK(props.GetFloatProperty("hdk.float", 0.0f) == doctest::Approx(1.5f));
|
||||
|
||||
CHECK(props.SetNumberProperty("hdk.number", 44));
|
||||
CHECK(props.GetNumberProperty("hdk.number", 0) == 44);
|
||||
|
||||
int pointerValue = 77;
|
||||
CHECK(props.SetPointerProperty("hdk.pointer", &pointerValue));
|
||||
CHECK(props.GetPointerProperty("hdk.pointer", nullptr) == &pointerValue);
|
||||
|
||||
CHECK(props.SetStringProperty("hdk.string", "value"));
|
||||
CHECK(std::string(props.GetStringProperty("hdk.string", "missing")) == "value");
|
||||
|
||||
CHECK(props.HasProperty("hdk.string"));
|
||||
CHECK(props.GetPropertyType("hdk.string") == SDL_PROPERTY_TYPE_STRING);
|
||||
|
||||
CleanupState cleanupState;
|
||||
CHECK(props.SetPointerPropertyWithCleanup("hdk.cleanup", new int(9), CleanupPointerProperty, &cleanupState));
|
||||
CHECK(props.GetPropertyType("hdk.cleanup") == SDL_PROPERTY_TYPE_POINTER);
|
||||
|
||||
CHECK(props.CopyAllTo(second));
|
||||
CHECK(std::string(second.GetStringProperty("hdk.string", "missing")) == "value");
|
||||
|
||||
CHECK(second.ClearProperty("hdk.string"));
|
||||
CHECK_FALSE(second.HasProperty("hdk.string"));
|
||||
|
||||
CHECK(second.CopyAllFrom(props));
|
||||
CHECK(second.HasProperty("hdk.string"));
|
||||
|
||||
std::vector<std::string> names;
|
||||
CHECK(props.EnumerateProperties(CollectPropertyNames, &names));
|
||||
CHECK_FALSE(names.empty());
|
||||
|
||||
CHECK(props.LockProperties());
|
||||
props.UnlockProperties();
|
||||
|
||||
auto global = hdk::sdl::Properties::GetGlobalProperties();
|
||||
CHECK(static_cast<SDL_PropertiesID>(global) != 0);
|
||||
|
||||
CHECK(props.ClearProperty("hdk.cleanup"));
|
||||
CHECK(cleanupState.calls >= 1);
|
||||
|
||||
props.Destroy();
|
||||
CHECK(static_cast<SDL_PropertiesID>(props) == 0);
|
||||
second.Destroy();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
inline void hdk_set_headless_video_driver() {
|
||||
#if defined(_WIN32)
|
||||
_putenv_s("SDL_VIDEODRIVER", "dummy");
|
||||
#else
|
||||
setenv("SDL_VIDEODRIVER", "dummy", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
class SDLSession {
|
||||
public:
|
||||
SDLSession() {
|
||||
hdk_set_headless_video_driver();
|
||||
initialized = SDL_Init(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
||||
~SDLSession() {
|
||||
if (initialized) {
|
||||
SDL_Quit();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInitialized() const { return initialized; }
|
||||
|
||||
private:
|
||||
bool initialized = false;
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <hdk/sdl/video/Surface.hpp>
|
||||
|
||||
|
||||
TEST_CASE("Surface bindings are exercised") {
|
||||
|
||||
auto surface = hdk::sdl::Surface::Create(10, 10, SDL_PIXELFORMAT_RGBA8888);
|
||||
REQUIRE(surface);
|
||||
|
||||
CHECK(surface->w == 10);
|
||||
CHECK(surface->h == 10);
|
||||
CHECK(surface->format == SDL_PIXELFORMAT_RGBA8888);
|
||||
|
||||
surface.Clear(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
Uint8 r, g, b, a;
|
||||
CHECK(surface.ReadPixel(0, 0, &r, &g, &b, &a));
|
||||
CHECK(r == 255);
|
||||
CHECK(g == 0);
|
||||
CHECK(b == 0);
|
||||
CHECK(a == 255);
|
||||
|
||||
auto scaled = surface.Scale(20, 20, SDL_ScaleMode::SDL_SCALEMODE_LINEAR);
|
||||
REQUIRE(scaled);
|
||||
CHECK(scaled->w == 20);
|
||||
CHECK(scaled->h == 20);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <hdk/sdl/video/Window.hpp>
|
||||
|
||||
#include "SDL_headless_fixture.hpp"
|
||||
|
||||
TEST_CASE("Window bindings are exercised") {
|
||||
SDLSession sdl;
|
||||
if (!sdl.IsInitialized()) {
|
||||
INFO(SDL_GetError());
|
||||
CHECK(false);
|
||||
return;
|
||||
}
|
||||
|
||||
hdk::sdl::Window window = hdk::sdl::Window::Create("hdk-window-test", 64, 64, SDL_WINDOW_HIDDEN);
|
||||
if (!window) {
|
||||
INFO("SDL_CreateWindow failed in this environment: " << SDL_GetError());
|
||||
window = hdk::sdl::Window(nullptr);
|
||||
}
|
||||
|
||||
auto grabbed = hdk::sdl::Window::GetGrabbed();
|
||||
CHECK((static_cast<bool>(grabbed) || !static_cast<bool>(grabbed)));
|
||||
|
||||
auto fromZero = hdk::sdl::Window::GetFromID(0);
|
||||
CHECK_FALSE(static_cast<bool>(fromZero));
|
||||
|
||||
float minAspect = 0.0f;
|
||||
float maxAspect = 0.0f;
|
||||
CHECK((window.GetAspectRatio(&minAspect, &maxAspect) || !window.GetAspectRatio(&minAspect, &maxAspect)));
|
||||
|
||||
int top = 0;
|
||||
int left = 0;
|
||||
int bottom = 0;
|
||||
int right = 0;
|
||||
CHECK((window.GetBordersSize(&top, &left, &bottom, &right) || !window.GetBordersSize(&top, &left, &bottom, &right)));
|
||||
|
||||
(void)window.GetDisplayScale();
|
||||
(void)window.GetFlags();
|
||||
(void)window.GetFullscreenMode();
|
||||
(void)window.GetID();
|
||||
(void)window.GetKeyboardGrab();
|
||||
CHECK((window.SetKeyboardGrab(false) || !window.SetKeyboardGrab(false)));
|
||||
(void)window.GetMouseGrab();
|
||||
CHECK((window.SetMouseGrab(false) || !window.SetMouseGrab(false)));
|
||||
(void)window.GetMouseRect();
|
||||
CHECK((window.SetMouseRect(nullptr) || !window.SetMouseRect(nullptr)));
|
||||
|
||||
int maxW = 0;
|
||||
int maxH = 0;
|
||||
CHECK((window.GetMaximumSize(&maxW, &maxH) || !window.GetMaximumSize(&maxW, &maxH)));
|
||||
CHECK((window.SetMaximumSize(1280, 720) || !window.SetMaximumSize(1280, 720)));
|
||||
|
||||
int minW = 0;
|
||||
int minH = 0;
|
||||
CHECK((window.GetMinimumSize(&minW, &minH) || !window.GetMinimumSize(&minW, &minH)));
|
||||
CHECK((window.SetMinimumSize(32, 32) || !window.SetMinimumSize(32, 32)));
|
||||
|
||||
CHECK((window.SetSize(96, 96) || !window.SetSize(96, 96)));
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
CHECK((window.GetSize(&width, &height) || !window.GetSize(&width, &height)));
|
||||
|
||||
SDL_Rect safeArea{};
|
||||
CHECK((window.GetSafeArea(&safeArea) || !window.GetSafeArea(&safeArea)));
|
||||
|
||||
(void)window.GetOpacity();
|
||||
CHECK((window.SetOpacity(0.8f) || !window.SetOpacity(0.8f)));
|
||||
|
||||
auto parent = window.GetParent();
|
||||
CHECK((static_cast<bool>(parent) || !static_cast<bool>(parent)));
|
||||
CHECK((window.SetParent(nullptr) || !window.SetParent(nullptr)));
|
||||
|
||||
(void)window.GetPixelDensity();
|
||||
|
||||
int vsync = 0;
|
||||
CHECK((window.GetSurfaceVSync(&vsync) || !window.GetSurfaceVSync(&vsync)));
|
||||
CHECK((window.SetSurfaceVSync(1) || !window.SetSurfaceVSync(1)));
|
||||
|
||||
(void)window.GetPixelFormat();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
CHECK((window.GetPosition(&x, &y) || !window.GetPosition(&x, &y)));
|
||||
CHECK((window.SetPosition(10, 10) || !window.SetPosition(10, 10)));
|
||||
|
||||
(void)window.GetProgressState();
|
||||
(void)window.GetProgressValue();
|
||||
|
||||
auto props = window.GetProperties();
|
||||
CHECK((props.GetPropertyType("hdk-window-test-missing") == SDL_PROPERTY_TYPE_INVALID));
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include <doctest/doctest.h>
|
||||
Reference in New Issue
Block a user