TEST (CompOption, AssignDefaultActionValueToUnsetTypeClearsOldStateKeepsInfo) { /* Value is unset at this point */ CompOption option ("testing", CompOption::TypeKey); CompAction action; /* We need to set up the state here as * the CompOption::Value constructor makes * a copy of the action */ action.setState (CompAction::StateInitKey); action.setButton (CompAction::ButtonBinding (1, 1 << 1)); CompOption::Value value (action); ASSERT_EQ (value.action ().state (), CompAction::StateInitKey); /* Actually set the action value, this will * overwrite the internal value */ option.set (value); /* We don't care about the old action's state, so get * rid of it */ ASSERT_EQ (option.value ().action ().state (), 0); /* We do want to keep the non-stateful data which is * pure info */ ASSERT_EQ (option.value ().action ().button ().button (), 1); ASSERT_EQ (option.value ().action ().button ().modifiers (), 1 << 1); }
bool CompOption::setOption (CompOption &o, CompOption::Value &value) { return o.set (value); }
void PrivateAnimScreen::updateOptionSet (OptionSet *os, const char *optNamesValuesOrig) { unsigned int len = strlen (optNamesValuesOrig); char *optNamesValues = (char *)calloc (len + 1, 1); // Find the first substring with no spaces in it sscanf (optNamesValuesOrig, " %s ", optNamesValues); if (!strlen (optNamesValues)) { free (optNamesValues); return; } // Backup original, since strtok is destructive strcpy (optNamesValues, optNamesValuesOrig); char *nameTrimmed = (char *)calloc (len + 1, 1); char *valueStr = 0; const char *betweenPairs = ","; const char *betweenOptVal = "="; // Count number of pairs char *pairToken = (char *)optNamesValuesOrig; // TODO do with CompString unsigned int nPairs = 1; while ((pairToken = strchr (pairToken, betweenPairs[0]))) { ++pairToken; // skip delimiter ++nPairs; } os->pairs.clear (); os->pairs.reserve (nPairs); // Tokenize pairs char *name = strtok (optNamesValues, betweenOptVal); int errorNo = -1; unsigned int i; for (i = 0; name && i < nPairs; ++i) { errorNo = 0; if (strchr (name, betweenPairs[0])) // handle "a, b=4" case { errorNo = 1; break; } sscanf (name, " %s ", nameTrimmed); if (!strlen (nameTrimmed)) { errorNo = 2; break; } valueStr = strtok (0, betweenPairs); if (!valueStr) { errorNo = 3; break; } // TODO: Fix: Convert to "pluginname:option_name" format // Warning: Assumes that option names in different extension plugins // will be different. bool matched = false; const ExtensionPluginInfo *chosenExtensionPlugin = NULL; CompOption *o = 0; int optId = -1; unsigned int nOptions; foreach (ExtensionPluginInfo *extensionPlugin, mExtensionPlugins) { nOptions = extensionPlugin->effectOptions->size (); for (optId = (int)extensionPlugin->firstEffectOptionIndex; optId < (int)nOptions; ++optId) { o = &(*extensionPlugin->effectOptions)[(unsigned)optId]; if (strcasecmp (nameTrimmed, o->name ().c_str ()) == 0) { matched = true; chosenExtensionPlugin = extensionPlugin; break; } } if (matched) break; } if (!matched) { errorNo = 4; break; } CompOption::Value v; os->pairs.push_back (IdValuePair ()); IdValuePair *pair = &os->pairs[i]; pair->pluginInfo = chosenExtensionPlugin; pair->optionId = optId; int valueRead = -1; switch (o->type ()) { case CompOption::TypeBool: int vb; valueRead = sscanf (valueStr, " %d ", &vb); if (valueRead) pair->value.set ((bool)vb); break; case CompOption::TypeInt: { int vi; valueRead = sscanf (valueStr, " %d ", &vi); if (valueRead > 0) { if (o->rest ().inRange (vi)) { v.set (vi); pair->value = v; } else errorNo = 7; } break; } case CompOption::TypeFloat: { float vf; valueRead = sscanf (valueStr, " %f ", &vf); if (valueRead > 0) { if (o->rest ().inRange (vf)) { v.set (vf); pair->value = v; } else errorNo = 7; } break; } case CompOption::TypeString: { v.set (CompString (valueStr)); valueRead = 1; break; } case CompOption::TypeColor: { unsigned short vc[4]; valueRead = sscanf (valueStr, " #%2hx%2hx%2hx%2hx ", &vc[0], &vc[1], &vc[2], &vc[3]); if (valueRead == 4) { CompOption::Value *pairVal = &pair->value; for (int j = 0; j < 4; ++j) vc[j] = vc[j] << 8 | vc[j]; pairVal->set (vc); } else errorNo = 6; break; } default: break; } if (valueRead == 0) errorNo = 6; if (errorNo > 0) break; // If valueRead is -1 here, then it must be a // non-(int/float/string) option, which is not supported yet. // Such an option doesn't currently exist anyway. errorNo = -1; name = strtok (0, betweenOptVal); }