int LoadSave::compareVersionStrings(String a, String b) { a.trim(); b.trim(); if (a.isEmpty() && b.isEmpty()) return 0; String major_version_a = a.upToFirstOccurrenceOf(".", false, true); String major_version_b = b.upToFirstOccurrenceOf(".", false, true); if (!major_version_a.containsOnly("0123456789")) major_version_a = "0"; if (!major_version_b.containsOnly("0123456789")) major_version_b = "0"; int major_value_a = major_version_a.getIntValue(); int major_value_b = major_version_b.getIntValue(); if (major_value_a > major_value_b) return 1; else if (major_value_a < major_value_b) return -1; return compareVersionStrings(a.fromFirstOccurrenceOf(".", false, true), b.fromFirstOccurrenceOf(".", false, true)); }
//this function is explained in the header. CFComparisonResult compareVersionStringsTranslating1_0To0_5(CFStringRef a, CFStringRef b) { if (a == b) return kCFCompareEqualTo; else if (!a) return kCFCompareGreaterThan; else if (!b) return kCFCompareLessThan; CFStringRef one_zero = CFSTR("1.0"); CFStringRef zero_five = CFSTR("0.5"); if (CFEqual(a, one_zero)) a = zero_five; if (CFEqual(b, one_zero)) b = zero_five; return compareVersionStrings(a, b); }
bool LoadSave::wasUpgraded() { var config_state = getConfigVar(); DynamicObject* config_object = config_state.getDynamicObject(); if (!config_state.isObject()) return true; if (!config_object->hasProperty("synth_version")) return true; Array<File> patches; String extension = String("*.") + mopo::PATCH_EXTENSION; getBankDirectory().findChildFiles(patches, File::findFiles, true, extension); if (patches.size() == 0) return true; return compareVersionStrings(config_object->getProperty("synth_version"), ProjectInfo::versionString) < 0; }
ScoreChange ScoreManager::getVersionScoreChange(const BinaryVersion* originalVersion, const BinaryVersion* supposedVersion) const { auto supposedVersionWeight = __get_version_weight(supposedVersion); auto originalVersionWeight = __get_version_weight(originalVersion); auto value = supposedVersionWeight - originalVersionWeight; ScoreChange scoreChange; ScoreChange::SubScore::Type scoreType; if (!originalVersion) { scoreType = ScoreChange::SubScore::New; } else if (!supposedVersion) { scoreType = ScoreChange::SubScore::Removal; auto binaryPackage = __cache->getBinaryPackage(originalVersion->packageName); auto installedVersion = binaryPackage->getInstalledVersion(); if (installedVersion && installedVersion->essential) { scoreChange.__subscores[ScoreChange::SubScore::RemovalOfEssential] = 1; } if (__cache->isAutomaticallyInstalled(originalVersion->packageName)) { scoreChange.__subscores[ScoreChange::SubScore::RemovalOfAuto] = 1; } } else { scoreType = compareVersionStrings(originalVersion->versionString, supposedVersion->versionString) < 0 ? ScoreChange::SubScore::Upgrade : ScoreChange::SubScore::Downgrade; } scoreChange.__subscores[ScoreChange::SubScore::Version] = value; scoreChange.__subscores[scoreType] = 1; return scoreChange; }
void LoadSave::varToState(SynthBase* synth, std::map<std::string, String>& save_info, var state) { if (!state.isObject()) return; DynamicObject* object_state = state.getDynamicObject(); NamedValueSet properties = object_state->getProperties(); // Version 0.4.1 was the last build before we saved the version number. String version = "0.4.1"; if (properties.contains("synth_version")) version = properties["synth_version"]; // After 0.4.1 there was a patch file restructure. if (compareVersionStrings(version, "0.4.1") <= 0) { NamedValueSet new_properties; new_properties.set("settings", object_state); properties = new_properties; } var settings = properties["settings"]; DynamicObject* settings_object = settings.getDynamicObject(); NamedValueSet settings_properties = settings_object->getProperties(); Array<var>* modulations = settings_properties["modulations"].getArray(); // After 0.5.0 mixer was added and osc_mix was removed. And scaling of oscillators was changed. if (compareVersionStrings(version, "0.5.0") <= 0) { // Fix control control values. if (settings_properties.contains("osc_mix")) { mopo::mopo_float osc_mix = settings_properties["osc_mix"]; settings_properties.set("osc_1_volume", sqrt(1.0f - osc_mix)); settings_properties.set("osc_2_volume", sqrt(osc_mix)); settings_properties.remove("osc_mix"); } // Fix modulation routing. var* modulation = modulations->begin(); Array<var> old_modulations; Array<DynamicObject*> new_modulations; for (; modulation != modulations->end(); ++modulation) { DynamicObject* mod = modulation->getDynamicObject(); String destination = mod->getProperty("destination").toString(); if (destination == "osc_mix") { String source = mod->getProperty("source").toString(); mopo::mopo_float amount = mod->getProperty("amount"); old_modulations.add(mod); DynamicObject* osc_1_mod = new DynamicObject(); osc_1_mod->setProperty("source", source); osc_1_mod->setProperty("destination", "osc_1_volume"); osc_1_mod->setProperty("amount", -amount); new_modulations.add(osc_1_mod); DynamicObject* osc_2_mod = new DynamicObject(); osc_2_mod->setProperty("source", source); osc_2_mod->setProperty("destination", "osc_2_volume"); osc_2_mod->setProperty("amount", amount); new_modulations.add(osc_2_mod); } } for (var old_modulation : old_modulations) modulations->removeFirstMatchingValue(old_modulation); for (DynamicObject* modulation : new_modulations) modulations->add(modulation); } if (compareVersionStrings(version, "0.7.2") <= 0) { bool stutter_on = settings_properties["stutter_on"]; if (stutter_on) { settings_properties.set("stutter_resample_sync", 0); settings_properties.set("stutter_sync", 0); } } loadControls(synth, settings_properties); loadModulations(synth, modulations); loadSaveState(save_info, properties); }