| @@ -523,11 +523,11 @@ protected: | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| /** | |||
| Set the key name of the state @a index. | |||
| Set the state key and default value of @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| Must be implemented by your plugin class only if DISTRHO_PLUGIN_WANT_STATE is enabled. | |||
| */ | |||
| virtual void d_initStateKey(uint32_t index, d_string& stateKey) = 0; | |||
| virtual void d_initState(uint32_t index, d_string& stateKey, d_string& defaultStateValue) = 0; | |||
| #endif | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| @@ -55,8 +55,9 @@ Plugin::Plugin(const uint32_t parameterCount, const uint32_t programCount, const | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| if (stateCount > 0) | |||
| { | |||
| pData->stateCount = stateCount; | |||
| pData->stateKeys = new d_string[stateCount]; | |||
| pData->stateCount = stateCount; | |||
| pData->stateKeys = new d_string[stateCount]; | |||
| pData->stateDefValues = new d_string[stateCount]; | |||
| } | |||
| #else | |||
| DISTRHO_SAFE_ASSERT(stateCount == 0); | |||
| @@ -49,6 +49,7 @@ struct Plugin::PrivateData { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| uint32_t stateCount; | |||
| d_string* stateKeys; | |||
| d_string* stateDefValues; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| @@ -73,6 +74,7 @@ struct Plugin::PrivateData { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| stateCount(0), | |||
| stateKeys(nullptr), | |||
| stateDefValues(nullptr), | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| latency(0), | |||
| @@ -106,6 +108,12 @@ struct Plugin::PrivateData { | |||
| delete[] stateKeys; | |||
| stateKeys = nullptr; | |||
| } | |||
| if (stateDefValues != nullptr) | |||
| { | |||
| delete[] stateDefValues; | |||
| stateDefValues = nullptr; | |||
| } | |||
| #endif | |||
| } | |||
| }; | |||
| @@ -134,7 +142,7 @@ public: | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| for (uint32_t i=0, count=fData->stateCount; i < count; ++i) | |||
| fPlugin->d_initStateKey(i, fData->stateKeys[i]); | |||
| fPlugin->d_initState(i, fData->stateKeys[i], fData->stateDefValues[i]); | |||
| #endif | |||
| } | |||
| @@ -305,6 +313,13 @@ public: | |||
| return fData->stateKeys[index]; | |||
| } | |||
| const d_string& getStateDefaultValue(const uint32_t index) const noexcept | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->stateCount, sFallbackString); | |||
| return fData->stateDefValues[index]; | |||
| } | |||
| void setState(const char* const key, const char* const value) | |||
| { | |||
| DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,); | |||
| @@ -48,7 +48,7 @@ | |||
| START_NAMESPACE_DISTRHO | |||
| typedef std::map<d_string,d_string> StringMap; | |||
| typedef std::map<const d_string,d_string> StringMap; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -114,7 +114,12 @@ public: | |||
| fNeededUiSends = new bool[count]; | |||
| for (uint32_t i=0; i < count; ++i) | |||
| { | |||
| fNeededUiSends[i] = false; | |||
| const d_string& d_key(fPlugin.getStateKey(i)); | |||
| fStateMap[d_key] = fPlugin.getStateDefaultValue(i); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| @@ -592,7 +597,10 @@ public: | |||
| const d_string& key = cit->first; | |||
| const d_string& value = cit->second; | |||
| store(handle, fUridMap->map(fUridMap->handle, key.buffer()), value.buffer(), value.length(), fURIDs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); | |||
| const d_string urnKey("urn:distrho:" + key); | |||
| // some hosts need +1 for the null terminator, even though the type is string | |||
| store(handle, fUridMap->map(fUridMap->handle, urnKey.buffer()), value.buffer(), value.length()+1, fURIDs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); | |||
| } | |||
| return LV2_STATE_SUCCESS; | |||
| @@ -606,11 +614,12 @@ public: | |||
| for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) | |||
| { | |||
| const d_string& key(fPlugin.getStateKey(i)); | |||
| const d_string urnKey("urn:distrho:" + key); | |||
| size = 0; | |||
| type = 0; | |||
| flags = LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE; | |||
| const void* data = retrieve(handle, fUridMap->map(fUridMap->handle, key.buffer()), &size, &type, &flags); | |||
| const void* data = retrieve(handle, fUridMap->map(fUridMap->handle, urnKey.buffer()), &size, &type, &flags); | |||
| if (data == nullptr || size == 0) | |||
| continue; | |||
| @@ -618,7 +627,8 @@ public: | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(type == fURIDs.atomString); | |||
| const char* const value((const char*)data); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(std::strlen(value) == size); | |||
| const std::size_t length(std::strlen(value)); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(length == size || length+1 == size); | |||
| setState(key, value); | |||
| @@ -762,9 +772,7 @@ private: | |||
| } | |||
| } | |||
| // nope, add a new one then | |||
| d_string d_key(key); | |||
| fStateMap[d_key] = newValue; | |||
| d_stderr("Failed to find plugin state with key \"%s\"", key); | |||
| } | |||
| #endif | |||
| @@ -65,7 +65,7 @@ struct ERect { | |||
| START_NAMESPACE_DISTRHO | |||
| typedef std::map<d_string,d_string> StringMap; | |||
| typedef std::map<const d_string,d_string> StringMap; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -311,6 +311,12 @@ public: | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| fStateChunk = nullptr; | |||
| for (uint32_t i=0, count=fPlugin.getStateCount(); i<count; ++i) | |||
| { | |||
| const d_string& d_key(fPlugin.getStateKey(i)); | |||
| fStateMap[d_key] = fPlugin.getStateDefaultValue(i); | |||
| } | |||
| #endif | |||
| } | |||
| @@ -745,12 +751,12 @@ private: | |||
| // ------------------------------------------------------------------- | |||
| // functions called from the UI side, may block | |||
| void setStateFromUi(const char* const newKey, const char* const newValue) override | |||
| void setStateFromUi(const char* const key, const char* const newValue) override | |||
| { | |||
| fPlugin.setState(newKey, newValue); | |||
| fPlugin.setState(key, newValue); | |||
| // check if we want to save this key | |||
| if (! fPlugin.wantStateKey(newKey)) | |||
| if (! fPlugin.wantStateKey(key)) | |||
| return; | |||
| // check if key already exists | |||
| @@ -758,16 +764,14 @@ private: | |||
| { | |||
| const d_string& d_key(it->first); | |||
| if (d_key == newKey) | |||
| if (d_key == key) | |||
| { | |||
| it->second = newValue; | |||
| return; | |||
| } | |||
| } | |||
| // nope, add a new one then | |||
| d_string d_key(newKey); | |||
| fStateMap[d_key] = newValue; | |||
| d_stderr("Failed to find plugin state with key \"%s\"", key); | |||
| } | |||
| #endif | |||
| }; | |||