Skip to content

Commit

Permalink
Better backrds compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
jatinchowdhury18 committed Nov 29, 2024
1 parent 5cd410c commit 2660c14
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,24 @@ inline void NonParamState::validateStateValues() const
#endif
}

template <typename Serializer>
typename Serializer::SerializedType NonParamState::serialize (const NonParamState& state)
inline json NonParamState::serialize (const NonParamState& state)
{
#if ! CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
auto serial = nlohmann::json::object();
for (const auto& value : state.values)
serial[value->name] = value->serialize();
return serial;
#else
auto serial = Serializer::createBaseElement();
for (const auto& value : state.values)
value->serialize (serial);
return serial;
#endif
}

template <typename Serializer>
void NonParamState::deserialize (typename Serializer::DeserializedType deserial, const NonParamState& state)
inline void NonParamState::legacy_deserialize (const json& deserial, const NonParamState& state)
{
#if ! CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
for (auto& value : state.values)
{
auto iter = deserial.find (value->name);
if (iter != deserial.end())
value->deserialize (*iter);
else
value->reset();
}
#else
using Serializer = JSONSerializer;
std::vector<std::string_view> namesThatHaveBeenDeserialized {};
if (const auto numNamesAndVals = Serializer::getNumChildElements (deserial); numNamesAndVals % 2 == 0)
{
namesThatHaveBeenDeserialized.reserve (static_cast<size_t> (numNamesAndVals) / 2);
for (int i = 0; i < numNamesAndVals; i += 2)
{
const auto name = Serializer::getChildElement (deserial, i).template get<std::string_view>();
const auto name = Serializer::getChildElement (deserial, i).get<std::string_view>();
const auto& valueDeserial = Serializer::getChildElement (deserial, i + 1);
for (auto& value : state.values)
{
Expand All @@ -102,6 +84,17 @@ void NonParamState::deserialize (typename Serializer::DeserializedType deserial,
value->reset();
}
}
#endif
}

inline void NonParamState::deserialize (const json& deserial, const NonParamState& state)
{
for (auto& value : state.values)
{
auto iter = deserial.find (value->name);
if (iter != deserial.end())
value->deserialize (*iter);
else
value->reset();
}
}
} // namespace chowdsp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ class NonParamState
void addStateValues (ContainerType& container);

/** Custom serializer */
template <typename Serializer>
static typename Serializer::SerializedType serialize (const NonParamState& state);
static json serialize (const NonParamState& state);

/** Custom deserializer */
template <typename Serializer>
static void deserialize (typename Serializer::DeserializedType deserial, const NonParamState& state);
static void deserialize (const json& deserial, const NonParamState& state);

/** Custom deserializer */
static void legacy_deserialize (const json& deserial, const NonParamState& state);

/** Assign this function to apply version streaming to your non-parameter state. */
std::function<void (const Version&)> versionStreamingCallback = nullptr;
Expand Down
91 changes: 21 additions & 70 deletions modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,13 @@ inline ParamHolder::ParamHolder (ParamHolder* parent, std::string_view phName, b
return OptionalPointer<ChainedArenaAllocator> { static_cast<size_t> (1024) };
}(),
},
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
allParamsMap { MapAllocator { arena } },
#endif
name { arena::alloc_string (*arena, phName) },
isOwning { phIsOwning }
{
}

