blob: 2334e459b6520a6c415fe3995fedb53e6d24fc68 [file] [log] [blame]
/*
* Copyright 2022 Rive
*/
#include <rive/refcnt.hpp>
#include <catch.hpp>
#include <cstdio>
using namespace rive;
class MyRefCnt : public RefCnt<MyRefCnt>
{
public:
MyRefCnt() {}
MyRefCnt(int, float, bool) {}
void require_count(int value) { REQUIRE(this->debugging_refcnt() == value); }
};
TEST_CASE("refcnt", "[basics]")
{
MyRefCnt my;
REQUIRE(my.debugging_refcnt() == 1);
my.ref();
REQUIRE(my.debugging_refcnt() == 2);
my.unref();
REQUIRE(my.debugging_refcnt() == 1);
safe_ref(&my);
REQUIRE(my.debugging_refcnt() == 2);
safe_unref(&my);
REQUIRE(my.debugging_refcnt() == 1);
// just exercise these to be sure they don't crash
safe_ref((MyRefCnt*)nullptr);
safe_unref((MyRefCnt*)nullptr);
}
TEST_CASE("rcp", "[basics]")
{
rcp<MyRefCnt> r0(nullptr);
REQUIRE(r0.get() == nullptr);
REQUIRE(!r0);
auto r1 = make_rcp<MyRefCnt>();
REQUIRE(r1.get() != nullptr);
REQUIRE(r1);
REQUIRE(r1 != r0);
REQUIRE(r1->debugging_refcnt() == 1);
auto r2 = r1;
REQUIRE(r1.get() == r2.get());
REQUIRE(r1 == r2);
REQUIRE(r2->debugging_refcnt() == 2);
auto r3 = make_rcp<MyRefCnt>(1, .5f, false);
REQUIRE(r3.get() != nullptr);
REQUIRE(r3);
REQUIRE(r3 != r1);
REQUIRE(r3->debugging_refcnt() == 1);
auto ptr = r2.release();
REQUIRE(r2.get() == nullptr);
REQUIRE(r1.get() == ptr);
// This is important, calling release() does not modify the ref count on the object
// We have to manage that explicit since we called release()
REQUIRE(r1->debugging_refcnt() == 2);
ptr->unref();
REQUIRE(r1->debugging_refcnt() == 1);
r1.reset();
REQUIRE(r1.get() == nullptr);
struct A : public rive::RefCnt<A>
{
int x = 17;
};
struct B : public A
{
int y = 21;
};
auto b = make_rcp<B>();
CHECK(b->y == 21);
rcp<A> a = b;
CHECK(a->x == 17);
CHECK(static_rcp_cast<B>(a)->y == 21);
CHECK(rcp<A>(b)->x == 17);
CHECK(a->debugging_refcnt() == 2);
CHECK(b->debugging_refcnt() == 2);
CHECK(static_rcp_cast<B>(std::move(a))->y == 21);
CHECK(a == nullptr);
CHECK(b->debugging_refcnt() == 1);
a = ref_rcp(b.get());
CHECK(b == a);
CHECK(a->debugging_refcnt() == 2);
CHECK(a->x == 17);
CHECK(static_rcp_cast<B>(a)->y == 21);
}