@@ -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 | |||
}; | |||