From 8685605821862964f32462b9df1cb2981779a6cc Mon Sep 17 00:00:00 2001 From: kunitoki Date: Sun, 2 Apr 2023 22:17:15 +0200 Subject: [PATCH 1/3] Move juce RefcountedObject to the private tests --- Manual.md | 34 ++++--------------- .../Source}/RefCountedObject.h | 5 +-- Tests/Source/RefCountedPtrTests.cpp | 14 ++++---- 3 files changed, 14 insertions(+), 39 deletions(-) rename {Source/LuaBridge => Tests/Source}/RefCountedObject.h (99%) diff --git a/Manual.md b/Manual.md index 68fd5927..5f53f24e 100644 --- a/Manual.md +++ b/Manual.md @@ -1167,29 +1167,7 @@ When a pointer or pointer to const is passed to Lua and the pointer is null (zer LuaBridge supports a _shared lifetime_ model: dynamically allocated and reference counted objects whose ownership is shared by both Lua and C++. The object remains in existence until there are no remaining C++ or Lua references, and Lua performs its usual garbage collection cycle. A container is recognized by a specialization of the `ContainerTraits` template class. LuaBridge will automatically recognize when a data type is a container when the corresponding specialization is present. Two styles of containers come with LuaBridge, including the necessary specializations. -### 3.4.1 - Class RefCountedObjectPtr - -This is an intrusive style container. Your existing class declaration must be changed to be also derived from `RefCountedObject`. Given `class T`, derived from `RefCountedObject`, the container `RefCountedObjectPtr ` may be used. In order for reference counts to be maintained properly, all C++ code must store a container instead of the pointer. This is similar in style to `std::shared_ptr` although there are slight differences. For example: - -```cpp -// A is reference counted. -struct A : public luabridge::RefCountedObject -{ - void foo () { } -}; - -struct B -{ - RefCountedObjectPtr a; // holds a reference to A -}; - -void bar (luabridge::RefCountedObjectPtr a) -{ - a->foo (); -} -``` - -### 3.4.2 - User-defined Containers +### 3.4.1 - User-defined Containers If you have your own container, you must provide a specialization of `ContainerTraits` in the `luabridge` namespace for your type before it will be recognized by LuaBridge (or else the code will not compile): @@ -1217,14 +1195,14 @@ struct ContainerTraits> Containers must be safely constructible from raw pointers to objects that are already referenced by other instances of the container (such as is the case for the provided containers or for example `boost::intrusive_ptr` but not `std::shared_ptr` or `boost::shared_ptr`). -### 3.4.3 - shared_ptr As Container +### 3.4.2 - shared_ptr As Container Standard containers like `std::shared_ptr` or `boost::shared_ptr` will work in LuaBridge3, but they require special care. This is because of type erasure; when the object goes from C++ to Lua and back to C++, constructing a new shared_ptr from the raw pointer will create another reference count and result in undefined behavior, unless it could intrusively reconstruct the container from a raw pointer. To overcome this issue classes that should be managed by `shared_ptr` have to provide a way to correctly reconstruct a `shared_ptr` which can be done only if type hold it is deriving publicly from `std::enable_shared_from_this` or `boost::enable_shared_from_this`. No additional specialization of traits is needed in this case. ```cpp -struct A : public std::enable_shared_from_this +struct A : public std::enable_shared_from_this { A () { } A (int) { } @@ -1255,12 +1233,12 @@ anotherA2 = A (1) anotherA2.foo () ``` -### 3.4.4 - Container Constructors +### 3.4.3 - Container Constructors When a constructor is registered for a class, there is an additional optional second template parameter describing the type of container to use. If this parameter is specified, calls to the constructor will create the object dynamically, via operator new, and place it a container of that type. The container must have been previously specialized in `ContainerTraits`, or else a compile error will result. This code will register two objects, each using a constructor that creates an object with Lua lifetime using the specified container: ```cpp -class C : public luabridge::RefCountedObject +class C : public std::enable_shared_from_this { C () { } C (int) { } @@ -1269,7 +1247,7 @@ class C : public luabridge::RefCountedObject luabridge::getGlobalNamespace (L) .beginNamespace ("test") .beginClass ("C") - .addConstructorFrom, void(), void(int)> () + .addConstructorFrom, void(), void(int)> () .endClass () .endNamespace () ``` diff --git a/Source/LuaBridge/RefCountedObject.h b/Tests/Source/RefCountedObject.h similarity index 99% rename from Source/LuaBridge/RefCountedObject.h rename to Tests/Source/RefCountedObject.h index 4ff6786e..4c07c093 100644 --- a/Source/LuaBridge/RefCountedObject.h +++ b/Tests/Source/RefCountedObject.h @@ -39,13 +39,10 @@ #pragma once -#include "detail/Config.h" -#include "detail/TypeTraits.h" +#include "TestBase.h" #include -namespace luabridge { - //============================================================================== /** Adds reference-counting to an object. diff --git a/Tests/Source/RefCountedPtrTests.cpp b/Tests/Source/RefCountedPtrTests.cpp index 57094fbe..c087d8bf 100644 --- a/Tests/Source/RefCountedPtrTests.cpp +++ b/Tests/Source/RefCountedPtrTests.cpp @@ -4,7 +4,7 @@ #include "TestBase.h" -#include "LuaBridge/RefCountedObject.h" +#include "RefCountedObject.h" struct RefCountedPtrTests : TestBase { @@ -18,7 +18,7 @@ struct RefCountedPtrTests : TestBase namespace { -struct RefCounted : luabridge::RefCountedObject +struct RefCounted : RefCountedObject { explicit RefCounted(bool& deleted) : deleted(deleted) { deleted = false; } @@ -29,7 +29,7 @@ struct RefCounted : luabridge::RefCountedObject bool& deleted; }; -struct RefCountedStatic : luabridge::RefCountedObject +struct RefCountedStatic : RefCountedObject { explicit RefCountedStatic() { constructed = true; } @@ -48,11 +48,11 @@ TEST_F(RefCountedPtrTests, Operators) { bool deleted1 = false; auto* raw_ptr1 = new RefCounted(deleted1); - luabridge::RefCountedObjectPtr ptr1(raw_ptr1); + RefCountedObjectPtr ptr1(raw_ptr1); bool deleted2 = false; auto* raw_ptr2 = new RefCounted(deleted2); - luabridge::RefCountedObjectPtr ptr2(raw_ptr2); + RefCountedObjectPtr ptr2(raw_ptr2); ASSERT_TRUE(raw_ptr1 == ptr1.getObject()); ASSERT_TRUE(ptr1.getObject() == raw_ptr1); @@ -67,7 +67,7 @@ TEST_F(RefCountedPtrTests, LastReferenceInLua) bool deleted = false; - luabridge::RefCountedObjectPtr object(new RefCounted(deleted)); + RefCountedObjectPtr object(new RefCounted(deleted)); luabridge::setGlobal(L, object, "object"); runLua("result = object.deleted"); @@ -95,7 +95,7 @@ TEST_F(RefCountedPtrTests, LastReferenceInCpp) bool deleted = false; - luabridge::RefCountedObjectPtr object(new RefCounted(deleted)); + RefCountedObjectPtr object(new RefCounted(deleted)); luabridge::setGlobal(L, object, "object"); runLua("result = object.deleted"); From 99da0f20b37f53e8ae9e99a2c933425e41df05e0 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Mon, 17 Apr 2023 21:05:31 +0200 Subject: [PATCH 2/3] Removed reference to an include --- Source/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ec71695c..90af3478 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -5,7 +5,6 @@ set (LUABRIDGE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/List.h ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/LuaBridge.h ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/Map.h - ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/RefCountedObject.h ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/Set.h ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/UnorderedMap.h ${CMAKE_CURRENT_SOURCE_DIR}/LuaBridge/Vector.h) From 4c295dc4371c7fcc368f6d3bf02e6bc46503014c Mon Sep 17 00:00:00 2001 From: kunitoki Date: Thu, 4 May 2023 00:04:30 +0200 Subject: [PATCH 3/3] Fix removal of RefCountedObjectPtr --- Manual.md | 7 +++---- Tests/Source/LegacyTests.cpp | 2 -- Tests/Source/RefCountedObject.h | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Manual.md b/Manual.md index a9ef1bc7..fb41fa0a 100644 --- a/Manual.md +++ b/Manual.md @@ -48,10 +48,9 @@ Contents * [3.2 - Lua Lifetime](#32---lua-lifetime) * [3.3 - Pointers, References, and Pass by Value](#33---pointers-references-and-pass-by-value) * [3.4 - Shared Lifetime](#34---shared-lifetime) - * [3.4.1 - Class RefCountedObjectPtr](#341---class-refcountedobjectptr) - * [3.4.2 - User-defined Containers](#342---user-defined-containers) - * [3.4.3 - shared_ptr As Container](#343---shared_ptr-as-container) - * [3.4.4 - Container Constructors](#344---container-constructors) + * [3.4.1 - User-defined Containers](#341---user-defined-containers) + * [3.4.2 - shared_ptr As Container](#342---shared_ptr-as-container) + * [3.4.3 - Container Constructors](#343---container-constructors) * [3.5 - Mixing Lifetimes](#35---mixing-lifetimes) * [3.6 - Convenience Functions](#36---convenience-functions) diff --git a/Tests/Source/LegacyTests.cpp b/Tests/Source/LegacyTests.cpp index ebef9c7e..582dd190 100644 --- a/Tests/Source/LegacyTests.cpp +++ b/Tests/Source/LegacyTests.cpp @@ -9,8 +9,6 @@ #include "TestBase.h" #include "LegacyTests.h" -#include "LuaBridge/RefCountedObject.h" - #include #include #include diff --git a/Tests/Source/RefCountedObject.h b/Tests/Source/RefCountedObject.h index 4c07c093..cfab32f0 100644 --- a/Tests/Source/RefCountedObject.h +++ b/Tests/Source/RefCountedObject.h @@ -352,6 +352,7 @@ bool operator!=(ReferenceCountedObjectClass* object1, } //============================================================================== +namespace luabridge { template struct ContainerTraits> @@ -363,6 +364,4 @@ struct ContainerTraits> static T* get(RefCountedObjectPtr const& c) { return c.getObject(); } }; -//============================================================================== - } // namespace luabridge