diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
index 937b8d4666..b751d4e25e 100644
--- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
+++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
@@ -1087,6 +1087,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
@@ -3796,6 +3797,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
index 2367664566..afd8bfb55a 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
@@ -3936,6 +3936,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
index 14322a89d1..20f254677e 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
@@ -6027,6 +6027,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
index 9bf02fc616..c4ad5a6cba 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
@@ -3936,6 +3936,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
index 10caa2f8a0..2763180c89 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
@@ -6027,6 +6027,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
index c2acc7913b..e3103684f4 100644
--- a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj
@@ -3936,6 +3936,7 @@
+
diff --git a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
index 1b00ec7111..fc7717f72c 100644
--- a/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2026/DemoRunner_App.vcxproj.filters
@@ -6027,6 +6027,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
index b34ce84d0d..644f9e981c 100644
--- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
@@ -946,6 +946,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
@@ -3269,6 +3270,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
index 3b5a363af2..c811ad790d 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
@@ -3402,6 +3402,7 @@
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
index 0b5c0a3dea..b1433ce8dc 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
@@ -5145,6 +5145,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
index 1582c2131b..14d4ced2dd 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj
@@ -3402,6 +3402,7 @@
+
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
index 1c54f49b16..6e58f82d2b 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2026/AudioPerformanceTest_App.vcxproj.filters
@@ -5145,6 +5145,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
index d6e3fc6e90..302b0d8142 100644
--- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
@@ -979,6 +979,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
@@ -3455,6 +3456,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
index 4fdd9e9560..5a15706247 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
@@ -3582,6 +3582,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
index 7505852b53..f38160f010 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
@@ -5421,6 +5421,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
index 5de905e745..ee8560fb32 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
@@ -3582,6 +3582,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
index 94beb845d2..720649761c 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
@@ -5421,6 +5421,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
index ddc3656c20..6aa4cb76a8 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj
@@ -3582,6 +3582,7 @@
+
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
index b6021f400e..602edde204 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2026/AudioPluginHost_App.vcxproj.filters
@@ -5421,6 +5421,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
index a38daaa9e9..a94438adbe 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
@@ -539,6 +539,7 @@
+
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
index 3e1cc4b4cd..7f6207fd99 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
@@ -549,6 +549,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj
index cb74101ff4..099a23da23 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj
+++ b/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj
@@ -539,6 +539,7 @@
+
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj.filters
index f759fcaad7..45d83c817f 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj.filters
+++ b/extras/BinaryBuilder/Builds/VisualStudio2026/BinaryBuilder_ConsoleApp.vcxproj.filters
@@ -549,6 +549,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
index fba84bd41f..7673020c2f 100644
--- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
+++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
@@ -950,6 +950,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
@@ -3353,6 +3354,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/containers/juce_Variant.cpp"
"../../../../../modules/juce_core/containers/juce_Variant.h"
"../../../../../modules/juce_core/detail/juce_CallbackListenerList.h"
+ "../../../../../modules/juce_core/detail/juce_IncrementRef.h"
"../../../../../modules/juce_core/detail/juce_LruCache.h"
"../../../../../modules/juce_core/detail/juce_NativeFileHandle.h"
"../../../../../modules/juce_core/files/juce_AndroidDocument.h"
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
index 1f16438a7c..232c6a5489 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
@@ -3493,6 +3493,7 @@
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
index 7fbbafc10e..5553422b6a 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
@@ -5286,6 +5286,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
index 80f3ad4779..589fa7c518 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj
@@ -3493,6 +3493,7 @@
+
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
index 4ca7edb6f7..9b7d2931b2 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2026/NetworkGraphicsDemo_App.vcxproj.filters
@@ -5286,6 +5286,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
index 1d899471c4..b6a3221ab1 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
@@ -2115,6 +2115,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
index 64123596c4..4b311d130f 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
@@ -2775,6 +2775,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
index b03b09c018..b50e94eb54 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
@@ -2115,6 +2115,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
index fa79989612..0caa276ffe 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
@@ -2775,6 +2775,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
index 86bac67c22..a0f5243094 100644
--- a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj
@@ -2115,6 +2115,7 @@
+
diff --git a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
index 69071f2a82..0f80bca7f4 100644
--- a/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2026/Projucer_App.vcxproj.filters
@@ -2775,6 +2775,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
index 783fde1c97..e22843e0f2 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
@@ -3694,6 +3694,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
index 3030501851..fbc065774c 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -5580,6 +5580,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
index 209ecd8ecc..a1a7fa8c30 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
@@ -3694,6 +3694,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
index 99bc61657a..df3fddc0e1 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -5580,6 +5580,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
index c707f7a095..12a0fb1afa 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj
@@ -3694,6 +3694,7 @@
+
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
index 4b22d8c130..1c172f1a9a 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2026/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -5580,6 +5580,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
index 7f3cc0cc87..1b8144ec2b 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj
@@ -3469,6 +3469,7 @@
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
index 7fb63390be..898b9c0e8b 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters
@@ -5253,6 +5253,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
index d13b255e09..a27dff9f37 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj
@@ -3469,6 +3469,7 @@
+
diff --git a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
index 6fc1e970f7..3aa4d1e3c6 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2026/WindowsDLL_DynamicLibrary.vcxproj.filters
@@ -5253,6 +5253,9 @@
JUCE Modules\juce_core\detail
+
+ JUCE Modules\juce_core\detail
+
JUCE Modules\juce_core\detail
diff --git a/modules/juce_audio_devices/native/juce_WASAPI_windows.cpp b/modules/juce_audio_devices/native/juce_WASAPI_windows.cpp
index 3c815cbc04..34eb2e2e1a 100644
--- a/modules/juce_audio_devices/native/juce_WASAPI_windows.cpp
+++ b/modules/juce_audio_devices/native/juce_WASAPI_windows.cpp
@@ -606,7 +606,7 @@ private:
if (audioSessionControl == nullptr)
return;
- sessionEventCallback = becomeComSmartPtrOwner (new SessionEventCallback (*this));
+ sessionEventCallback = ComSmartPtr { new SessionEventCallback (*this), IncrementRef::no };
audioSessionControl->RegisterAudioSessionNotification (sessionEventCallback);
}
@@ -1897,7 +1897,7 @@ private:
if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator))))
return {};
- notifyClient = becomeComSmartPtrOwner (new ChangeNotificationClient (this));
+ notifyClient = ComSmartPtr (new ChangeNotificationClient (this), IncrementRef::no);
enumerator->RegisterEndpointNotificationCallback (notifyClient);
}
diff --git a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp
index 8a1c162d53..13db4e3f83 100644
--- a/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp
+++ b/modules/juce_audio_formats/codecs/juce_WindowsMediaAudioFormat.cpp
@@ -153,7 +153,10 @@ public:
HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress());
if (SUCCEEDED (hr))
- hr = wmSyncReader->OpenStream (becomeComSmartPtrOwner (new JuceIStream (*input)));
+ {
+ hr = wmSyncReader->OpenStream (ComSmartPtr { new JuceIStream (*input),
+ IncrementRef::no });
+ }
if (SUCCEEDED (hr))
{
diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3ManifestHelper.cpp b/modules/juce_audio_plugin_client/VST3/juce_VST3ManifestHelper.cpp
index d1ad7087c8..07403ef992 100644
--- a/modules/juce_audio_plugin_client/VST3/juce_VST3ManifestHelper.cpp
+++ b/modules/juce_audio_plugin_client/VST3/juce_VST3ManifestHelper.cpp
@@ -115,6 +115,7 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#include "JucePluginDefines.h"
#endif
+#include
#include
#include
#include
diff --git a/modules/juce_audio_plugin_client/VST3/juce_VST3ModuleInfo.h b/modules/juce_audio_plugin_client/VST3/juce_VST3ModuleInfo.h
index 814788dbad..231a9f4416 100644
--- a/modules/juce_audio_plugin_client/VST3/juce_VST3ModuleInfo.h
+++ b/modules/juce_audio_plugin_client/VST3/juce_VST3ModuleInfo.h
@@ -241,7 +241,7 @@ public:
{
if (doUIDsMatch (entry.infoW.cid, cid))
{
- if (auto instance = becomeVSTComSmartPtrOwner (createInstance (entry)))
+ if (VSTComSmartPtr instance { createInstance (entry), IncrementRef::no })
{
if (instance->queryInterface (iidToQuery, obj) == Steinberg::kResultOk)
return Steinberg::kResultOk;
diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp
index 173a2c7e6b..6301bec135 100644
--- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp
+++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp
@@ -1231,7 +1231,7 @@ public:
void setAudioProcessor (JuceAudioProcessor* audioProc)
{
if (audioProcessor.get() != audioProc)
- installAudioProcessor (addVSTComSmartPtrOwner (audioProc));
+ installAudioProcessor ({ audioProc, IncrementRef::yes });
}
tresult PLUGIN_API connect (IConnectionPoint* other) override
@@ -1794,7 +1794,7 @@ private:
{
jassert (hostContext != nullptr);
- if (auto message = becomeVSTComSmartPtrOwner (allocateMessage()))
+ if (VSTComSmartPtr message { allocateMessage(), IncrementRef::no })
{
message->setMessageID (idTag);
message->getAttributes()->setInt (idTag, value);
@@ -1912,7 +1912,7 @@ private:
return {};
const auto idToUse = parameter != nullptr ? processor.getVSTParamIDForIndex (parameter->getParameterIndex()) : 0;
- const auto menu = becomeVSTComSmartPtrOwner (handler->createContextMenu (view, &idToUse));
+ VSTComSmartPtr menu { handler->createContextMenu (view, &idToUse), IncrementRef::no };
return std::make_unique (editor, menu);
}
@@ -1932,7 +1932,7 @@ private:
public:
JuceVST3Editor (JuceVST3EditController& ec, JuceAudioProcessor& p)
: EditorView (&ec, nullptr),
- owner (addVSTComSmartPtrOwner (&ec)),
+ owner (&ec, IncrementRef::yes),
pluginInstance (*p.get())
{
createContentWrapperComponentIfNeeded();
@@ -2689,7 +2689,7 @@ public:
// and not AudioChannelSet::discreteChannels (2) etc.
jassert (checkBusFormatsAreNotDiscrete());
- comPluginInstance = addVSTComSmartPtrOwner (new JuceAudioProcessor (pluginInstance));
+ comPluginInstance = VSTComSmartPtr (new JuceAudioProcessor (pluginInstance), IncrementRef::yes);
zerostruct (processContext);
@@ -2780,7 +2780,8 @@ public:
if (message->getAttributes()->getInt ("JuceVST3EditController", value) == kResultTrue)
{
- juceVST3EditController = addVSTComSmartPtrOwner ((JuceVST3EditController*) (pointer_sized_int) value);
+ juceVST3EditController = VSTComSmartPtr ((JuceVST3EditController*) (pointer_sized_int) value,
+ IncrementRef::yes);
if (juceVST3EditController != nullptr)
juceVST3EditController->setAudioProcessor (comPluginInstance.get());
diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
index a417045c53..cf2ca496e3 100644
--- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
+++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
@@ -76,7 +76,7 @@ private:
ItemAndTarget newItem;
newItem.item = item;
- newItem.target = addVSTComSmartPtrOwner (target);
+ newItem.target = VSTComSmartPtr (target, IncrementRef::yes);
items.add (newItem);
return kResultOk;
@@ -180,7 +180,9 @@ private:
// Unfortunately, Steinberg's docs explicitly say this should be modal..
handleResult (topLevelMenu->showMenu (options));
#else
- topLevelMenu->showMenuAsync (options, ModalCallbackFunction::create (menuFinished, addVSTComSmartPtrOwner (this)));
+ topLevelMenu->showMenuAsync (options,
+ ModalCallbackFunction::create (menuFinished,
+ VSTComSmartPtr (this, IncrementRef::yes)));
#endif
return kResultOk;
@@ -616,13 +618,13 @@ public:
if (getActiveEditor() != nullptr)
return true;
- auto view = becomeVSTComSmartPtrOwner (tryCreatingView());
+ VSTComSmartPtr view { tryCreatingView(), IncrementRef::no };
return view != nullptr;
}
VST3PluginWindow* createEditor() override
{
- if (auto view = becomeVSTComSmartPtrOwner (tryCreatingView()))
+ if (VSTComSmartPtr view { tryCreatingView(), IncrementRef::no })
return new VST3PluginWindow (this, view);
return nullptr;
@@ -635,7 +637,7 @@ void VST3PluginFormat::createPluginInstance (const PluginDescription& descriptio
PluginCreationCallback callback)
{
createVst3InstanceImpl (*this,
- becomeVSTComSmartPtrOwner (new VST3HostContextWithContextMenu),
+ { new VST3HostContextWithContextMenu, IncrementRef::no },
description,
callback);
}
diff --git a/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.cpp b/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.cpp
index a12e73a390..774b46130c 100644
--- a/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.cpp
+++ b/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.cpp
@@ -82,7 +82,7 @@ void VST3PluginFormatHeadless::findAllTypesForFile (OwnedArray (*this,
- becomeVSTComSmartPtrOwner (new VST3HostContextHeadless),
+ { new VST3HostContextHeadless(), IncrementRef::no },
description,
callback);
}
diff --git a/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h b/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h
index c8ada125a4..e9a0563d1b 100644
--- a/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h
+++ b/modules/juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h
@@ -1096,7 +1096,7 @@ struct DLLHandle
{
if (factory == nullptr)
if (auto* proc = (GetFactoryProc) getFunction (factoryFnName))
- factory = becomeVSTComSmartPtrOwner (proc());
+ factory = VSTComSmartPtr (proc(), IncrementRef::no);
// The plugin NEEDS to provide a factory to be able to be called a VST3!
// Most likely you are trying to load a 32-bit VST3 from a 64-bit host
@@ -1887,7 +1887,9 @@ class ParameterChanges final : public Vst::IParameterChanges
struct Entry
{
- explicit Entry (std::unique_ptr queue) : ptr (addVSTComSmartPtrOwner (queue.release())) {}
+ explicit Entry (std::unique_ptr queue)
+ : ptr (queue.release(), IncrementRef::yes)
+ {}
VSTComSmartPtr ptr;
Steinberg::int32 index = notInVector;
@@ -2632,7 +2634,7 @@ public:
{
if (trackInfoListener != nullptr)
{
- auto l = addVSTComSmartPtrOwner (new TrackPropertiesAttributeList (properties));
+ VSTComSmartPtr l { new TrackPropertiesAttributeList (properties), IncrementRef::yes };
trackInfoListener->setChannelContextInfos (l.get());
}
}
@@ -2886,7 +2888,7 @@ public:
MemoryBlock getStateForPresetFile() const
{
- auto memoryStream = becomeVSTComSmartPtrOwner (new MemoryStream());
+ VSTComSmartPtr memoryStream { new MemoryStream(), IncrementRef::no };
if (memoryStream == nullptr || holder->component == nullptr)
return {};
@@ -2905,7 +2907,8 @@ public:
bool setStateFromPresetFile (const MemoryBlock& rawData) const
{
auto rawDataCopy = rawData;
- auto memoryStream = becomeVSTComSmartPtrOwner (new MemoryStream (rawDataCopy.getData(), (int) rawDataCopy.getSize()));
+ VSTComSmartPtr memoryStream { new MemoryStream (rawDataCopy.getData(), (int) rawDataCopy.getSize()),
+ IncrementRef::no };
if (memoryStream == nullptr || holder->component == nullptr)
return false;
@@ -3042,7 +3045,7 @@ private:
if (mem.fromBase64Encoding (state->getAllSubText()))
{
- auto stream = becomeVSTComSmartPtrOwner (new MemoryStream());
+ VSTComSmartPtr stream { new MemoryStream(), IncrementRef::no };
stream->setSize ((TSize) mem.getSize());
mem.copyTo (stream->getData(), 0, mem.getSize());
return stream;
@@ -3053,10 +3056,20 @@ private:
}
CachedParamValues cachedParamValues;
- VSTComSmartPtr> inputParameterChanges = addVSTComSmartPtrOwner (new ParameterChanges);
- VSTComSmartPtr> outputParameterChanges = addVSTComSmartPtrOwner (new ParameterChanges);
- VSTComSmartPtr midiInputs = addVSTComSmartPtrOwner (new MidiEventList);
- VSTComSmartPtr midiOutputs = addVSTComSmartPtrOwner (new MidiEventList);
+ VSTComSmartPtr> inputParameterChanges
+ {
+ new ParameterChanges,
+ IncrementRef::yes
+ };
+
+ VSTComSmartPtr> outputParameterChanges
+ {
+ new ParameterChanges,
+ IncrementRef::yes
+ };
+
+ VSTComSmartPtr midiInputs { new MidiEventList, IncrementRef::yes };
+ VSTComSmartPtr midiOutputs { new MidiEventList, IncrementRef::yes };
Vst::ProcessContext timingInfo; //< Only use this in processBlock()!
bool isControllerInitialised = false, isActive = false, lastProcessBlockCallWasBypass = false;
const bool hasMidiInput = getNumSingleDirectionBusesFor (holder->component.get(), MediaKind::event, Direction::input) > 0,
diff --git a/modules/juce_audio_processors_headless/format_types/juce_VST3Utilities.h b/modules/juce_audio_processors_headless/format_types/juce_VST3Utilities.h
index a621ea89df..f23bc2b716 100644
--- a/modules/juce_audio_processors_headless/format_types/juce_VST3Utilities.h
+++ b/modules/juce_audio_processors_headless/format_types/juce_VST3Utilities.h
@@ -173,8 +173,15 @@ public:
source->release();
}
+ VSTComSmartPtr (ObjectType* object, IncrementRef incrementRefCount) noexcept
+ : source (object)
+ {
+ if (source != nullptr && incrementRefCount == IncrementRef::yes)
+ source->addRef();
+ }
+
VSTComSmartPtr (const VSTComSmartPtr& other) noexcept
- : VSTComSmartPtr (other.get(), true) {}
+ : VSTComSmartPtr (other.get(), IncrementRef::yes) {}
template , int> = 0>
VSTComSmartPtr (const VSTComSmartPtr& other) noexcept
@@ -219,43 +226,10 @@ public:
return factory->createInstance (uuid, ObjectType::iid, (void**) &source) == Steinberg::kResultOk;
}
- /** Increments refcount. */
- static auto addOwner (ObjectType* t)
- {
- return VSTComSmartPtr (t, true);
- }
-
- /** Does not initially increment refcount; assumes t has a positive refcount. */
- static auto becomeOwner (ObjectType* t)
- {
- return VSTComSmartPtr (t, false);
- }
-
private:
- VSTComSmartPtr (ObjectType* object, bool autoAddRef) noexcept
- : source (object)
- {
- if (source != nullptr && autoAddRef)
- source->addRef();
- }
-
ObjectType* source = nullptr;
};
-/** Increments refcount. */
-template
-auto addVSTComSmartPtrOwner (ObjectType* t)
-{
- return VSTComSmartPtr::addOwner (t);
-}
-
-/** Does not initially increment refcount; assumes t has a positive refcount. */
-template
-auto becomeVSTComSmartPtrOwner (ObjectType* t)
-{
- return VSTComSmartPtr::becomeOwner (t);
-}
-
// NOLINTEND(clang-analyzer-cplusplus.NewDelete)
JUCE_END_NO_SANITIZE
diff --git a/modules/juce_core/detail/juce_IncrementRef.h b/modules/juce_core/detail/juce_IncrementRef.h
new file mode 100644
index 0000000000..29e71bdbdc
--- /dev/null
+++ b/modules/juce_core/detail/juce_IncrementRef.h
@@ -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
diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h
index 5618a14fa8..d0e541625d 100644
--- a/modules/juce_core/juce_core.h
+++ b/modules/juce_core/juce_core.h
@@ -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"
diff --git a/modules/juce_core/native/juce_ComSmartPtr_windows.h b/modules/juce_core/native/juce_ComSmartPtr_windows.h
index 68eb626ce3..c717dd4021 100644
--- a/modules/juce_core/native/juce_ComSmartPtr_windows.h
+++ b/modules/juce_core/native/juce_ComSmartPtr_windows.h
@@ -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
- ComSmartPtr (const ComSmartPtr& other) : ComSmartPtr (other, true) {}
- ComSmartPtr (const ComSmartPtr& other) : ComSmartPtr (other, true) {}
+ ComSmartPtr (const ComSmartPtr& 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
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
-auto addComSmartPtrOwner (ObjectType* t)
-{
- return ComSmartPtr::addOwner (t);
-}
-
-/** Does not initially increment refcount; assumes t has a positive refcount. */
-template
-auto becomeComSmartPtrOwner (ObjectType* t)
-{
- return ComSmartPtr::becomeOwner (t);
-}
-
//==============================================================================
template
class ComBaseClassHelperBase : public First, public ComClasses...
diff --git a/modules/juce_core/native/juce_JNIHelpers_android.h b/modules/juce_core/native/juce_JNIHelpers_android.h
index e19d8b7280..dbb36ab45c 100644
--- a/modules/juce_core/native/juce_JNIHelpers_android.h
+++ b/modules/juce_core/native/juce_JNIHelpers_android.h
@@ -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
-auto addLocalRefOwner (JavaType t)
-{
- return LocalRef::addOwner (t);
-}
-
-/* Wraps a local reference and destroys it when it goes out of scope. */
-template
-auto becomeLocalRefOwner (JavaType t)
-{
- return LocalRef::becomeOwner (t);
-}
-
//==============================================================================
template
class GlobalRefImpl
diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp
index 1a6cba8a01..915e6ebba6 100644
--- a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp
+++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp
@@ -216,8 +216,8 @@ private:
explicit OwningLayer (const D2D1_LAYER_PARAMETERS1& p) : params (p) {}
D2D1_LAYER_PARAMETERS1 params;
- ComSmartPtr geometry = params.geometricMask != nullptr ? addComSmartPtrOwner (params.geometricMask) : nullptr;
- ComSmartPtr brush = params.opacityBrush != nullptr ? addComSmartPtrOwner (params.opacityBrush) : nullptr;
+ ComSmartPtr geometry { params.geometricMask, IncrementRef::yes };
+ ComSmartPtr brush { params.opacityBrush, IncrementRef::yes };
};
struct Layer
diff --git a/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp b/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp
index 091c0ae409..5f3f60b50f 100644
--- a/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp
+++ b/modules/juce_graphics/native/juce_DirectWriteTypeface_windows.cpp
@@ -150,7 +150,8 @@ public:
if (FAILED (factory->GetSystemFontFallback (fallback.resetAndGetPointerAddress())) || fallback == nullptr)
return {};
- auto analysisSource = becomeComSmartPtrOwner (new AnalysisSource (c, language));
+ ComSmartPtr analysisSource { new AnalysisSource (c, language), IncrementRef::no };
+
const auto originalName = getLocalisedFamilyName (*dwFont);
const auto mapped = factories->getFonts().mapCharacters (fallback,
diff --git a/modules/juce_graphics/native/juce_DirectX_windows.cpp b/modules/juce_graphics/native/juce_DirectX_windows.cpp
index e8f507947f..09f02ed4e4 100644
--- a/modules/juce_graphics/native/juce_DirectX_windows.cpp
+++ b/modules/juce_graphics/native/juce_DirectX_windows.cpp
@@ -1067,7 +1067,8 @@ DirectWriteCustomFontCollectionLoader::~DirectWriteCustomFontCollectionLoader()
Uuid DirectWriteCustomFontCollectionLoader::addRawFontData (Span blob)
{
- const auto loader = becomeComSmartPtrOwner (new MemoryFontFileLoader { { blob.data(), blob.size() } });
+ ComSmartPtr loader { new MemoryFontFileLoader { { blob.data(), blob.size() } },
+ IncrementRef::no };
factory.RegisterFontFileLoader (loader);
@@ -1148,7 +1149,9 @@ Direct2DFactories::Direct2DFactories()
}) },
collectionLoader { std::invoke ([&]() -> ComSmartPtr
{
- auto result = becomeComSmartPtrOwner (new DirectWriteCustomFontCollectionLoader { *directWriteFactory });
+ ComSmartPtr result { new DirectWriteCustomFontCollectionLoader { *directWriteFactory },
+ IncrementRef::no };
+
directWriteFactory->RegisterFontCollectionLoader (result);
return result;
diff --git a/modules/juce_gui_basics/native/accessibility/juce_Accessibility_windows.cpp b/modules/juce_gui_basics/native/accessibility/juce_Accessibility_windows.cpp
index 9fa451fb4e..6a385c2e74 100644
--- a/modules/juce_gui_basics/native/accessibility/juce_Accessibility_windows.cpp
+++ b/modules/juce_gui_basics/native/accessibility/juce_Accessibility_windows.cpp
@@ -122,7 +122,7 @@ class AccessibilityHandler::AccessibilityNativeImpl
{
public:
explicit AccessibilityNativeImpl (AccessibilityHandler& owner)
- : accessibilityElement (becomeComSmartPtrOwner (new AccessibilityNativeHandle (owner)))
+ : accessibilityElement (new AccessibilityNativeHandle (owner), IncrementRef::no)
{
++providerCount;
}
diff --git a/modules/juce_gui_basics/native/accessibility/juce_UIAProviderBase_windows.h b/modules/juce_gui_basics/native/accessibility/juce_UIAProviderBase_windows.h
index 91fd086b00..77c37c2436 100644
--- a/modules/juce_gui_basics/native/accessibility/juce_UIAProviderBase_windows.h
+++ b/modules/juce_gui_basics/native/accessibility/juce_UIAProviderBase_windows.h
@@ -40,7 +40,7 @@ class UIAProviderBase
{
public:
explicit UIAProviderBase (AccessibilityNativeHandle* nativeHandleIn)
- : nativeHandle (addComSmartPtrOwner (nativeHandleIn))
+ : nativeHandle (nativeHandleIn, IncrementRef::yes)
{
}
diff --git a/modules/juce_gui_basics/native/accessibility/juce_UIATextProvider_windows.h b/modules/juce_gui_basics/native/accessibility/juce_UIATextProvider_windows.h
index 5bb60afc68..bffd595714 100644
--- a/modules/juce_gui_basics/native/accessibility/juce_UIATextProvider_windows.h
+++ b/modules/juce_gui_basics/native/accessibility/juce_UIATextProvider_windows.h
@@ -194,7 +194,7 @@ private:
public:
UIATextRangeProvider (UIATextProvider& textProvider, Range range)
: UIAProviderBase (textProvider.getHandler().getNativeImplementation()),
- owner (addComSmartPtrOwner (&textProvider)),
+ owner (&textProvider, IncrementRef::yes),
selectionRange (range)
{
}
diff --git a/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp b/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp
index 4d7cbb15a9..f7796bcae3 100644
--- a/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp
+++ b/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp
@@ -357,8 +357,8 @@ public:
static jobjectArray JNICALL contentSharerGetStreamTypes (JNIEnv*, jobject /*contentProvider*/, jobject uri, jstring mimeTypeFilter)
{
- return getInstance().getStreamTypes (addLocalRefOwner (uri),
- addLocalRefOwner (mimeTypeFilter));
+ return getInstance().getStreamTypes (LocalRef (uri, IncrementRef::yes),
+ LocalRef (mimeTypeFilter, IncrementRef::yes));
}
private:
diff --git a/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp b/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp
index 36e7e2b2c2..8c12a16dc3 100644
--- a/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp
+++ b/modules/juce_gui_basics/native/juce_FileChooser_windows.cpp
@@ -296,7 +296,7 @@ private:
{
HWND hwnd = nullptr;
- if (auto window = addComSmartPtrOwner (d).getInterface())
+ if (auto window = ComSmartPtr (d, IncrementRef::yes).getInterface())
window->GetWindow (&hwnd);
ScopedLock lock (owner.deletingDialog);
diff --git a/modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp b/modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp
index 71b917fd8a..e687e7ef58 100644
--- a/modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp
+++ b/modules/juce_gui_extra/native/juce_ActiveXComponent_windows.cpp
@@ -75,7 +75,6 @@ namespace ActiveXHelpers
JUCE_COMRESULT GetBorder (LPRECT) override { return E_NOTIMPL; }
JUCE_COMRESULT RequestBorderSpace (LPCBORDERWIDTHS) override { return E_NOTIMPL; }
JUCE_COMRESULT SetBorderSpace (LPCBORDERWIDTHS) override { return E_NOTIMPL; }
- JUCE_COMRESULT SetActiveObject (IOleInPlaceActiveObject* a, LPCOLESTR) override { activeObject = addComSmartPtrOwner (a); return S_OK; }
JUCE_COMRESULT InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) override { return E_NOTIMPL; }
JUCE_COMRESULT SetMenu (HMENU, HOLEMENU, HWND) override { return S_OK; }
JUCE_COMRESULT RemoveMenus (HMENU) override { return E_NOTIMPL; }
@@ -83,6 +82,12 @@ namespace ActiveXHelpers
JUCE_COMRESULT EnableModeless (BOOL) override { return S_OK; }
JUCE_COMRESULT TranslateAccelerator (LPMSG, WORD) override { return E_NOTIMPL; }
+ JUCE_COMRESULT SetActiveObject (IOleInPlaceActiveObject* a, LPCOLESTR) override
+ {
+ activeObject = ComSmartPtr (a, IncrementRef::yes);
+ return S_OK;
+ }
+
HRESULT OfferKeyTranslation (LPMSG lpmsg)
{
if (activeObject != nullptr)
diff --git a/modules/juce_gui_extra/native/juce_WebBrowserComponent_windows.cpp b/modules/juce_gui_extra/native/juce_WebBrowserComponent_windows.cpp
index ddd734329b..b08e1c4c94 100644
--- a/modules/juce_gui_extra/native/juce_WebBrowserComponent_windows.cpp
+++ b/modules/juce_gui_extra/native/juce_WebBrowserComponent_windows.cpp
@@ -671,7 +671,7 @@ public:
Callback (
[&result] (HRESULT, ICoreWebView2Environment* env) -> HRESULT
{
- result.environment = addComSmartPtrOwner (env);
+ result.environment = ComSmartPtr (env, IncrementRef::yes);
return S_OK;
}).Get());
@@ -857,8 +857,10 @@ private:
{
method = "POST";
- auto content = becomeComSmartPtrOwner (SHCreateMemStream ((BYTE*) urlRequest.postData.getData(),
- (UINT) urlRequest.postData.getSize()));
+ auto content = ComSmartPtr (SHCreateMemStream ((BYTE*) urlRequest.postData.getData(),
+ (UINT) urlRequest.postData.getSize()),
+ IncrementRef::no);
+
request->put_Content (content);
}
@@ -884,8 +886,9 @@ private:
{
if (auto responseData = owner.impl->handleResourceRequest (resourceRequestUri))
{
- auto stream = becomeComSmartPtrOwner (SHCreateMemStream ((BYTE*) responseData->data.data(),
- (UINT) responseData->data.size()));
+ ComSmartPtr stream { SHCreateMemStream ((BYTE*) responseData->data.data(),
+ (UINT) responseData->data.size()),
+ IncrementRef::no };
StringArray headers { "Content-Type: " + responseData->mimeType };
@@ -1063,7 +1066,7 @@ private:
if (controller != nullptr)
{
- weakThis->webViewController = addComSmartPtrOwner (controller);
+ weakThis->webViewController = ComSmartPtr (controller, IncrementRef::yes);
controller->get_CoreWebView2 (weakThis->webView.resetAndGetPointerAddress());
auto allUserScripts = weakThis->userScripts;
diff --git a/modules/juce_video/native/juce_CameraDevice_windows.h b/modules/juce_video/native/juce_CameraDevice_windows.h
index a8e7ab2bb0..b649e595cc 100644
--- a/modules/juce_video/native/juce_CameraDevice_windows.h
+++ b/modules/juce_video/native/juce_CameraDevice_windows.h
@@ -134,7 +134,7 @@ struct CameraDevice::Pimpl : public ChangeBroadcaster
sampleGrabber->SetMediaType (&mt);
}
- callback = becomeComSmartPtrOwner (new GrabberCallback (*this));
+ callback = ComSmartPtr (new GrabberCallback (*this), IncrementRef::no);
hr = sampleGrabber->SetCallback (callback, 1);
hr = graphBuilder->AddFilter (sampleGrabberBase, _T ("Sample Grabber"));