1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Smart Pointers: Add a new enum for indicating if a smart point should increment a reference count or not

This commit is contained in:
Anthony Nicholls 2025-09-22 17:34:34 +01:00 committed by Anthony Nicholls
parent 8931d45fe9
commit e68627c9ed
68 changed files with 243 additions and 160 deletions

View file

@ -0,0 +1,45 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce
{
/** @internal */
enum class IncrementRef
{
no,
yes
};
} // namespace juce

View file

@ -375,6 +375,7 @@ JUCE_END_IGNORE_WARNINGS_MSVC
#include "detail/juce_CallbackListenerList.h"
#include "detail/juce_LruCache.h"
#include "detail/juce_IncrementRef.h"
#if JUCE_CORE_INCLUDE_OBJC_HELPERS && (JUCE_MAC || JUCE_IOS)
#include "native/juce_CFHelpers_mac.h"

View file

@ -106,9 +106,16 @@ public:
ComSmartPtr() noexcept = default;
ComSmartPtr (std::nullptr_t) noexcept {}
ComSmartPtr (ComClass* object, IncrementRef incrementRef) noexcept
: p (object)
{
if (p != nullptr && incrementRef == IncrementRef::yes)
p->AddRef();
}
template <typename U>
ComSmartPtr (const ComSmartPtr<U>& other) : ComSmartPtr (other, true) {}
ComSmartPtr (const ComSmartPtr& other) : ComSmartPtr (other, true) {}
ComSmartPtr (const ComSmartPtr<U>& other) : ComSmartPtr (other, IncrementRef::yes) {}
ComSmartPtr (const ComSmartPtr& other) : ComSmartPtr (other, IncrementRef::yes) {}
~ComSmartPtr() noexcept { release(); }
@ -162,29 +169,10 @@ public:
return destObject;
}
/** Increments refcount. */
static auto addOwner (ComClass* t)
{
return ComSmartPtr (t, true);
}
/** Does not initially increment refcount; assumes t has a positive refcount. */
static auto becomeOwner (ComClass* t)
{
return ComSmartPtr (t, false);
}
private:
template <typename U>
friend class ComSmartPtr;
ComSmartPtr (ComClass* object, bool autoAddRef) noexcept
: p (object)
{
if (p != nullptr && autoAddRef)
p->AddRef();
}
void release()
{
if (auto* q = std::exchange (p, nullptr))
@ -196,20 +184,6 @@ private:
ComClass* p = nullptr;
};
/** Increments refcount. */
template <class ObjectType>
auto addComSmartPtrOwner (ObjectType* t)
{
return ComSmartPtr<ObjectType>::addOwner (t);
}
/** Does not initially increment refcount; assumes t has a positive refcount. */
template <class ObjectType>
auto becomeComSmartPtrOwner (ObjectType* t)
{
return ComSmartPtr<ObjectType>::becomeOwner (t);
}
//==============================================================================
template <class First, class... ComClasses>
class ComBaseClassHelperBase : public First, public ComClasses...

View file

@ -49,7 +49,20 @@ public:
JNI, i.e. for native function callback parameters.
*/
explicit LocalRef (JavaType o) noexcept
: LocalRef (o, false)
: LocalRef (o, IncrementRef::no)
{}
/* We cannot delete local references that were not created by JNI, e.g. references that were
created by the VM and passed into the native function.
For these references we should use createNewLocalRef = true, which will create a new
local reference that this wrapper is allowed to delete.
Doing otherwise will result in an "Attempt to remove non-JNI local reference" warning in the
VM, which could even cause crashes in future VM implementations.
*/
LocalRef (JavaType o, IncrementRef incrementRefCount) noexcept
: obj (incrementRefCount == IncrementRef::yes ? retain (o) : o)
{}
LocalRef (const LocalRef& other) noexcept : obj (retain (other.obj)) {}
@ -91,59 +104,15 @@ public:
return std::exchange (obj, nullptr);
}
/** Creates a new internal local reference. */
static auto addOwner (JavaType o)
{
return LocalRef { o, true };
}
/** Takes ownership of the passed in local reference, and deletes it when the LocalRef goes out
of scope.
*/
static auto becomeOwner (JavaType o)
{
return LocalRef { o, false };
}
private:
static JavaType retain (JavaType obj)
{
return obj == nullptr ? nullptr : (JavaType) getEnv()->NewLocalRef (obj);
}
/* We cannot delete local references that were not created by JNI, e.g. references that were
created by the VM and passed into the native function.
For these references we should use createNewLocalRef = true, which will create a new
local reference that this wrapper is allowed to delete.
Doing otherwise will result in an "Attempt to remove non-JNI local reference" warning in the
VM, which could even cause crashes in future VM implementations.
*/
LocalRef (JavaType o, bool createNewLocalRef) noexcept
: obj (createNewLocalRef ? retain (o) : o)
{}
JavaType obj = nullptr;
};
/* Creates a new local reference that shares ownership with the passed in pointer.
Can be used for wrapping function parameters that were created outside the JNI.
*/
template <class JavaType>
auto addLocalRefOwner (JavaType t)
{
return LocalRef<JavaType>::addOwner (t);
}
/* Wraps a local reference and destroys it when it goes out of scope. */
template <class JavaType>
auto becomeLocalRefOwner (JavaType t)
{
return LocalRef<JavaType>::becomeOwner (t);
}
//==============================================================================
template <typename JavaType>
class GlobalRefImpl