diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 8906e61c2a..900c73c5a3 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -1014,6 +1014,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -1112,6 +1114,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" @@ -3077,6 +3080,8 @@ set_source_files_properties( "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -3175,6 +3180,7 @@ set_source_files_properties( "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj index 453551f226..0eef468167 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj @@ -567,6 +567,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -576,7 +577,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; @@ -658,6 +659,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -666,7 +668,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index 3b82207f5f..a56f53e087 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -1310,6 +1310,9 @@ true + + true + true @@ -2764,7 +2767,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3326,6 +3331,7 @@ + @@ -3375,6 +3381,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index 9a2cae232a..c7f46a60be 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -437,6 +437,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1924,6 +1927,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5187,6 +5193,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5334,6 +5343,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index 2b01a6925e..ed44a0263b 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -1310,6 +1310,9 @@ true + + true + true @@ -2764,7 +2767,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3326,6 +3331,7 @@ + @@ -3375,6 +3381,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 99e39fe0d0..8ea21b802c 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -437,6 +437,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1924,6 +1927,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5187,6 +5193,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5334,6 +5343,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 1069b83eca..bb93ee018a 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -1310,6 +1310,9 @@ true + + true + true @@ -2764,7 +2767,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3326,6 +3331,7 @@ + @@ -3375,6 +3381,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index b9b7836ad2..922f3319b5 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -437,6 +437,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1924,6 +1927,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5187,6 +5193,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -5334,6 +5343,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj index 08087f38d8..a7bcba72d1 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -571,6 +571,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -579,7 +580,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit -weak_framework UserNotifications"; @@ -662,6 +663,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -669,7 +671,7 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit -weak_framework UserNotifications"; diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index ba48b78203..fd039e8652 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -890,6 +890,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -988,6 +990,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" @@ -2653,6 +2656,8 @@ set_source_files_properties( "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -2751,6 +2756,7 @@ set_source_files_properties( "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index e3f292c89a..b30591fbc8 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -1150,6 +1150,9 @@ true + + true + true @@ -2383,7 +2386,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -2882,6 +2887,7 @@ + @@ -2931,6 +2937,7 @@ + diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 6efb730b3a..2e0c11fcd1 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -392,6 +392,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1633,6 +1636,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4467,6 +4473,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4614,6 +4623,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 31a752e6d3..3d86aba9be 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -923,6 +923,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -1021,6 +1023,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" @@ -2839,6 +2842,8 @@ set_source_files_properties( "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -2937,6 +2942,7 @@ set_source_files_properties( "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" diff --git a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj index 64841881c2..6256cbb5b2 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj @@ -499,6 +499,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -508,7 +509,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; @@ -637,6 +638,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -645,7 +647,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index e564f441dc..7f7009fed5 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -1158,6 +1158,9 @@ true + + true + true @@ -2554,7 +2557,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3062,6 +3067,7 @@ + @@ -3111,6 +3117,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index b95133a94c..6412eaaf0e 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1708,6 +1711,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4743,6 +4749,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4890,6 +4899,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 80adb304ae..8e4d3b2c39 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -1158,6 +1158,9 @@ true + + true + true @@ -2554,7 +2557,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3062,6 +3067,7 @@ + @@ -3111,6 +3117,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 8030e0558c..fab70583a2 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1708,6 +1711,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4743,6 +4749,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4890,6 +4899,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index 365f14ec0b..a60475887e 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -1158,6 +1158,9 @@ true + + true + true @@ -2554,7 +2557,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3062,6 +3067,7 @@ + @@ -3111,6 +3117,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index d44e3c1d0e..a1354ba663 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1708,6 +1711,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4743,6 +4749,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4890,6 +4899,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj index f0cf314521..d68cccdc72 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj @@ -510,6 +510,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -518,7 +519,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit -weak_framework UserNotifications"; @@ -650,6 +651,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -657,7 +659,7 @@ INFOPLIST_FILE = Info-App.plist; INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit -weak_framework UserNotifications"; diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj index 02dc30ec5d..111da4d5a0 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj @@ -217,6 +217,9 @@ true + + true + true @@ -484,7 +487,9 @@ true - + + /bigobj %(AdditionalOptions) + @@ -522,6 +527,7 @@ + @@ -571,6 +577,7 @@ + diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters index b57c4ea2c8..89603e456a 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters @@ -38,6 +38,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -154,6 +157,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -549,6 +555,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -696,6 +705,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/Build/CMake/JUCEModuleSupport.cmake b/extras/Build/CMake/JUCEModuleSupport.cmake index f353be4e32..e18dd5e087 100644 --- a/extras/Build/CMake/JUCEModuleSupport.cmake +++ b/extras/Build/CMake/JUCEModuleSupport.cmake @@ -609,7 +609,7 @@ function(juce_add_module module_path) _juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" linuxLibs) elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")) - if(module_name STREQUAL "juce_gui_basics") + if(module_name MATCHES "juce_gui_basics|juce_audio_processors|juce_core") target_compile_options(${module_name} INTERFACE /bigobj) endif() diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 82b4f53ba4..41381d1f81 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -894,6 +894,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -992,6 +994,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" @@ -2737,6 +2740,8 @@ set_source_files_properties( "../../../../../modules/juce_core/javascript/juce_Javascript.h" "../../../../../modules/juce_core/javascript/juce_JSON.cpp" "../../../../../modules/juce_core/javascript/juce_JSON.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation.h" + "../../../../../modules/juce_core/javascript/juce_JSONSerialisation_test.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.cpp" "../../../../../modules/juce_core/logging/juce_FileLogger.h" "../../../../../modules/juce_core/logging/juce_Logger.cpp" @@ -2835,6 +2840,7 @@ set_source_files_properties( "../../../../../modules/juce_core/network/juce_URL.h" "../../../../../modules/juce_core/network/juce_WebInputStream.cpp" "../../../../../modules/juce_core/network/juce_WebInputStream.h" + "../../../../../modules/juce_core/serialisation/juce_Serialisation.h" "../../../../../modules/juce_core/streams/juce_AndroidDocumentInputSource.h" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.cpp" "../../../../../modules/juce_core/streams/juce_BufferedInputStream.h" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 1371987f31..38228cb131 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -1150,6 +1150,9 @@ true + + true + true @@ -2468,7 +2471,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -2973,6 +2978,7 @@ + @@ -3022,6 +3028,7 @@ + diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 31cd82ac04..8b36f6bdf8 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -392,6 +392,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1663,6 +1666,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4608,6 +4614,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4755,6 +4764,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj index 5cd6d923af..e5b0dc5d3f 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj @@ -353,6 +353,9 @@ true + + true + true @@ -1600,7 +1603,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -1815,6 +1820,7 @@ + @@ -1864,6 +1870,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters index 3a6e321cd4..2c6d9092d7 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters @@ -119,6 +119,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -631,6 +634,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2622,6 +2628,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2769,6 +2778,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index ecfaba5e15..3aa9a26508 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -353,6 +353,9 @@ true + + true + true @@ -1600,7 +1603,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -1815,6 +1820,7 @@ + @@ -1864,6 +1870,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index 2c138c57f9..62bf8c6eb6 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -119,6 +119,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -631,6 +634,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2622,6 +2628,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2769,6 +2778,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj index da7eb6a76b..f4bd7575a3 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj @@ -353,6 +353,9 @@ true + + true + true @@ -1600,7 +1603,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -1815,6 +1820,7 @@ + @@ -1864,6 +1870,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters index f3ebace5a6..649e69130c 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters @@ -119,6 +119,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -631,6 +634,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2622,6 +2628,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -2769,6 +2778,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index 54f91e3410..e5c9d69ca8 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -1908,7 +1908,8 @@ protected: const auto name = path.getFileNameWithoutExtension(); return name.equalsIgnoreCase ("include_juce_gui_basics") - || name.equalsIgnoreCase ("include_juce_audio_processors"); + || name.equalsIgnoreCase ("include_juce_audio_processors") + || name.equalsIgnoreCase ("include_juce_core"); } StringArray getModuleLibs() const diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj index 12fdc68f3c..2207f3ebdb 100644 --- a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj @@ -459,6 +459,7 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", @@ -466,7 +467,7 @@ INSTALL_PATH = "/usr/bin"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; @@ -590,13 +591,14 @@ "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK", "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK", + "$(HOME)/Developer/VSTSDK", "$(SRCROOT)/../../JuceLibraryCode", "$(SRCROOT)/../../../../modules", "$(inherited)", ); INSTALL_PATH = "/usr/bin"; MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/LV2_SDK $(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(HOME)/Developer/VSTSDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wcast-align -Wfloat-equal -Wno-ignored-qualifiers -Wsign-compare -Wsign-conversion -Wstrict-aliasing -Wswitch-enum -Wuninitialized -Wunreachable-code -Wunused-parameter -Wmissing-field-initializers -Wshadow-all -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wmissing-prototypes -Wnullable-to-nonnull-conversion -Wpedantic -Wdeprecated -Wunguarded-availability -Wunguarded-availability-new"; OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index 6a814939f1..4b1fee2c6c 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -1166,6 +1166,9 @@ true + + true + true @@ -2619,7 +2622,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3128,6 +3133,7 @@ + @@ -3177,6 +3183,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index e958b4b227..4dfd10ecb3 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1732,6 +1735,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4833,6 +4839,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4980,6 +4989,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index e611bd6ccb..e6cacf8e8b 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -1166,6 +1166,9 @@ true + + true + true @@ -2619,7 +2622,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3128,6 +3133,7 @@ + @@ -3177,6 +3183,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 93cd36c710..1cee45cd03 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1732,6 +1735,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4833,6 +4839,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4980,6 +4989,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index 44d40abc25..d98f2d81f3 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -1166,6 +1166,9 @@ true + + true + true @@ -2619,7 +2622,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -3128,6 +3133,7 @@ + @@ -3177,6 +3183,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index e608da5300..513b91f96f 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -401,6 +401,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1732,6 +1735,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4833,6 +4839,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4980,6 +4989,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj index 5219f5c8a1..e0876552a7 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj @@ -1149,6 +1149,9 @@ true + + true + true @@ -2448,7 +2451,9 @@ - + + /bigobj %(AdditionalOptions) + @@ -2949,6 +2954,7 @@ + @@ -2998,6 +3004,7 @@ + diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters index 78edeef02a..619101a3b3 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters @@ -386,6 +386,9 @@ {0F70B1A9-BB50-23F5-2AE7-F95E51A00389} + + {D4D9BC01-0DED-2577-4B99-2FF7B9C7EF8A} + {D4C8DC40-2CD2-04B6-05D0-1E7A88841390} @@ -1660,6 +1663,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4575,6 +4581,9 @@ JUCE Modules\juce_core\javascript + + JUCE Modules\juce_core\javascript + JUCE Modules\juce_core\logging @@ -4722,6 +4731,9 @@ JUCE Modules\juce_core\network + + JUCE Modules\juce_core\serialisation + JUCE Modules\juce_core\streams diff --git a/modules/juce_core/javascript/juce_JSONSerialisation.h b/modules/juce_core/javascript/juce_JSONSerialisation.h new file mode 100644 index 0000000000..8726834c34 --- /dev/null +++ b/modules/juce_core/javascript/juce_JSONSerialisation.h @@ -0,0 +1,459 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +/** + Options that control conversion from arbitrary types to juce::var. + + @see ToVar + + @tags{Core} +*/ +class ToVarOptions +{ +public: + /** By default, conversion will serialise the type using the marshallingVersion defined for + that type. Setting an explicit version allows the type to be serialised as an earlier + version. + */ + [[nodiscard]] ToVarOptions withExplicitVersion (std::optional x) const { return withMember (*this, &ToVarOptions::explicitVersion, x); } + + /** By default, conversion will include version information for any type with a non-null + marshallingVersion. Setting versionIncluded to false will cause the version info to be + omitted, which is useful in situations where the version information is not needed + (e.g. when presenting transient information to the user, rather than writing data to + disk that must be deserialised in the future). + */ + [[nodiscard]] ToVarOptions withVersionIncluded (bool x) const { return withMember (*this, &ToVarOptions::versionIncluded, x); } + + /** @see withExplicitVersion() */ + [[nodiscard]] auto getExplicitVersion() const { return explicitVersion; } + + /** @see withVersionIncluded(). */ + [[nodiscard]] auto getVersionIncluded() const { return versionIncluded; } + +private: + std::optional> explicitVersion; + bool versionIncluded = true; +}; + +/** + Allows converting an object of arbitrary type to var. + + To use this, you must first ensure that the type passed to convert is set up for serialisation. + For details of what this entails, see the docs for SerialisationTraits. + + In short, the constant 'marshallingVersion', and either the single function 'serialise()', or + the function pair 'load()' and 'save()' must be defined for the type. These may be defined + as public members of the type T itself, or as public members of juce::SerialisationTraits, + which is a specialisation of the SerialisationTraits template struct for the type T. + + @see FromVar + + @tags{Core} +*/ +class ToVar +{ +public: + using Options = ToVarOptions; + + /** Attempts to convert the argument to a var using the serialisation utilities specified for + that type. + + This will return a non-null optional if conversion succeeds, or nullopt if conversion fails. + */ + template + static std::optional convert (const T& t, const Options& options = {}) + { + return Visitor::convert (t, options); + } + +private: + class Visitor + { + public: + template + static std::optional convert (const T& t, const Options& options) + { + constexpr auto fallbackVersion = detail::ForwardingSerialisationTraits::marshallingVersion; + const auto versionToUse = options.getExplicitVersion() + .value_or (fallbackVersion); + + if (versionToUse > fallbackVersion) + { + // The requested explicit version is higher than the declared version of the type. + return std::nullopt; + } + + Visitor visitor { versionToUse, options.getVersionIncluded() }; + detail::doSave (visitor, t); + return visitor.value; + } + + std::optional getVersion() const { return version; } + + template + void operator() (Ts&&... ts) + { + (visit (std::forward (ts)), ...); + } + + private: + Visitor (const std::optional& explicitVersion, bool includeVersion) + : version (explicitVersion), + value ([&]() -> var + { + if (! (version.has_value() && includeVersion)) + return var(); + + auto obj = std::make_unique(); + obj->setProperty ("__version__", *version); + return obj.release(); + }()), + versionIncluded (includeVersion) {} + + template + void visit (const T& t) + { + if constexpr (std::is_integral_v) + { + push ((int64) t); + } + else if constexpr (std::is_floating_point_v) + { + push ((double) t); + } + else if (auto converted = convert(t)) + { + push (*converted); + } + else + { + value.reset(); + } + } + + template + void visit (const Named& named) + { + if (! value.has_value()) + return; + + if (value == var()) + value = new DynamicObject; + + auto* obj = value->getDynamicObject(); + + if (obj == nullptr) + { + // Serialisation failure! This may be caused by archiving a primitive or + // SerialisationSize, and then attempting to archive a named pair to the same + // archive instance. + // When using named pairs, *all* items serialised with a particular archiver must be + // named pairs. + jassertfalse; + + value.reset(); + return; + } + + if (! trySetProperty (*obj, named)) + value.reset(); + } + + template + void visit (const SerialisationSize&) + { + push (Array{}); + } + + void visit (const bool& t) + { + push (t); + } + + void visit (const String& t) + { + push (t); + } + + void visit (const var& t) + { + push (t); + } + + template + std::optional convert (const T& t) + { + return convert (t, Options{}.withVersionIncluded (versionIncluded)); + } + + void push (var v) + { + if (! value.has_value()) + return; + + if (*value == var()) + *value = v; + else if (auto* array = value->getArray()) + array->add (v); + else + value.reset(); + } + + template + bool trySetProperty (DynamicObject& obj, const Named& n) + { + if (const auto converted = convert (n.value)) + { + obj.setProperty (Identifier (std::string (n.name)), *converted); + return true; + } + + return false; + } + + std::optional version; + std::optional value; + bool versionIncluded = true; + }; +}; + +//============================================================================== +/** + Allows converting a var to an object of arbitrary type. + + To use this, you must first ensure that the type passed to convert is set up for serialisation. + For details of what this entails, see the docs for SerialisationTraits. + + In short, the constant 'marshallingVersion', and either the single function 'serialise()', or + the function pair 'load()' and 'save()' must be defined for the type. These may be defined + as public members of the type T itself, or as public members of juce::SerialisationTraits, + which is a specialisation of the SerialisationTraits template struct for the type T. + + @see ToVar + + @tags{Core} +*/ +class FromVar +{ +public: + /** Attempts to convert a var to an instance of type T. + + This will return a non-null optional if conversion succeeds, or nullopt if conversion fails. + */ + template + static std::optional convert (const var& v) + { + return Visitor::convert (v); + } + +private: + class Visitor + { + public: + template + static std::optional convert (const var& v) + { + const auto version = [&]() -> std::optional + { + if (auto* obj = v.getDynamicObject()) + if (obj->hasProperty ("__version__")) + return (int) obj->getProperty ("__version__"); + + return std::nullopt; + }(); + + Visitor visitor { version, v }; + T t{}; + detail::doLoad (visitor, t); + return ! visitor.failed ? std::optional (std::move (t)) + : std::nullopt; + } + + std::optional getVersion() const { return version; } + + template + void operator() (Ts&&... ts) + { + (visit (std::forward (ts)), ...); + } + + private: + Visitor (std::optional vn, const var& i) + : version (vn), input (i) {} + + template + void visit (T& t) + { + if constexpr (std::is_integral_v) + { + readPrimitive (std::in_place_type, t); + } + else if constexpr (std::is_floating_point_v) + { + readPrimitive (std::in_place_type, t); + } + else + { + auto node = getNodeToRead(); + + if (! node.has_value()) + return; + + auto converted = convert (*node); + + if (converted.has_value()) + t = *converted; + else + failed = true; + } + } + + template + void visit (const Named& named) + { + auto node = getNodeToRead(); + + if (! node.has_value()) + return; + + auto* obj = node->getDynamicObject(); + + failed = obj == nullptr || ! tryGetProperty (*obj, named); + } + + template + void visit (const SerialisationSize& t) + { + if (failed) + return; + + if (auto* array = input.getArray()) + { + t.size = static_cast (array->size()); + currentArrayIndex = 0; + } + else + { + failed = true; + } + } + + void visit (bool& t) + { + readPrimitive (std::in_place_type, t); + } + + void visit (String& t) + { + readPrimitive (std::in_place_type, t); + } + + void visit (var& t) + { + t = input; + } + + static std::optional pullTyped (std::in_place_type_t, const var& source) + { + return source.isDouble() ? std::optional ((double) source) : std::nullopt; + } + + static std::optional pullTyped (std::in_place_type_t, const var& source) + { + return source.isInt() || source.isInt64() ? std::optional ((int64) source) : std::nullopt; + } + + static std::optional pullTyped (std::in_place_type_t, const var& source) + { + return source.isBool() || source.isInt() || source.isInt64() ? std::optional ((bool) source) : std::nullopt; + } + + static std::optional pullTyped (std::in_place_type_t, const var& source) + { + return source.isString() ? std::optional (source.toString()) : std::nullopt; + } + + std::optional getNodeToRead() + { + if (failed) + return std::nullopt; + + if (currentArrayIndex == std::numeric_limits::max()) + return input; + + const auto* array = input.getArray(); + + if (array == nullptr) + return input; + + if ((int) currentArrayIndex < array->size()) + return array->getReference ((int) currentArrayIndex++); + + failed = true; + return std::nullopt; + } + + template + void readPrimitive (std::in_place_type_t tag, T& t) + { + auto node = getNodeToRead(); + + if (! node.has_value()) + return; + + auto typed = pullTyped (tag, *node); + + if (typed.has_value()) + t = static_cast (*typed); + else + failed = true; + } + + template + static bool tryGetProperty (const DynamicObject& obj, const Named& n) + { + const Identifier identifier (String (n.name.data(), n.name.size())); + + if (! obj.hasProperty (identifier)) + return false; + + const auto converted = convert (obj.getProperty (identifier)); + + if (! converted.has_value()) + return false; + + n.value = *converted; + return true; + } + + std::optional version; + var input; + size_t currentArrayIndex = std::numeric_limits::max(); + bool failed = false; + }; +}; + +} // namespace juce diff --git a/modules/juce_core/javascript/juce_JSONSerialisation_test.cpp b/modules/juce_core/javascript/juce_JSONSerialisation_test.cpp new file mode 100644 index 0000000000..780ececdb6 --- /dev/null +++ b/modules/juce_core/javascript/juce_JSONSerialisation_test.cpp @@ -0,0 +1,652 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +struct TypeWithExternalUnifiedSerialisation +{ + int a; + std::string b; + std::vector c; + std::map d; + + auto operator== (const TypeWithExternalUnifiedSerialisation& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.a, x.b, x.c, x.d); }; + return tie (*this) == tie (other); + } + + auto operator!= (const TypeWithExternalUnifiedSerialisation& other) const { return ! operator== (other); } +}; + +template <> +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = 2; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("a", t.a), + named ("b", t.b), + named ("c", t.c), + named ("d", t.d)); + } +}; + +// Now that the serialiser trait is visible, it should be detected +static_assert (detail::serialisationKind == detail::SerialisationKind::external); + +struct TypeWithInternalUnifiedSerialisation +{ + double a; + float b; + String c; + StringArray d; + + auto operator== (const TypeWithInternalUnifiedSerialisation& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.a, x.b, x.c, x.d); }; + return tie (*this) == tie (other); + } + + auto operator!= (const TypeWithInternalUnifiedSerialisation& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = 5; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("a", t.a), + named ("b", t.b), + named ("c", t.c), + named ("d", t.d)); + } +}; + +static_assert (detail::serialisationKind == detail::SerialisationKind::internal); + +struct TypeWithExternalSplitSerialisation +{ + std::optional a; + Array b; + + auto operator== (const TypeWithExternalSplitSerialisation& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.a, x.b); }; + return tie (*this) == tie (other); + } + + auto operator!= (const TypeWithExternalSplitSerialisation& other) const { return ! operator== (other); } +}; + +template <> +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = 10; + + template + static void load (Archive& archive, TypeWithExternalSplitSerialisation& t) + { + std::optional a; + Array hexStrings; + archive (named ("a", a), named ("b", hexStrings)); + + Array b; + + for (auto& i : hexStrings) + b.add (i.getHexValue32()); + + t = { a, b }; + } + + template + static void save (Archive& archive, const TypeWithExternalSplitSerialisation& t) + { + Array hexStrings; + + for (auto& i : t.b) + hexStrings.add ("0x" + String::toHexString (i)); + + archive (named ("a", t.a), named ("b", hexStrings)); + } +}; + +// Now that the serialiser trait is visible, it should be detected +static_assert (detail::serialisationKind == detail::SerialisationKind::external); + +// Check that serialisation kinds are correctly detected for primitives +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind< int8_t> == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind< uint8_t> == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind< int16_t> == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind< int32_t> == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind< int64_t> == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); +static_assert (detail::serialisationKind == detail::SerialisationKind::primitive); + +// Check that serialisation is disabled for types with no serialsation defined +static_assert (detail::serialisationKind == detail::SerialisationKind::none); +static_assert (detail::serialisationKind == detail::SerialisationKind::none); + +struct TypeWithInternalSplitSerialisation +{ + std::string a; + Array b; + + auto operator== (const TypeWithInternalSplitSerialisation& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.a, x.b); }; + return tie (*this) == tie (other); + } + + auto operator!= (const TypeWithInternalSplitSerialisation& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = 1; + + template + static void load (Archive& archive, TypeWithInternalSplitSerialisation& t) + { + std::string a; + Array hexStrings; + archive (named ("a", a), named ("b", hexStrings)); + + Array b; + + for (auto& i : hexStrings) + b.add (i.getHexValue32()); + + t = { a, b }; + } + + template + static void save (Archive& archive, const TypeWithInternalSplitSerialisation& t) + { + Array hexStrings; + + for (auto& i : t.b) + hexStrings.add ("0x" + String::toHexString (i)); + + archive (named ("a", t.a), named ("b", hexStrings)); + } +}; + +static_assert (detail::serialisationKind == detail::SerialisationKind::internal); + +struct TypeWithBrokenObjectSerialisation +{ + int a; + int b; + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + // Archiving a named value will start reading/writing an object + archive (named ("a", t.a)); + // Archiving a non-named value will assume that the current node is convertible + archive (t.b); + } +}; + +struct TypeWithBrokenPrimitiveSerialisation +{ + int a; + int b; + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + // Archiving a non-named value will assume that the current node is convertible + archive (t.a); + // Archiving a named value will fail if the current node holds a non-object type + archive (named ("b", t.b)); + } +}; + +struct TypeWithBrokenArraySerialisation +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T&) + { + size_t size = 5; + archive (size); + + // serialisationSize should always be serialised first! + archive (serialisationSize (size)); + } +}; + +struct TypeWithBrokenNestedSerialisation +{ + int a; + TypeWithBrokenObjectSerialisation b; + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("a", t.a), named ("b", t.b)); + } +}; + +struct TypeWithBrokenDynamicSerialisation +{ + std::vector a; + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (t.a); + } +}; + +struct TypeWithVersionedSerialisation +{ + int a{}, b{}, c{}, d{}; + + bool operator== (const TypeWithVersionedSerialisation& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.a, x.b, x.c, x.d); }; + return tie (*this) == tie (other); + } + + bool operator!= (const TypeWithVersionedSerialisation& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = 3; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("a", t.a)); + + if (archive.getVersion() >= 1) + archive (named ("b", t.b)); + + if (archive.getVersion() >= 2) + archive (named ("c", t.c)); + + if (archive.getVersion() >= 3) + archive (named ("d", t.d)); + } +}; + +struct TypeWithRawVarLast +{ + int status = 0; + String message; + var extended; + + bool operator== (const TypeWithRawVarLast& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.status, x.message, x.extended); }; + return tie (*this) == tie (other); + } + + bool operator!= (const TypeWithRawVarLast& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("status", t.status), + named ("message", t.message), + named ("extended", t.extended)); + } +}; + +struct TypeWithRawVarFirst +{ + int status = 0; + String message; + var extended; + + bool operator== (const TypeWithRawVarFirst& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.status, x.message, x.extended); }; + return tie (*this) == tie (other); + } + + bool operator!= (const TypeWithRawVarFirst& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("extended", t.extended), + named ("status", t.status), + named ("message", t.message)); + } +}; + +struct TypeWithInnerVar +{ + int eventId = 0; + var payload; + + bool operator== (const TypeWithInnerVar& other) const + { + const auto tie = [] (const auto& x) { return std::tie (x.eventId, x.payload); }; + return tie (*this) == tie (other); + } + + bool operator!= (const TypeWithInnerVar& other) const { return ! operator== (other); } + + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("eventId", t.eventId), + named ("payload", t.payload)); + } +}; + +class JSONSerialisationTest : public UnitTest +{ +public: + JSONSerialisationTest() : UnitTest ("JSONSerialisation", UnitTestCategories::json) {} + + void runTest() override + { + beginTest ("ToVar"); + { + expectDeepEqual (ToVar::convert (false), false); + expectDeepEqual (ToVar::convert (true), true); + expectDeepEqual (ToVar::convert (1), 1); + expectDeepEqual (ToVar::convert (5.0f), 5.0); + expectDeepEqual (ToVar::convert (6LL), 6); + expectDeepEqual (ToVar::convert ("hello world"), "hello world"); + expectDeepEqual (ToVar::convert (String ("hello world")), "hello world"); + expectDeepEqual (ToVar::convert (std::vector { 1, 2, 3 }), Array { 1, 2, 3 }); + expectDeepEqual (ToVar::convert (TypeWithExternalUnifiedSerialisation { 7, + "hello world", + { 5, 6, 7 }, + { { "foo", 4 }, { "bar", 5 } } }), + makeObject ({ { "__version__", 2 }, + { "a", 7 }, + { "b", "hello world" }, + { "c", Array { 5, 6, 7 } }, + { "d", Array { makeObject ({ { "first", "bar" }, { "second", 5 } }), + makeObject ({ { "first", "foo" }, { "second", 4 } }) } } })); + expectDeepEqual (ToVar::convert (TypeWithInternalUnifiedSerialisation { 7.89, + 4.321f, + "custom string", + { "foo", "bar", "baz" } }), + makeObject ({ { "__version__", 5 }, + { "a", 7.89 }, + { "b", 4.321f }, + { "c", "custom string" }, + { "d", Array { "foo", "bar", "baz" } } })); + expectDeepEqual (ToVar::convert (TypeWithExternalSplitSerialisation { "string", { 1, 2, 3 } }), + makeObject ({ { "__version__", 10 }, + { "a", makeObject ({ { "engaged", true }, { "value", "string" } }) }, + { "b", Array { "0x1", "0x2", "0x3" } } })); + expectDeepEqual (ToVar::convert (TypeWithInternalSplitSerialisation { "string", { 16, 32, 48 } }), + makeObject ({ { "__version__", 1 }, + { "a", "string" }, + { "b", Array { "0x10", "0x20", "0x30" } } })); + + expect (ToVar::convert (TypeWithBrokenObjectSerialisation { 1, 2 }) == std::nullopt); + expect (ToVar::convert (TypeWithBrokenPrimitiveSerialisation { 1, 2 }) == std::nullopt); + expect (ToVar::convert (TypeWithBrokenArraySerialisation {}) == std::nullopt); + expect (ToVar::convert (TypeWithBrokenNestedSerialisation {}) == std::nullopt); + expect (ToVar::convert (TypeWithBrokenDynamicSerialisation { std::vector (10) }) == std::nullopt); + + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }), + makeObject ({ { "__version__", 3 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 }, + { "d", 4 } })); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options{}.withVersionIncluded (false)), + makeObject ({ { "a", 1 }, + { "b", 2 }, + { "c", 3 }, + { "d", 4 } })); + // Requested explicit version is higher than the type's declared version + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options{}.withExplicitVersion (4)), + std::nullopt); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options {}.withExplicitVersion (3)), + makeObject ({ { "__version__", 3 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 }, + { "d", 4 } })); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options {}.withExplicitVersion (2)), + makeObject ({ { "__version__", 2 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 } })); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options {}.withExplicitVersion (1)), + makeObject ({ { "__version__", 1 }, + { "a", 1 }, + { "b", 2 } })); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options {}.withExplicitVersion (0)), + makeObject ({ { "__version__", 0 }, + { "a", 1 } })); + expectDeepEqual (ToVar::convert (TypeWithVersionedSerialisation { 1, 2, 3, 4 }, ToVar::Options {}.withExplicitVersion (std::nullopt)), + makeObject ({ { "a", 1 } })); + + expectDeepEqual (ToVar::convert (TypeWithRawVarLast { 200, "success", true }), + makeObject ({ { "status", 200 }, { "message", "success" }, { "extended", true } })); + expectDeepEqual (ToVar::convert (TypeWithRawVarLast { 200, + "success", + makeObject ({ { "status", 123.456 }, + { "message", "failure" }, + { "extended", true } }) }), + makeObject ({ { "status", 200 }, + { "message", "success" }, + { "extended", makeObject ({ { "status", 123.456 }, + { "message", "failure" }, + { "extended", true } }) } })); + + expectDeepEqual (ToVar::convert (TypeWithRawVarFirst { 200, "success", true }), + makeObject ({ { "status", 200 }, { "message", "success" }, { "extended", true } })); + expectDeepEqual (ToVar::convert (TypeWithRawVarFirst { 200, + "success", + makeObject ({ { "status", 123.456 }, + { "message", "failure" }, + { "extended", true } }) }), + makeObject ({ { "status", 200 }, + { "message", "success" }, + { "extended", makeObject ({ { "status", 123.456 }, + { "message", "failure" }, + { "extended", true } }) } })); + + const auto payload = makeObject ({ { "foo", 1 }, { "bar", 2 } }); + expectDeepEqual (ToVar::convert (TypeWithInnerVar { 404, payload }), + makeObject ({ { "eventId", 404 }, { "payload", payload } })); + } + + beginTest ("FromVar"); + { + expect (FromVar::convert (JSON::fromString ("false")) == false); + expect (FromVar::convert (JSON::fromString ("true")) == true); + expect (FromVar::convert (JSON::fromString ("0")) == false); + expect (FromVar::convert (JSON::fromString ("1")) == true); + expect (FromVar::convert (JSON::fromString ("1")) == 1); + expect (FromVar::convert (JSON::fromString ("5.0f")) == 5.0f); + expect (FromVar::convert (JSON::fromString ("6")) == 6); + expect (FromVar::convert (JSON::fromString ("\"hello world\"")) == "hello world"); + expect (FromVar::convert> (JSON::fromString ("[1,2,3]")) == std::vector { 1, 2, 3 }); + expect (FromVar::convert (makeObject ({ { "__version__", 2 }, + { "a", 7 }, + { "b", "hello world" }, + { "c", Array { 5, 6, 7 } }, + { "d", Array { makeObject ({ { "first", "bar" }, { "second", 5 } }), + makeObject ({ { "first", "foo" }, { "second", 4 } }) } } })) + == TypeWithExternalUnifiedSerialisation { 7, + "hello world", + { 5, 6, 7 }, + { { "foo", 4 }, { "bar", 5 } } }); + + expect (FromVar::convert (makeObject ({ { "__version__", 5 }, + { "a", 7.89 }, + { "b", 4.321f }, + { "c", "custom string" }, + { "d", Array { "foo", "bar", "baz" } } })) + == TypeWithInternalUnifiedSerialisation { 7.89, + 4.321f, + "custom string", + { "foo", "bar", "baz" } }); + + expect (FromVar::convert (makeObject ({ { "__version__", 10 }, + { "a", makeObject ({ { "engaged", true }, { "value", "string" } }) }, + { "b", Array { "0x1", "0x2", "0x3" } } })) + == TypeWithExternalSplitSerialisation { "string", { 1, 2, 3 } }); + expect (FromVar::convert (makeObject ({ { "__version__", 1 }, + { "a", "string" }, + { "b", Array { "0x10", "0x20", "0x30" } } })) + == TypeWithInternalSplitSerialisation { "string", { 16, 32, 48 } }); + + expect (FromVar::convert (JSON::fromString ("null")) == std::nullopt); + expect (FromVar::convert (JSON::fromString ("null")) == std::nullopt); + expect (FromVar::convert (JSON::fromString ("null")) == std::nullopt); + expect (FromVar::convert (JSON::fromString ("null")) == std::nullopt); + expect (FromVar::convert (JSON::fromString ("null")) == std::nullopt); + + expect (FromVar::convert (makeObject ({ { "a", 7.89 }, + { "b", 4.321f } })) == std::nullopt); + + expect (FromVar::convert (makeObject ({ { "__version__", 3 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 }, + { "d", 4 } })) + == TypeWithVersionedSerialisation { 1, 2, 3, 4 }); + expect (FromVar::convert (makeObject ({ { "__version__", 4 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 }, + { "d", 4 } })) + == TypeWithVersionedSerialisation { 1, 2, 3, 4 }); + expect (FromVar::convert (makeObject ({ { "__version__", 2 }, + { "a", 1 }, + { "b", 2 }, + { "c", 3 } })) + == TypeWithVersionedSerialisation { 1, 2, 3, 0 }); + expect (FromVar::convert (makeObject ({ { "__version__", 1 }, + { "a", 1 }, + { "b", 2 } })) + == TypeWithVersionedSerialisation { 1, 2, 0, 0 }); + expect (FromVar::convert (makeObject ({ { "__version__", 0 }, + { "a", 1 } })) + == TypeWithVersionedSerialisation { 1, 0, 0, 0 }); + expect (FromVar::convert (makeObject ({ { "a", 1 } })) + == TypeWithVersionedSerialisation { 1, 0, 0, 0 }); + + const auto raw = makeObject ({ { "status", 200 }, { "message", "success" }, { "extended", "another string" } }); + expect (FromVar::convert (raw) == TypeWithRawVarLast { 200, "success", "another string" }); + expect (FromVar::convert (raw) == TypeWithRawVarFirst { 200, "success", "another string" }); + + const var payloads[] { makeObject ({ { "foo", 1 }, { "bar", 2 } }), + var (Array { 1, 2 }), + var() }; + + for (const auto& payload : payloads) + { + const auto objectWithPayload = makeObject ({ { "eventId", 404 }, { "payload", payload } }); + expect (FromVar::convert (objectWithPayload) == TypeWithInnerVar { 404, payload }); + } + } + } + +private: + void expectDeepEqual (const std::optional& a, const std::optional& b) + { + expect (deepEqual (a, b), a.has_value() && b.has_value() ? JSON::toString (*a) + " != " + JSON::toString (*b) : String()); + } + + static var makeObject (const std::map& map) + { + auto obj = std::make_unique(); + + for (auto& [key, value] : map) + obj->setProperty (key, value); + + return obj.release(); + } + + static bool deepEqual (const DynamicObject& a, const DynamicObject& b) + { + if (a.getProperties().size() != b.getProperties().size()) + return false; + + for (const auto& [key, value] : a.getProperties()) + { + if (! b.hasProperty (key)) + return false; + + if (! deepEqual (value, b.getProperty (key))) + return false; + } + + return true; + } + + static bool deepEqual (const Array& a, const Array& b) + { + return std::equal (a.begin(), a.end(), b.begin(), b.end(), [] (const var& i, const var& j) { return deepEqual (i, j); }); + } + + static bool deepEqual (const var& a, const var& b) + { + if (auto* i = a.getDynamicObject()) + if (auto* j = b.getDynamicObject()) + return deepEqual (*i, *j); + + if (auto* i = a.getArray()) + if (auto* j = b.getArray()) + return deepEqual (*i, *j); + + return a == b; + } + + static bool deepEqual (const std::optional& a, const std::optional& b) + { + if (a.has_value() != b.has_value()) + return false; + + return ! a.has_value() || deepEqual (*a, *b); + } +}; + +static JSONSerialisationTest jsonSerialisationTest; + +} // namespace juce diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index 6f0ac4997c..0e6b23fb37 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -281,6 +281,7 @@ #include "maths/juce_MathsFunctions_test.cpp" #include "misc/juce_EnumHelpers_test.cpp" #include "containers/juce_FixedSizeFunction_test.cpp" + #include "javascript/juce_JSONSerialisation_test.cpp" #endif //============================================================================== diff --git a/modules/juce_core/juce_core.h b/modules/juce_core/juce_core.h index a1074d03ca..011dd00c68 100644 --- a/modules/juce_core/juce_core.h +++ b/modules/juce_core/juce_core.h @@ -309,6 +309,8 @@ JUCE_END_IGNORE_WARNINGS_MSVC #include "streams/juce_FileInputSource.h" #include "logging/juce_FileLogger.h" #include "javascript/juce_JSON.h" +#include "serialisation/juce_Serialisation.h" +#include "javascript/juce_JSONSerialisation.h" #include "javascript/juce_Javascript.h" #include "maths/juce_BigInteger.h" #include "maths/juce_Expression.h" diff --git a/modules/juce_core/serialisation/juce_Serialisation.h b/modules/juce_core/serialisation/juce_Serialisation.h new file mode 100644 index 0000000000..a8431a0ab1 --- /dev/null +++ b/modules/juce_core/serialisation/juce_Serialisation.h @@ -0,0 +1,576 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2022 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +#define JUCE_COMPARISON_OPS X(==) X(!=) X(<) X(<=) X(>) X(>=) + +/** + Combines an object with a name. + + Instances of Named have reference-like semantics. That is, Named stores a reference + to a wrapped value, rather than storing the value internally. + + @tparam T the type of reference that is wrapped. Passing "const T" will cause the Named + instance to hold a "const T&"; passing "T" will cause the Named instance to + hold a "T&". + + @see named() + + @tags{Core} +*/ +template +struct Named +{ + #define X(op) auto operator op (const Named& other) const { return value op other.value; } + JUCE_COMPARISON_OPS + #undef X + + std::string_view name; ///< A name that corresponds to the value + T& value; ///< A reference to a value to wrap +}; + +/** Produces a Named instance that holds a mutable reference. */ +template constexpr auto named (std::string_view c, T& t) { return Named { c, t }; } + +/** Produces a Named instance that holds an immutable reference. */ +template constexpr auto named (std::string_view c, const T& t) { return Named { c, t }; } + +/** + Holds a reference to some kind of size value, used to indicate that an object being marshalled + is of variable size (e.g. Array, vector, map, set, etc.). + + If you need to write your own serialisation routines for a dynamically-sized type, ensure + that you archive an instance of SerialisationSize before any of the contents of the container. + + @tparam the (probably numeric) type of the size value + + @see serialisztionSize() + + @tags{Core} +*/ +template +struct SerialisationSize +{ + #define X(op) auto operator op (const SerialisationSize& other) const { return size op other.size; } + JUCE_COMPARISON_OPS + #undef X + + T& size; +}; + +/** Produces a SerialisationSize instance that holds a mutable reference to a size value. */ +template constexpr auto serialisationSize (T& t) -> std::enable_if_t, SerialisationSize> { return { t }; } + +/** Produces a SerialisationSize instance that holds an immutable reference to a size value. */ +template constexpr auto serialisationSize (const T& t) -> std::enable_if_t, SerialisationSize> { return { t }; } + +#undef JUCE_COMPARISON_OPS + +/** + Allows serialisation functions to be attached to a specific type without having to modify the + declaration of that type. + + A specialisation of SerialisationTraits must include: + - A static constexpr data member named 'marshallingVersion' with a value that is convertible + to std::optional. + - Either: + - Normally, a single function with the following signature: + @code + template + static void serialise (Archive& archive, Item& item); + @endcode + - For types that must do slightly different work when loading and saving, you may supply two + functions with the following signatures, where "T" is a placeholder for the type on which + SerialisationTraits is specialised: + @code + template + static void load (Archive& archive, T& item); + + template + static void save (Archive& archive, const T& item); + @endcode + + If the marshallingVersion converts to a null optional, then all versioning information will be + ignored when marshalling the type. Otherwise, if the value converts to a non-null optional, this + versioning information will be included when serialising the type. + + Inside serialise() and load() you may call archive.getVersion() to find the detected version + of the object being deserialised. archive.getVersion() will return an std::optional, + where 'nullopt' indicates that no versioning information was detected. + + Marshalling functions can also be specified directly inside the type to be marshalled. This + approach may be preferable as it is more concise. Internal marshalling functions are written + in exactly the same way as external ones; i.e. the type must include a marshallingVersion, + and either a single serialise function, or a load/save pair of functions, as specified above. + + @tags{Core} +*/ +template struct SerialisationTraits +{ + /* Intentionally left blank. */ +}; + +//============================================================================== +/* + The following are specialisations of SerialisationTraits for commonly-used types. +*/ + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + t.resize (size); + + for (auto& element : t) + archive (element); + } + + template + static void save (Archive& archive, const T& t) + { + archive (serialisationSize (t.size())); + + for (auto& element : t) + archive (element); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + t.resize (size); + + for (auto& element : t) + archive (element); + } + + template + static void save (Archive& archive, const T& t) + { + archive (serialisationSize (t.size())); + + for (auto& element : t) + archive (element); + } +}; + +template <> +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (t.strings); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) + { + archive (named ("first", t.first), named ("second", t.second)); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, std::optional& t) + { + bool engaged = false; + + archive (named ("engaged", engaged)); + + if (! engaged) + return; + + t.emplace(); + archive (named ("value", *t)); + } + + template + static void save (Archive& archive, const std::optional& t) + { + archive (named ("engaged", t.has_value())); + + if (t.has_value()) + archive (named ("value", *t)); + } +}; + +template <> +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, std::string& t) + { + String temporary; + archive (temporary); + t = temporary.toStdString(); + } + + template + static void save (Archive& archive, const std::string& t) + { + archive (String (t)); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + + for (auto i = (decltype (size)) 0; i < size; ++i) + { + std::pair element; + archive (element); + t.insert (element); + } + } + + template + static void save (Archive& archive, const T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + + for (const auto& element : t) + archive (element); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + + for (auto i = (decltype (size)) 0; i < size; ++i) + { + typename T::value_type element; + archive (element); + t.insert (element); + } + } + + template + static void save (Archive& archive, const T& t) + { + auto size = t.size(); + archive (serialisationSize (size)); + + for (const auto& element : t) + archive (element); + } +}; + +template +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void serialise (Archive& archive, T& t) { archive (String (t, N)); } +}; + +template +struct SerialisationTraits +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = N; + archive (serialisationSize (size)); + + for (auto& element : t) + archive (element); + } + + template + static void save (Archive& archive, const T& t) + { + const auto size = N; + archive (serialisationSize (size)); + + for (auto& element : t) + archive (element); + } +}; + +template +struct SerialisationTraits> +{ + static constexpr auto marshallingVersion = std::nullopt; + + template + static void load (Archive& archive, T& t) + { + auto size = N; + archive (serialisationSize (size)); + + for (auto& element : t) + archive (element); + } + + template + static void save (Archive& archive, const T& t) + { + const auto size = N; + archive (serialisationSize (size)); + + for (auto& element : t) + archive (element); + } +}; + +#ifndef DOXYGEN + +/* + This namespace holds utilities for detecting and using serialisation functions. + + The contents of this namespace are private, and liable to change, so you shouldn't use any of + the contents directly. +*/ +namespace detail +{ + struct DummyArchive + { + template + bool operator() (Ts&&...); + + std::optional getVersion() const { return {}; } + }; + + template + constexpr auto hasInternalVersion = false; + + template + constexpr auto hasInternalVersion> = true; + + template + constexpr auto hasInternalSerialise = false; + + template + constexpr auto hasInternalSerialise(), std::declval()))>> = true; + + template + constexpr auto hasInternalLoad = false; + + template + constexpr auto hasInternalLoad(), std::declval()))>> = true; + + template + constexpr auto hasInternalSave = false; + + template + constexpr auto hasInternalSave(), std::declval()))>> = true; + + template + struct SerialisedTypeTrait { using type = T; }; + + template + struct SerialisedTypeTrait> { using type = T; }; + + template + using SerialisedType = typename SerialisedTypeTrait::type; + + template + constexpr auto hasSerialisation = hasInternalVersion> + || hasInternalSerialise> + || hasInternalLoad> + || hasInternalSave>; + + /* Different kinds of serialisation function. */ + enum class SerialisationKind + { + none, // The type doesn't have any serialisation + primitive, // The type has serialisation handling defined directly on the archiver. enums will be converted to equivalent integral values + internal, // The type has internally-defined serialisation utilities + external, // The type has an external specialisation of SerialisationTraits + }; + + /* The SerialisationKind to use for the type T. + + Primitive serialisation is used for arithmetic types, enums, Strings, and vars. + Internal serialisation is used for types that declare an internal marshallingVersion, + serialise(), load(), or save(). + External serialisation is used in all other cases. + */ + template + constexpr auto serialisationKind = [] + { + if constexpr (std::is_arithmetic_v || std::is_enum_v || std::is_same_v || std::is_same_v) + return SerialisationKind::primitive; + else if constexpr (hasSerialisation) + return SerialisationKind::internal; + else if constexpr (hasSerialisation>) + return SerialisationKind::external; + else + return SerialisationKind::none; + }(); + + /* This trait defines the serialisation utilities that are used for primitive types. */ + template > + struct ForwardingSerialisationTraits + { + static constexpr auto marshallingVersion = std::nullopt; + + template + static auto load (Archive& archive, Primitive& t) + { + if constexpr (std::is_enum_v) + return archive (*reinterpret_cast*> (&t)); + else + return archive (t); + } + + template + static auto save (Archive& archive, const Primitive& t) + { + if constexpr (std::is_enum_v) + return archive (*reinterpret_cast*> (&t)); + else + return archive (t); + } + }; + + /* This specialisation will be used for types with internal serialisation. + + All members of ForwardingSerialisationTraits forward to the corresponding member of T. + */ + template + struct ForwardingSerialisationTraits + { + static constexpr std::optional marshallingVersion { T::marshallingVersion }; + + template + static auto serialise (Archive& archive, Item& t) -> decltype (Item::serialise (archive, t)) { return Item::serialise (archive, t); } + + template + static auto load (Archive& archive, Item& t) -> decltype (Item::load (archive, t)) { return Item::load (archive, t); } + + template + static auto save (Archive& archive, const Item& t) -> decltype (Item::save (archive, t)) { return Item::save (archive, t); } + }; + + /* This specialisation will be used for types with external serialisation. + + @see SerialisationTraits + */ + template + struct ForwardingSerialisationTraits : SerialisationTraits {}; + + template + constexpr auto hasSerialise = false; + + template + constexpr auto hasSerialise::serialise (std::declval(), std::declval()))>> = true; + + template + constexpr auto hasLoad = false; + + template + constexpr auto hasLoad::load (std::declval(), std::declval()))>> = true; + + template + constexpr auto hasSave = false; + + template + constexpr auto hasSave::save (std::declval(), std::declval()))>> = true; + + template + constexpr auto delayStaticAssert = false; + + /* Calls the correct function (serialise or save) to save the argument t to the archive. + */ + template + auto doSave (Archive& archive, const T& t) + { + if constexpr (serialisationKind == SerialisationKind::none) + static_assert (delayStaticAssert, "No serialisation function found or marshallingVersion unset"); + else if constexpr (hasSerialise && ! hasSave) + return ForwardingSerialisationTraits::serialise (archive, t); + else if constexpr (! hasSerialise && hasSave) + return ForwardingSerialisationTraits::save (archive, t); + else + static_assert (delayStaticAssert, "Multiple serialisation functions found"); + } + + /* Calls the correct function (serialise or load) to load the argument t from the archive. + */ + template + auto doLoad (Archive& archive, T& t) + { + if constexpr (serialisationKind == SerialisationKind::none) + static_assert (delayStaticAssert, "No serialisation function found or marshallingVersion unset"); + else if constexpr (hasSerialise && ! hasLoad) + return ForwardingSerialisationTraits::serialise (archive, t); + else if constexpr (! hasSerialise && hasLoad) + return ForwardingSerialisationTraits::load (archive, t); + else + static_assert (delayStaticAssert, "Multiple serialisation functions found"); + } +} // namespace detail + +#endif + +} // namespace juce