inline ParamHolder::ParamHolder (ChainedArenaAllocator& alloc, std::string_view phName, bool phIsOwning)
: arena { &alloc, false },
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
allParamsMap { MapAllocator { arena } },
#endif
name { arena::alloc_string (*arena, phName) },
isOwning { phIsOwning }
{
Expand Down Expand Up @@ -59,41 +53,26 @@ template <typename ParamType, typename... OtherParams>
std::enable_if_t<std::is_base_of_v<FloatParameter, ParamType>, void>
ParamHolder::add (OptionalPointer<ParamType>& floatParam, OtherParams&... others)
{
ThingPtr paramPtr { reinterpret_cast<PackedVoid*> (isOwning ? floatParam.release() : floatParam.get()),
getFlags (FloatParam, isOwning) };
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
const auto paramID = toStringView (floatParam->paramID);
allParamsMap.insert ({ paramID, paramPtr });
#endif
things.insert (std::move (paramPtr));
things.insert (ThingPtr { reinterpret_cast<PackedVoid*> (isOwning ? floatParam.release() : floatParam.get()),
getFlags (FloatParam, isOwning) });
add (others...);
}

template <typename ParamType, typename... OtherParams>
std::enable_if_t<std::is_base_of_v<ChoiceParameter, ParamType>, void>
ParamHolder::add (OptionalPointer<ParamType>& choiceParam, OtherParams&... others)
{
ThingPtr paramPtr { reinterpret_cast<PackedVoid*> (isOwning ? choiceParam.release() : choiceParam.get()),
getFlags (ChoiceParam, isOwning) };
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
const auto paramID = toStringView (choiceParam->paramID);
allParamsMap.insert ({ paramID, paramPtr });
#endif
things.insert (std::move (paramPtr));
things.insert (ThingPtr { reinterpret_cast<PackedVoid*> (isOwning ? choiceParam.release() : choiceParam.get()),
getFlags (ChoiceParam, isOwning) });
add (others...);
}

template <typename ParamType, typename... OtherParams>
std::enable_if_t<std::is_base_of_v<BoolParameter, ParamType>, void>
ParamHolder::add (OptionalPointer<ParamType>& boolParam, OtherParams&... others)
{
ThingPtr paramPtr { reinterpret_cast<PackedVoid*> (isOwning ? boolParam.release() : boolParam.get()),
getFlags (BoolParam, isOwning) };
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
const auto paramID = toStringView (boolParam->paramID);
allParamsMap.insert ({ paramID, paramPtr });
#endif
things.insert (std::move (paramPtr));
things.insert (ThingPtr { reinterpret_cast<PackedVoid*> (isOwning ? boolParam.release() : boolParam.get()),
getFlags (BoolParam, isOwning) });
add (others...);
}

Expand Down Expand Up @@ -124,13 +103,6 @@ std::enable_if_t<std::is_base_of_v<BoolParameter, ParamType>, void>
template <typename... OtherParams>
void ParamHolder::add (ParamHolder& paramHolder, OtherParams&... others)
{
#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
// This should be the parent of the holder being added.
jassert (arena == paramHolder.arena);

allParamsMap.merge (paramHolder.allParamsMap);
jassert (paramHolder.allParamsMap.empty()); // assuming no duplicate parameter IDs, all the parameters should be moved in the merge!
#endif
things.insert (ThingPtr { reinterpret_cast<PackedVoid*> (&paramHolder), Holder });
add (others...);
}
Expand All @@ -144,7 +116,6 @@ std::enable_if_t<TypeTraits::IsIterable<ParamContainerType>, void>
add (others...);
}


[[nodiscard]] inline int ParamHolder::count() const noexcept
{
auto count = static_cast<int> (things.count());
Expand Down Expand Up @@ -275,8 +246,7 @@ size_t ParamHolder::doForAllParameters (Callable&& callable, size_t index) const
return index;
}

