misc: Fix Attachment shared pointer reinterpret (#154)

This commit is contained in:
Lee Bousfield 2025-03-10 12:41:37 -05:00 committed by GitHub
parent 81498562d0
commit 258cfeb3d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 104 additions and 12 deletions

View file

@ -29,7 +29,7 @@ pkg_check_modules(
libinput>=1.26.0
wayland-client
wayland-protocols
hyprutils>=0.2.3
hyprutils>=0.5.2
pixman-1
libdrm
gbm
@ -137,6 +137,14 @@ add_test(
COMMAND simpleWindow "simpleWindow")
add_dependencies(tests simpleWindow)
add_executable(attachments "tests/Attachments.cpp")
target_link_libraries(attachments PRIVATE PkgConfig::deps aquamarine)
add_test(
NAME "attachments"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
COMMAND attachments "attachments")
add_dependencies(tests attachments)
# Installation
install(TARGETS aquamarine)
install(DIRECTORY "include/aquamarine" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

18
flake.lock generated
View file

@ -10,11 +10,11 @@
]
},
"locked": {
"lastModified": 1737978343,
"narHash": "sha256-TfFS0HCEJh63Kahrkp1h9hVDMdLU8a37Zz+IFucxyfA=",
"lastModified": 1741534688,
"narHash": "sha256-EV3945SnjOCuRVbGRghsWx/9D89FyshnSO1Q6/TuQ14=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "6a8bc9d2a4451df12f5179dc0b1d2d46518a90ab",
"rev": "dd1f720cbc2dbb3c71167c9598045dd3261d27b3",
"type": "github"
},
"original": {
@ -33,11 +33,11 @@
]
},
"locked": {
"lastModified": 1735493474,
"narHash": "sha256-fktzv4NaqKm94VAkAoVqO/nqQlw+X0/tJJNAeCSfzK4=",
"lastModified": 1739870480,
"narHash": "sha256-SiDN5BGxa/1hAsqhgJsS03C3t2QrLgBT8u+ENJ0Qzwc=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
"rev": "de913476b59ee88685fdc018e77b8f6637a2ae0b",
"rev": "206367a08dc5ac4ba7ad31bdca391d098082e64b",
"type": "github"
},
"original": {
@ -48,11 +48,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1737885589,
"narHash": "sha256-Zf0hSrtzaM1DEz8//+Xs51k/wdSajticVrATqDrfQjg=",
"lastModified": 1741379970,
"narHash": "sha256-Wh7esNh7G24qYleLvgOSY/7HlDUzWaL/n4qzlBePpiw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "852ff1d9e153d8875a83602e03fdef8a63f0ecf8",
"rev": "36fd87baa9083f34f7f5027900b62ee6d09b1f2f",
"type": "github"
},
"original": {

View file

@ -33,7 +33,7 @@ namespace Aquamarine {
// Reinterpret SP<IAttachment> into SP<T>.
// This is safe because we looked up this attachment by typeid(T),
// so it must be an SP<T>.
return *reinterpret_cast<const Hyprutils::Memory::CSharedPointer<T>*>(&it->second);
return Hyprutils::Memory::reinterpretPointerCast<T>(it->second);
}
// Also removes the previous attachment of the same type if one exists
void add(Hyprutils::Memory::CSharedPointer<IAttachment> attachment);

View file

@ -12,7 +12,7 @@ void Aquamarine::CAttachmentManager::add(SP<IAttachment> attachment) {
void Aquamarine::CAttachmentManager::remove(SP<IAttachment> attachment) {
const IAttachment& att = *attachment;
auto it = attachments.find(typeid(att));
if (it != attachments.end())
if (it != attachments.end() && it->second == attachment)
attachments.erase(it);
}

64
tests/Attachments.cpp Normal file
View file

@ -0,0 +1,64 @@
#include <aquamarine/misc/Attachment.hpp>
#include <hyprutils/memory/SharedPtr.hpp>
#include <hyprutils/memory/WeakPtr.hpp>
#include "shared.hpp"
class CFooAttachment : public Aquamarine::IAttachment {
public:
int counter = 0;
};
class CBarAttachment : public Aquamarine::IAttachment {
public:
int counter = 0;
};
int main() {
Aquamarine::CAttachmentManager attachments;
int ret = 0;
EXPECT(attachments.has<CFooAttachment>(), false);
EXPECT(attachments.get<CFooAttachment>(), nullptr);
EXPECT(attachments.has<CBarAttachment>(), false);
EXPECT(attachments.get<CBarAttachment>(), nullptr);
auto foo = Hyprutils::Memory::makeShared<CFooAttachment>();
attachments.add(foo);
EXPECT(attachments.has<CFooAttachment>(), true);
EXPECT(attachments.has<CBarAttachment>(), false);
foo->counter++;
EXPECT(attachments.get<CFooAttachment>(), foo);
EXPECT(attachments.get<CFooAttachment>()->counter, 1);
attachments.add(Hyprutils::Memory::makeShared<CBarAttachment>());
EXPECT(attachments.get<CFooAttachment>()->counter, 1);
EXPECT(attachments.get<CBarAttachment>()->counter, 0);
Hyprutils::Memory::CWeakPointer<CBarAttachment> bar = attachments.get<CBarAttachment>();
EXPECT(bar.valid(), true);
bar->counter = 5;
// test overriding an attachment
attachments.add(Hyprutils::Memory::makeShared<CBarAttachment>());
Hyprutils::Memory::CWeakPointer<CBarAttachment> newBar = attachments.get<CBarAttachment>();
EXPECT(bar == newBar, false);
EXPECT(attachments.get<CBarAttachment>()->counter, 0);
// should be a noop as this is a different attachment
attachments.remove(Hyprutils::Memory::makeShared<CFooAttachment>());
EXPECT(attachments.has<CFooAttachment>(), true);
EXPECT(attachments.has<CBarAttachment>(), true);
attachments.remove(foo);
EXPECT(attachments.has<CFooAttachment>(), false);
EXPECT(attachments.has<CBarAttachment>(), true);
attachments.removeByType<CBarAttachment>();
EXPECT(attachments.has<CFooAttachment>(), false);
EXPECT(attachments.has<CBarAttachment>(), false);
EXPECT(foo.strongRef(), 1);
EXPECT(bar.valid(), false);
EXPECT(newBar.valid(), false);
return ret;
}

20
tests/shared.hpp Normal file
View file

@ -0,0 +1,20 @@
#pragma once
#include <iostream>
namespace Colors {
constexpr const char* RED = "\x1b[31m";
constexpr const char* GREEN = "\x1b[32m";
constexpr const char* YELLOW = "\x1b[33m";
constexpr const char* BLUE = "\x1b[34m";
constexpr const char* MAGENTA = "\x1b[35m";
constexpr const char* CYAN = "\x1b[36m";
constexpr const char* RESET = "\x1b[0m";
};
#define EXPECT(expr, val) \
if (const auto RESULT = expr; RESULT != (val)) { \
std::cout << Colors::RED << "Failed: " << Colors::RESET << #expr << ", expected " << val << " but got " << RESULT << "\n"; \
ret = 1; \
} else { \
std::cout << Colors::GREEN << "Passed " << Colors::RESET << #expr << ". Got " << val << "\n"; \
}