xml::Element& operator<<(xml::Element& elemDataTypes, const DataType& dataType) { std::string usedTypedef; dataTypeToString(usedTypedef, dataType, true); std::string nsName; dataTypeToString(nsName, dataType, false, true); std::string type; dataTypeToString(type, dataType); elemDataTypes.setValue(type); elemDataTypes.createElement("isConst", dataType.isConst); elemDataTypes.createElement("isRef", dataType.isRef); elemDataTypes.createElement("usedName", !dataType.usedName.empty() ? dataType.usedName : usedTypedef); elemDataTypes.createElement("name", dataType.name); elemDataTypes.createElement("nsName", nsName); elemDataTypes.createElement("ns", dataType.ns); elemDataTypes.createElement("type", typeToString(dataType.type)); elemDataTypes.createElement("usedTypedef", usedTypedef); xml::Element& elemTemplateParams = elemDataTypes.createElement("templateParams"); int num = 1; for(std::list<DataType>::const_iterator it = dataType.params.begin(); it != dataType.params.end(); ++it, ++num) elemTemplateParams.createElement("templateParam" + toString(num)) << *it; if (dataType.type == DataType::Type::Unknown) LogWarning() << "Unknown datatype: " << (dataType.ns + dataType.name); return elemDataTypes; }
bool dataTypeToString(std::string& out, const DataType& dataType, bool asUsed = false, bool noModifiers = false) { if (!noModifiers && dataType.isConst) out += "const "; if (!noModifiers && !dataType.prefix.empty()) out += dataType.prefix + " "; if (asUsed && !dataType.usedName.empty()) { out += dataType.usedName; } else { out += dataType.ns; if (!dataType.ownerName.empty()) out += dataType.ownerName + "::"; out += dataType.name; } bool bIsTemplate = !dataType.params.empty(); if (!bIsTemplate) { if (!noModifiers) { out += (dataType.isRef ? "&" : ""); } return false; } out += "<"; std::string::size_type beginTemplatePos = out.size(); bool space = !dataType.params.back().params.empty(); bool first = true; for (std::list<DataType>::const_iterator it = dataType.params.begin(); it != dataType.params.end(); ++it) { if (!first) out += ", "; bIsTemplate = dataTypeToString(out, *it, asUsed); if (first) { if (out.substr(beginTemplatePos, 2) == "::") space = true; first = false; } } if (space) { // first parameter begins with :: or last parameter was template: insert spaces out.insert(beginTemplatePos, " "); out += ' '; } out += ">"; if (!noModifiers) out += (dataType.isRef ? "&" : ""); return true; }
void AnimationTrack::saveToXML(TiXmlElement *xmlNodeTrack) { xmlNodeTrack->SetAttribute("name",m_name.c_str()); stringc dataType; dataTypeToString(m_dataType, dataType); xmlNodeTrack->SetAttribute("dataType",dataType); s32 kfNum = (s32)m_keyFrames.size(); //save times TiXmlElement * timesNode = new TiXmlElement( "times" ); xmlNodeTrack->LinkEndChild( timesNode ); stringc tempStr; char tempBuf[256]; for(s32 i=0; i<kfNum; ++i) { f32 time = m_keyFrames[i]->getTime(); if(i!=kfNum-1) sprintf(tempBuf,"%.3f,",time); else sprintf(tempBuf,"%.3f",time); tempStr.append(tempBuf); } timesNode->LinkEndChild(new TiXmlText(tempStr)); //save kf datas TiXmlElement * kfsNode = new TiXmlElement( "keyframes" ); xmlNodeTrack->LinkEndChild( kfsNode ); tempStr.clear(); for(int i=0; i<kfNum; ++i) { m_keyFrames[i]->valueToString(tempBuf,i==kfNum-1); tempStr.append(tempBuf); } kfsNode->LinkEndChild(new TiXmlText(tempStr)); //save interp datas (per frame) TiXmlElement *interpsNode = new TiXmlElement("interps"); xmlNodeTrack->LinkEndChild( interpsNode ); tempStr.clear(); for(int i=0; i<kfNum; ++i) { m_keyFrames[i]->interpTypeToString(tempBuf,i==kfNum-1); tempStr.append(tempBuf); } interpsNode->LinkEndChild(new TiXmlText(tempStr)); }
void writeParam(xml::Element& elemParams, xml::Element& elemParam, const Param& param) { elemParam.createElement("name", param.name); elemParam.createElement("description", param.description); elemParam.createElement("details", param.details); xml::Element& elemOptions = elemParam.createElement("options"); for (StringMap::const_iterator itOption = param.options.begin(); itOption != param.options.end(); ++itOption) elemOptions.createElement(itOption->first, itOption->second); elemParam.createElement("dataType") << param.dataType; std::string value = elemParams.getValue(); if (!value.empty()) value += ", "; dataTypeToString(value, param.dataType, true); value += " " + param.name; elemParams.setValue(value); }
void KnobSerialization::encode(YAML::Emitter& em) const { if (!_mustSerialize || _values.empty()) { return; } em << YAML::BeginMap; em << YAML::Key << "Name" << YAML::Value << _scriptName; // Instead of inserting in the map each boolean // we serialize strings, meaning that // if they are here, their value is true otherwise it goes to default std::list<std::string> propNames; int nDimsToSerialize = 0; int nDimsWithValue = 0; int nDimsWithDefValue = 0; for (PerViewValueSerializationMap::const_iterator it = _values.begin(); it != _values.end(); ++it) { for (PerDimensionValueSerializationVec::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { if (it2->_mustSerialize && _isPersistent) { ++nDimsToSerialize; if (it2->_serializeValue || !it2->_animationCurve.keys.empty() || it2->_slaveMasterLink.hasLink || !it2->_expression.empty()) { ++nDimsWithValue; } } } } for (std::size_t i = 0; i < _defaultValues.size(); ++i) { if (_defaultValues[i].serializeDefaultValue) { ++nDimsWithDefValue; } } if (nDimsToSerialize > 0) { // We serialize a value, we need to know which type of knob this is because at the time of deserialization the // application may not have created the corresponding knob already and may not know to what type it corresponds if (nDimsWithValue > 0) { em << YAML::Key; em << dataTypeToString(_dataType); em << YAML::Value; if (_values.size() > 1) { // Map against views em << YAML::BeginMap; } for (PerViewValueSerializationMap::const_iterator it = _values.begin(); it != _values.end(); ++it) { if (_values.size() > 1) { em << YAML::Key << it->first << YAML::Value; } // Starting dimensions, make a sequence if multiple dimensions are serialized if (it->second.size() > 1) { em << YAML::Flow << YAML::BeginSeq; } for (PerDimensionValueSerializationVec::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) { const ValueSerialization& val = *it2; if (val._slaveMasterLink.hasLink) { // Wrap the link in a sequence of 1 element to distinguish with regular string knobs values em << YAML::Flow << YAML::BeginMap; std::stringstream ss; // Encode the hard-link into a single string if (!val._slaveMasterLink.masterNodeName.empty()) { em << YAML::Key << "N"; em << YAML::Value << val._slaveMasterLink.masterNodeName; } if (!val._slaveMasterLink.masterTableItemName.empty()) { em << YAML::Key << "T"; em << YAML::Value << val._slaveMasterLink.masterTableItemName; } if (!val._slaveMasterLink.masterKnobName.empty()) { em << YAML::Key << "K"; em << YAML::Value << val._slaveMasterLink.masterKnobName; } if (!val._slaveMasterLink.masterDimensionName.empty()) { em << YAML::Key << "D"; em << YAML::Value << val._slaveMasterLink.masterDimensionName; } if (!val._slaveMasterLink.masterViewName.empty()) { em << YAML::Key << "V"; em << YAML::Value << val._slaveMasterLink.masterViewName; } // Also serialize the curve in case the expression fails to restore correctly if (!val._animationCurve.keys.empty()) { em << YAML::Key << "Curve" << YAML::Value; val._animationCurve.encode(em); } em << YAML::EndMap; } else if (!val._expression.empty()) { // Wrap the expression in a sequence of 1 element to distinguish with regular string knobs values em << YAML::Flow << YAML::BeginMap; if (val._expressionLanguage == kKnobSerializationExpressionLanguagePython) { if (val._expresionHasReturnVariable) { // Multi-line expr em << YAML::Key << "pyMultiExpr"; } else { // single line expr em << YAML::Key << "pyExpr"; } } else if (val._expressionLanguage == kKnobSerializationExpressionLanguageExprtk) { em << YAML::Key << "exprtk"; } else { // Unknown language assert(false); } em << YAML::Value << val._expression; // Also serialize the curve in case the expression fails to restore correctly if (!val._animationCurve.keys.empty()) { em << YAML::Key << "Curve" << YAML::Value; val._animationCurve.encode(em); } em << YAML::EndMap; } else if (!val._animationCurve.keys.empty()) { em << YAML::Flow << YAML::BeginMap; em << YAML::Key << "Curve" << YAML::Value; val._animationCurve.encode(em); em << YAML::EndMap; } else { // No animation or link, directly write the value without a map // This is the general case so we keep it tight assert(_dataType != eSerializationValueVariantTypeNone); switch (_dataType) { case eSerializationValueVariantTypeBoolean: em << val._value.isBool; break; case eSerializationValueVariantTypeInteger: em << val._value.isInt; break; case eSerializationValueVariantTypeDouble: em << val._value.isDouble; break; case eSerializationValueVariantTypeString: em << val._value.isString; break; case eSerializationValueVariantTypeTable: { em << YAML::BeginSeq; for (std::list<std::vector<std::string> >::const_iterator it3 = val._value.isTable.begin(); it3 != val._value.isTable.end(); ++it3) { if (it3->size() > 1) { em << YAML::Flow << YAML::BeginSeq; for (std::vector<std::string>::const_iterator it4 = it3->begin(); it4 != it3->end(); ++it4) { em << *it4; } em << YAML::EndSeq; } else if (it3->size() == 1) { em << it3->front(); } } em << YAML::EndSeq; } break; case eSerializationValueVariantTypeNone: break; } } } // for each dimension if (it->second.size() > 1) { em << YAML::EndSeq; } } // for each view if (_values.size() > 1) { em << YAML::EndMap; } } // nDimsWithValue > 0 if (nDimsWithDefValue > 0) { { em << YAML::Key; std::string defaultKey("Default"); defaultKey += dataTypeToString(_dataType); em << defaultKey; em << YAML::Value; } // Starting dimensions if (_defaultValues.size() > 1) { em << YAML::Flow << YAML::BeginSeq; } for (std::size_t i = 0; i < _defaultValues.size(); ++i) { switch (_dataType) { case eSerializationValueVariantTypeBoolean: em << _defaultValues[i].value.isBool; break; case eSerializationValueVariantTypeInteger: em << _defaultValues[i].value.isInt; break; case eSerializationValueVariantTypeDouble: em << _defaultValues[i].value.isDouble; break; case eSerializationValueVariantTypeString: em << _defaultValues[i].value.isString; break; case eSerializationValueVariantTypeTable: { em << YAML::Flow << YAML::BeginSeq; for (std::list<std::vector<std::string> >::const_iterator it3 = _defaultValues[i].value.isTable.begin(); it3 != _defaultValues[i].value.isTable.end(); ++it3) { if (it3->size() > 1) { em << YAML::Flow << YAML::BeginSeq; for (std::vector<std::string>::const_iterator it4 = it3->begin(); it4 != it3->end(); ++it4) { em << *it4; } em << YAML::EndSeq; } else if (it3->size() == 1) { em << it3->front(); } } em << YAML::EndSeq; } break; case eSerializationValueVariantTypeNone: break; } } // for all dimensions if (_defaultValues.size() > 1) { em << YAML::EndSeq; } } // nDimsWithDefValue > 0 } // nDimsToSerialize > 0 TextExtraData* textData = dynamic_cast<TextExtraData*>(_extraData.get()); if (_extraData && _isPersistent) { ParametricExtraData* parametricData = dynamic_cast<ParametricExtraData*>(_extraData.get()); if (parametricData) { if (!parametricData->parametricCurves.empty()) { em << YAML::Key << "ParametricCurves" << YAML::Value; if (parametricData->parametricCurves.size() > 1) { // Multi-view em << YAML::BeginMap; } for (std::map<std::string,std::list<CurveSerialization> >::const_iterator it = parametricData->parametricCurves.begin(); it!= parametricData->parametricCurves.end(); ++it) { if (parametricData->parametricCurves.size() > 1) { // Multi-view em << YAML::Key << it->first << YAML::Value; } em << YAML::BeginSeq; for (std::list<CurveSerialization>::const_iterator it2 = it->second.begin(); it2!=it->second.end(); ++it2) { it2->encode(em); } em << YAML::EndSeq; } if (parametricData->parametricCurves.size() > 1) { // Multi-view em << YAML::EndMap; } } } else if (textData) { if (!textData->keyframes.empty()) { bool hasDeclaredTextAnim = false; for (std::map<std::string,std::map<double, std::string> >::const_iterator it = textData->keyframes.begin(); it != textData->keyframes.end(); ++it) { if (it->second.empty()) { continue; } if (!hasDeclaredTextAnim) { hasDeclaredTextAnim = true; em << YAML::Key << "TextAnim" << YAML::Value; if (textData->keyframes.size() > 1) { // Multi-view: start a map em << YAML::BeginMap; } } if (textData->keyframes.size() > 1) { em << YAML::Key << it->first << YAML::Value; } em << YAML::Flow; em << YAML::BeginSeq; for (std::map<double, std::string>::const_iterator it2 = it->second.begin(); it2!=it->second.end(); ++it2) { em << it2->first << it2->second; } em << YAML::EndSeq; } if (hasDeclaredTextAnim && textData->keyframes.size() > 1) { em << YAML::EndMap; } } if (std::abs(textData->fontColor[0] - 0.) > 0.01 || std::abs(textData->fontColor[1] - 0.) > 0.01 || std::abs(textData->fontColor[2] - 0.) > 0.01) { em << YAML::Key << "FontColor" << YAML::Value << YAML::Flow << YAML::BeginSeq << textData->fontColor[0] << textData->fontColor[1] << textData->fontColor[2] << YAML::EndSeq; } if (textData->fontSize != kKnobStringDefaultFontSize) { em << YAML::Key << "FontSize" << YAML::Value << textData->fontSize; } if (textData->fontFamily != NATRON_FONT) { em << YAML::Key << "Font" << YAML::Value << textData->fontFamily; } if (textData->italicActivated) { propNames.push_back("Italic"); } if (textData->boldActivated) { propNames.push_back("Bold"); } } } if (_isUserKnob) { // Num of dimensions can be figured out for knobs created by plug-in // Knobs created by user need to know it em << YAML::Key << "NDims" << YAML::Value << _dimension; em << YAML::Key << "TypeName" << YAML::Value << _typeName; if (_label != _scriptName) { em << YAML::Key << "Label" << YAML::Value << _label; } if (!_tooltip.empty()) { em << YAML::Key << "Hint" << YAML::Value << _tooltip; } if (_isSecret) { propNames.push_back("Secret"); } if (_disabled) { propNames.push_back("Disabled"); } if (!_triggerNewLine) { propNames.push_back("NoNewLine"); } if (!_evaluatesOnChange) { propNames.push_back("NoEval"); } if (_animatesChanged) { propNames.push_back("AnimatesChanged"); } if (!_isPersistent) { propNames.push_back("Volatile"); } if (!_iconFilePath[0].empty()) { em << YAML::Key << "UncheckedIcon" << YAML::Value << _iconFilePath[0]; } if (!_iconFilePath[1].empty()) { em << YAML::Key << "CheckedIcon" << YAML::Value << _iconFilePath[1]; } ChoiceExtraData* cdata = dynamic_cast<ChoiceExtraData*>(_extraData.get()); ValueExtraData* vdata = dynamic_cast<ValueExtraData*>(_extraData.get()); TextExtraData* tdata = dynamic_cast<TextExtraData*>(_extraData.get()); FileExtraData* fdata = dynamic_cast<FileExtraData*>(_extraData.get()); PathExtraData* pdata = dynamic_cast<PathExtraData*>(_extraData.get()); if (cdata) { if (!cdata->_entries.empty()) { em << YAML::Key << "Entries" << YAML::Value; em << YAML::Flow << YAML::BeginSeq; for (std::size_t i = 0; i < cdata->_entries.size(); ++i) { em << cdata->_entries[i]; } em << YAML::EndSeq; } if (!cdata->_helpStrings.empty()) { bool hasHelp = false; for (std::size_t i = 0; i < cdata->_helpStrings.size(); ++i) { if (!cdata->_helpStrings[i].empty()) { hasHelp = true; break; } } if (hasHelp) { em << YAML::Key << "Hints" << YAML::Value; em << YAML::Flow << YAML::BeginSeq; for (std::size_t i = 0; i < cdata->_helpStrings.size(); ++i) { em << cdata->_helpStrings[i]; } em << YAML::EndSeq; } } } else if (vdata) { if (vdata->min != INT_MIN && vdata->min != -DBL_MAX) { em << YAML::Key << "Min" << YAML::Value << vdata->min; } if (vdata->min != INT_MAX && vdata->min != DBL_MAX) { em << YAML::Key << "Max" << YAML::Value << vdata->max; } if (vdata->min != INT_MIN && vdata->min != -DBL_MAX) { em << YAML::Key << "DisplayMin" << YAML::Value << vdata->dmin; } if (vdata->min != INT_MAX && vdata->min != DBL_MAX) { em << YAML::Key << "DisplayMax" << YAML::Value << vdata->dmax; } } else if (tdata) { if (tdata->label) { propNames.push_back("IsLabel"); } if (tdata->multiLine) { propNames.push_back("MultiLine"); } if (tdata->richText) { propNames.push_back("RichText"); } } else if (pdata) { if (pdata->multiPath) { propNames.push_back("MultiPath"); } } else if (fdata) { if (fdata->useSequences) { propNames.push_back("Sequences"); } if (fdata->useExistingFiles) { propNames.push_back("ExistingFiles"); } if (!fdata->filters.empty()) { em << YAML::Key << "FileTypes" << YAML::Value << YAML::Flow << YAML::BeginSeq; for (std::size_t i = 0; i < fdata->filters.size(); ++i) { em << fdata->filters[i]; } em << YAML::EndSeq; } } } // if (_isUserKnob) { if (_hasViewerInterface) { if (!_inViewerContextItemLayout.empty() && _inViewerContextItemLayout != kInViewerContextItemLayoutSpacing) { em << YAML::Key << "InViewerLayout" << YAML::Value << _inViewerContextItemLayout; } else { if (_inViewerContextItemSpacing != kKnobInViewerContextDefaultItemSpacing) { em << YAML::Key << "InViewerSpacing" << YAML::Value << _inViewerContextItemSpacing; } } if (_isUserKnob) { if (!_inViewerContextLabel.empty()) { em << YAML::Key << "InViewerLabel" << YAML::Value << _inViewerContextLabel; } if (!_inViewerContextIconFilePath[0].empty()) { em << YAML::Key << "InViewerIconUnchecked" << YAML::Value << _inViewerContextIconFilePath[0]; } if (!_inViewerContextIconFilePath[1].empty()) { em << YAML::Key << "InViewerIconChecked" << YAML::Value << _inViewerContextIconFilePath[1]; } } } if (!propNames.empty()) { em << YAML::Key << "Props" << YAML::Value << YAML::Flow << YAML::BeginSeq; for (std::list<std::string>::const_iterator it2 = propNames.begin(); it2 != propNames.end(); ++it2) { em << *it2; } em << YAML::EndSeq; } em << YAML::EndMap; } // KnobSerialization::encode
//! returns column's datatype as human readable wxString. wxString Domain::getDatatypeAsString() { ensurePropertiesLoaded(); return dataTypeToString(datatypeM, scaleM, precisionM, subtypeM, lengthM); }