template <typename Serializer>
typename Serializer::SerializedType ParamHolder::serialize (const ParamHolder& paramHolder)
inline json ParamHolder::serialize (const ParamHolder& paramHolder)
{
#if ! CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
auto serial = nlohmann::json::object();
Expand All @@ -298,55 +268,37 @@ typename Serializer::SerializedType ParamHolder::serialize (const ParamHolder& p
#endif
}

template <typename Serializer>
void ParamHolder::deserialize (typename Serializer::DeserializedType deserial, ParamHolder& paramHolder)
inline void ParamHolder::deserialize (const json& deserial, ParamHolder& paramHolder)
{
#if ! CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
paramHolder.doForAllParameters (
[&deserial] (auto& param, size_t)
{
const auto paramID = toStringView (param.paramID);
ParameterTypeHelpers::setValue (deserial.value (paramID, ParameterTypeHelpers::getDefaultValue (param)), param);
});
#else
}

inline void ParamHolder::legacy_deserialize (const json& deserial, ParamHolder& paramHolder)
{
using Serializer = JSONSerializer;
std::vector<std::string_view> paramIDsThatHaveBeenDeserialized {};
if (const auto numParamIDsAndVals = Serializer::getNumChildElements (deserial); numParamIDsAndVals % 2 == 0)
{
paramIDsThatHaveBeenDeserialized.reserve (static_cast<size_t> (numParamIDsAndVals) / 2);
for (int i = 0; i < numParamIDsAndVals; i += 2)
{
const auto paramID = Serializer::getChildElement (deserial, i).template get<std::string_view>();
const auto paramID = Serializer::getChildElement (deserial, i).get<std::string_view>();
const auto& paramDeserial = Serializer::getChildElement (deserial, i + 1);

auto paramPtrIter = paramHolder.allParamsMap.find (std::string { paramID });
if (paramPtrIter == paramHolder.allParamsMap.end())
continue;

paramIDsThatHaveBeenDeserialized.push_back (paramID);
[&paramDeserial] (ThingPtr& paramPtr)
{
const auto deserializeParam = [] (auto* param, auto& pd)
paramHolder.doForAllParameters (
[&] (auto& param, size_t)
{
ParameterTypeHelpers::deserializeParameter<Serializer> (pd, *param);
};
if (toStringView (param.paramID) != paramID)
return;

const auto type = getType (paramPtr);
switch (type)
{
case FloatParam:
deserializeParam (reinterpret_cast<FloatParameter*> (paramPtr.get_ptr()), paramDeserial);
break;
case ChoiceParam:
deserializeParam (reinterpret_cast<ChoiceParameter*> (paramPtr.get_ptr()), paramDeserial);
break;
case BoolParam:
deserializeParam (reinterpret_cast<BoolParameter*> (paramPtr.get_ptr()), paramDeserial);
break;
default:
jassertfalse;
break;
}
}(paramPtrIter->second);
paramIDsThatHaveBeenDeserialized.push_back (paramID);
ParameterTypeHelpers::deserializeParameter<Serializer> (paramDeserial, param);
});
}
}
else
Expand All @@ -367,7 +319,6 @@ void ParamHolder::deserialize (typename Serializer::DeserializedType deserial, P
ParameterTypeHelpers::resetParameter (param);
});
}
#endif
}

inline void ParamHolder::applyVersionStreaming (const Version& version)
Expand Down
17 changes: 5 additions & 12 deletions modules/plugin/chowdsp_plugin_state/Backend/chowdsp_ParamHolder.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,13 @@ class ParamHolder
size_t doForAllParameters (Callable&& callable, size_t index = 0) const;

/** Custom serializer */
template <typename Serializer>
static typename Serializer::SerializedType serialize (const ParamHolder& paramHolder);
static json serialize (const ParamHolder& paramHolder);

/** Custom deserializer */
template <typename Serializer>
static void deserialize (typename Serializer::DeserializedType deserial, ParamHolder& paramHolder);
static void deserialize (const json& deserial, ParamHolder& paramHolder);

/** Legacy deserializer */
static void legacy_deserialize (const json& deserial, ParamHolder& paramHolder);

/** Recursively applies version streaming to the parameters herein. */
void applyVersionStreaming (const Version&);
Expand Down Expand Up @@ -139,14 +140,6 @@ class ParamHolder
return static_cast<uint8_t> (type | (shouldDelete ? ShouldDelete : 0));
}

#if CHOWDSP_USE_LEGACY_STATE_SERIALIZATION
using MapKey = std::string_view;
using MapValue = ThingPtr;
using MapAllocator = STLArenaAllocator<std::pair<const MapKey, MapValue>, ChainedArenaAllocator>;
using AllParamsMap = std::unordered_map<MapKey, MapValue, std::hash<MapKey>, std::equal_to<>, MapAllocator>;
AllParamsMap allParamsMap;
#endif

std::string_view name;
bool isOwning;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PluginState
virtual void serialize (juce::MemoryBlock& data) const = 0;

/** Deserializes the plugin state from the given MemoryBlock */
virtual void deserialize (const juce::MemoryBlock& data) = 0;
virtual void deserialize (juce::MemoryBlock&& data) = 0;

/**
* Adds a parameter listener which will be called on either the message
Expand Down Expand Up @@ -96,7 +96,7 @@ class PluginState
struct DummyPluginState : PluginState
{
void serialize (juce::MemoryBlock&) const override {}
void deserialize (const juce::MemoryBlock&) override {}
void deserialize (juce::MemoryBlock&&) override {}

NonParamState non_params {};
[[nodiscard]] NonParamState& getNonParameters() override { return non_params; }
Expand Down
Loading

0 comments on commit 2660c14

Please sign in to comment.