Exemple #1
0
void ConfigManager::flushToDisk() {
#ifndef __DC__
	WriteStream *stream;

	if (_filename.empty()) {
		// Write to the default config file
		assert(g_system);
		stream = g_system->createConfigWriteStream();
		if (!stream)    // If writing to the config file is not possible, do nothing
			return;
	} else {
		DumpFile *dump = new DumpFile();
		assert(dump);

		if (!dump->open(_filename)) {
			warning("Unable to write configuration file: %s", _filename.c_str());
			delete dump;
			return;
		}

		stream = dump;
	}

	// Write the application domain
	writeDomain(*stream, kApplicationDomain, _appDomain);

#ifdef ENABLE_KEYMAPPER
	// Write the keymapper domain
	writeDomain(*stream, kKeymapperDomain, _keymapperDomain);
#endif

	DomainMap::const_iterator d;

	// Write the miscellaneous domains next
	for (d = _miscDomains.begin(); d != _miscDomains.end(); ++d) {
		writeDomain(*stream, d->_key, d->_value);
	}

	// First write the domains in _domainSaveOrder, in that order.
	// Note: It's possible for _domainSaveOrder to list domains which
	// are not present anymore, so we validate each name.
	Array<String>::const_iterator i;
	for (i = _domainSaveOrder.begin(); i != _domainSaveOrder.end(); ++i) {
		if (_gameDomains.contains(*i)) {
			writeDomain(*stream, *i, _gameDomains[*i]);
		}
	}

	// Now write the domains which haven't been written yet
	for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) {
		if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), d->_key) == _domainSaveOrder.end())
			writeDomain(*stream, d->_key, d->_value);
	}

	delete stream;

#endif // !__DC__
}
void ConfigManager::flushToDisk() {
#ifndef __DC__
	FILE *cfg_file;

// TODO
//	if (!willwrite)
//		return;

	if (!(cfg_file = fopen(_filename.c_str(), "w"))) {
		warning("Unable to write configuration file: %s", _filename.c_str());
	} else {

		// First write the domains in _domainSaveOrder, in that order.
		// Note: It's possible for _domainSaveOrder to list domains which
		// are not present anymore.
		StringList::const_iterator i;
		for (i = _domainSaveOrder.begin(); i != _domainSaveOrder.end(); ++i) {
			if (kApplicationDomain == *i) {
				writeDomain(cfg_file, *i, _appDomain);
			} else if (_gameDomains.contains(*i)) {
				writeDomain(cfg_file, *i, _gameDomains[*i]);
			}
		}

		DomainMap::const_iterator d;

		// Now write the domains which haven't been written yet
		if (!_domainSaveOrder.contains(kApplicationDomain))
			writeDomain(cfg_file, kApplicationDomain, _appDomain);
		for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) {
			if (!_domainSaveOrder.contains(d->_key))
				writeDomain(cfg_file, d->_key, d->_value);
		}

		fclose(cfg_file);
	}
#endif // !__DC__
}
void writeEnumFast(std::ostream &t_os, const std::string &t_name, const Container &t_values)
{
  t_os <<
  "#ifdef SWIG " << std::endl <<
  "  OPENSTUDIO_ENUM(" << t_name << ", )" << std::endl <<
  "#else" << std::endl <<
  "class " << t_name << ": public ::EnumBase<" << t_name << "> {" << std::endl <<
  " public: " << std::endl;

  writeDomain(t_os, t_name, t_values, true);

  t_os <<
  "  " << t_name << "()" << std::endl <<
  "   : EnumBase<" << t_name << ">(" << t_values.front().first << ") {} " << std::endl <<
  "  " << t_name << "(const std::string &t_name) " << std::endl <<
  "   : EnumBase<" << t_name << ">(t_name) {} " << std::endl <<
  "  " << t_name << "(int t_value) " << std::endl <<
  "   : EnumBase<" << t_name << ">(t_value) {} " << std::endl <<
  "  static std::string enumName() " << std::endl <<
  "  { return \"" << t_name << "\"; }" << std::endl <<
  "  domain value() const { return static_cast<domain>(EnumBase<" << t_name << ">::value()); }" << std::endl <<
 
  "   private:" << std::endl <<
  "    friend class EnumBase<" << t_name << ">;" << std::endl <<
  "    typedef std::pair<std::string, int> PT;" << std::endl <<
  "    typedef std::vector<PT> VecType;" << std::endl;

  writeBuildStringVec(t_os, t_name, t_values, true);

  t_os <<
  "  " << std::endl <<
//  "    friend class boost::serialization::access;" << std::endl <<
 
//  "    template<class Archive> void serialize(Archive & ar, const unsigned int version)" << std::endl <<
//  "    {" << std::endl <<
//  "      ar & boost::serialization::make_nvp(\"value\", m_value);" << std::endl <<
//  "    }" << std::endl <<
  "  };" << std::endl <<
 
  "  inline std::ostream &operator<<(std::ostream &os, const " << t_name << " &e)" << std::endl <<
  "  {" << std::endl <<
  "    return os << e.valueName() << \"(\" << e.value() << \")\";" << std::endl <<
  "  }" << std::endl <<
 
  "  typedef boost::optional<" << t_name << "> Optional" << t_name << " ;" << std::endl <<
  "#endif";
}
void completeOutFiles(const IddFileFactoryDataVector& iddFiles,
                      GenerateIddFactoryOutFiles& outFiles) {


  std::vector<std::pair<std::string, std::string>> filetypes{ {"UserCustom", ""}, {"WholeFactory", ""} };
  for (const IddFileFactoryData& idd : iddFiles) {
    filetypes.emplace_back(idd.fileName(), "");
  }


  std::stringstream tempSS;
  writeDomain(tempSS, "IddFileType", filetypes, false);

  outFiles.iddEnumsHxx.tempFile
    << std::endl
    << "/** \\class IddFileType */" << std::endl
    << tempSS.str();
  tempSS.str("");

  std::vector<std::pair<std::string, std::string>> objtypes{ {"Catchall", ""}, {"UserCustom", ""} };

  // loop through each IDD file
  for (const IddFileFactoryData& idd : iddFiles) {
    // write out an IddObjectType enum value for each object in the IDD file
    for (const StringPair& objectName : idd.objectNames()) {
      objtypes.emplace_back(objectName.first, objectName.second);
    }
  }

  objtypes.emplace_back("CommentOnly", "");
  writeDomain(tempSS, "IddObjectType", objtypes, false);

  outFiles.iddEnumsHxx.tempFile
    << std::endl
    << "/** \\class IddObjectType */" << std::endl
    << tempSS.str()
    << std::endl
    << "}\n"
    << "#endif // UTILITIES_IDD_IDDENUMS_HXX" << std::endl;
  tempSS.str("");

  // complete and close IddFieldEnums.hxx
  outFiles.iddFieldEnumsHxx.tempFile
    << std::endl
    << "#endif // UTILITIES_IDD_IDDFIELDENUMS_HXX" << std::endl;

  // complete and close IddFieldEnums.ixx
  outFiles.iddFieldEnumsIxx.tempFile
    << std::endl
    << "#endif // UTILITIES_IDD_IDDFIELDENUMS_IXX" << std::endl;

  // complete and close IddFactory.cxx

  // create function for CommentOnly IddObject
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "IddObject createCommentOnlyIddObject() {" << std::endl
    << std::endl
    << "  static IddObject object;" << std::endl
    << std::endl
    << "  if (object.type() == IddObjectType::Catchall) {" << std::endl
    << "    std::stringstream ss;" << std::endl
    << "    ss << \"CommentOnly; ! Autogenerated comment only object.\" << std::endl;" << std::endl
    << std::endl
    << "    IddObjectType objType(IddObjectType::CommentOnly);" << std::endl
    << "    OptionalIddObject oObj = IddObject::load(\"CommentOnly\"," << std::endl
    << "                                             \"\"," << std::endl
    << "                                             ss.str()," << std::endl
    << "                                             objType);" << std::endl
    << "    OS_ASSERT(oObj);" << std::endl
    << "    object = *oObj;" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return object;" << std::endl
    << "}" << std::endl;

  // constructor
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "IddFactorySingleton::IddFactorySingleton() {" << std::endl
    << std::endl
    << "  // initialize callback map" << std::endl
    << std::endl;
  // register create functions in the callback map
  // Catchall
  outFiles.iddFactoryCxx.tempFile
    << "  m_callbackMap.insert(IddObjectCallbackMap::value_type(IddObjectType::Catchall,"
    << "createCatchallIddObject));" << std::endl;
  // parsed objects
  for (const IddFileFactoryData& idd : iddFiles) {
    outFiles.iddFactoryCxx.tempFile
      << "  register" << idd.fileName() << "ObjectsInCallbackMap();" << std::endl;
  }
  // CommentOnly
  outFiles.iddFactoryCxx.tempFile
    << "  m_callbackMap.insert(IddObjectCallbackMap::value_type(IddObjectType::CommentOnly,"
    << "createCommentOnlyIddObject));" << std::endl
    << std::endl
    << "  // instantiate IddObjectType to IddFileType multimap" << std::endl
    << std::endl;
  // register IddObjectTypes with IddFileTypes
  for (const IddFileFactoryData& idd : iddFiles) {
    std::string fileName = idd.fileName();

    // register local objects
    for (const StringPair& objectName : idd.objectNames()) {
      outFiles.iddFactoryCxx.tempFile
        << "  m_sourceFileMap.insert(IddObjectSourceFileMap::value_type(IddObjectType::"
        << objectName.first << ",IddFileType::" << fileName << "));" << std::endl;
    }

    // register imported objects
    for (unsigned i = 0, ni = idd.numIncludedFiles(); i < ni; ++i) {
      /* Included files are identified by name. Optionally, there may be a list of removed objects
         that should not be inherited by the composite file. */
      IddFileFactoryData::FileNameRemovedObjectsPair includedFileData = idd.includedFile(i);
      // Get the included file by name. Will throw if there is no match.
      IddFileFactoryData includedFile = getFile(includedFileData.first,iddFiles);

      std::vector<std::string> excludedObjects;
      for (const StringPair& objectName : includedFile.objectNames()) {

        // If objectName is in list of removed objects, do not add it to m_sourceFileMap,
        if (std::find(includedFileData.second.begin(),includedFileData.second.end(),objectName.first)
            != includedFileData.second.end()) {
          // and keep its name in case we need to write a warning.
          excludedObjects.push_back(objectName.first);
          continue;
        }

        // objectName is not to be removed, so add it to the composite file.
        outFiles.iddFactoryCxx.tempFile
          << "  m_sourceFileMap.insert(IddObjectSourceFileMap::value_type(IddObjectType::"
          << objectName.first << ",IddFileType::" << fileName << "));" << std::endl;

      } // foreach

      // Write warning if we did not encounter all of the objects that were to be removed.
      if (excludedObjects.size() != includedFileData.second.size()) {
        std::cout << "Warning: Did not encounter all 'objects to remove' while including file " << std::endl
                  << "'" << includedFileData.first << "' in file '" << fileName << "'." << std::endl
                  << "\\remove-object Tags      Objects Actually Removed " << std::endl
                  << "------------------------- -------------------------" << std::endl;
        for (int x = 0, y = 0, nx = includedFileData.second.size(), ny = excludedObjects.size();
             (x < nx) || (y < ny); ++x, ++y) {
          if (x < nx) { std::cout << std::setw(25) << includedFileData.second[x] << " "; }
          else { std::cout << std::setw(25) << " " << " "; }
          if (y < ny) { std::cout << std::setw(25)<< excludedObjects[y] << std::endl; }
          else { std::cout << std::setw(25) << " " << std::endl; }
        } // for
      } // if

    } // for

    // Register CommentOnly object for all files.
    outFiles.iddFactoryCxx.tempFile
        << "  m_sourceFileMap.insert(IddObjectSourceFileMap::value_type(IddObjectType::CommentOnly"
        << ",IddFileType::" << fileName << "));" << std::endl;
  }
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "}" << std::endl;

  // version and header getters
  outFiles.iddFactoryCxx.tempFile
      << std::endl
      << "std::string IddFactorySingleton::getVersion(IddFileType fileType) const {" << std::endl
      << "  std::string result;" << std::endl
      << std::endl
      << "  switch (fileType.value()) {" << std::endl;
  for (const IddFileFactoryData& idd : iddFiles) {
    outFiles.iddFactoryCxx.tempFile
        << "    case IddFileType::" << idd.fileName() << " :" << std::endl
        << "      result = \"" << idd.version() << "\";" << std::endl
        << "      break;" << std::endl;
  }
  outFiles.iddFactoryCxx.tempFile
      << "    default :" << std::endl
      << "      LOG_AND_THROW(\"No version to return for IddFileType \" << fileType.valueDescription() << \".\");" << std::endl
      << "  } // switch" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::string IddFactorySingleton::getHeader(IddFileType fileType) const {" << std::endl
      << "  std::stringstream result;" << std::endl
      << "  switch (fileType.value()) {" << std::endl;
  for (const IddFileFactoryData& idd : iddFiles) {
    outFiles.iddFactoryCxx.tempFile
        << "    case IddFileType::" << idd.fileName() << " :" << std::endl
        << "      result";
    std::stringstream headerStream(idd.header());
    std::string line;
    while (std::getline(headerStream,line)) {
      outFiles.iddFactoryCxx.tempFile
          << std::endl
          << "        << \"" << line << "\" << std::endl";
    }
    // print information about included files
    for (unsigned i = 0, ni = idd.numIncludedFiles(); i < ni; ++i) {
      IddFileFactoryData::FileNameRemovedObjectsPair includedFileData = idd.includedFile(i);
      IddFileFactoryData includedFile = getFile(includedFileData.first,iddFiles);
      outFiles.iddFactoryCxx.tempFile
        << std::endl
        << "        << \"!\\n\"" << std::endl
        << "        << \"! **************************************************************************\\n\"" << std::endl
        << "        << \"! Includes File: '" << includedFile.fileName() << "'\\n\"" << std::endl
        << "        << \"!\\n\"" << std::endl
        << "        << \"! Contains all objects from " << includedFile.fileName() << " IDD_Version " << includedFile.version() << ", except: \\n\"" << std::endl;
      for (const std::string& objectName : includedFileData.second) {
        outFiles.iddFactoryCxx.tempFile
          << "        << \"!   " << objectName << "\\n\"" << std::endl;
      }
      outFiles.iddFactoryCxx.tempFile
        << "        << \"! **************************************************************************\\n\"";
    }
    outFiles.iddFactoryCxx.tempFile
      << ";" << std::endl
      << std::endl
      << "      break;" << std::endl;
  }
 outFiles.iddFactoryCxx.tempFile
     << "    default :" << std::endl
     << "      LOG_AND_THROW(\"No header to return for IddFileType \" << fileType.valueDescription() << \".\");" << std::endl
     << "  } // switch" << std::endl
     << "  return result.str();" << std::endl
     << "}" << std::endl;

  // object getters
  outFiles.iddFactoryCxx.tempFile
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::objects() const {" << std::endl
      << "  IddObjectVector result;" << std::endl
      << std::endl
      << "  for (IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
      << "       itEnd = m_callbackMap.end(); it != itEnd; ++it) {" << std::endl
      << "    QMutexLocker l(&m_callbackmutex);" << std::endl
      << "    result.push_back(it->second());" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::getObjects(IddFileType fileType) const {" << std::endl
      << "  IddObjectVector result;" << std::endl
      << std::endl
      << "  for(IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
      << "      itend = m_callbackMap.end(); it != itend; ++it) {" << std::endl
      << "    if (isInFile(it->first,fileType)) { " << std::endl
      << "      // This lock is necessary to protect construction of the statics used in the callbacks " << std::endl
      << "      QMutexLocker l(&m_callbackmutex);" << std::endl
      << "      result.push_back(it->second()); " << std::endl
      << "    }" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<std::string> IddFactorySingleton::groups() const {" << std::endl
      << "  StringSet result;" << std::endl
      << "  for (const IddObject& object : objects()) {" << std::endl
      << "    result.insert(object.group());" << std::endl
      << "  }" << std::endl
      << "  return StringVector(result.begin(),result.end());" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<std::string> IddFactorySingleton::getGroups(IddFileType fileType) const {" << std::endl
      << "  StringSet result;" << std::endl
      << "  for (const IddObject& object : getObjects(fileType)) {" << std::endl
      << "    result.insert(object.group());" << std::endl
      << "  }" << std::endl
      << "  return StringVector(result.begin(),result.end());" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::getObjectsInGroup(const std::string& group) const {" << std::endl
      << "  IddObjectVector result;" << std::endl
      << "  for (const IddObject& object : objects()) {" << std::endl
      << "    if (istringEqual(object.group(),group)) {" << std::endl
      << "      result.push_back(object);" << std::endl
      << "    }" << std::endl
      << "  }" << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::getObjectsInGroup(const std::string& group, IddFileType fileType) const {" << std::endl
      << "  IddObjectVector result;" << std::endl
      << "  for (const IddObject& object : getObjects(fileType)) {" << std::endl
      << "    if (istringEqual(object.group(),group)) {" << std::endl
      << "      result.push_back(object);" << std::endl
      << "    }" << std::endl
      << "  }" << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::getObjects(const boost::regex& objectRegex) const {" << std::endl
      << "  IddObjectVector result;" << std::endl
      << std::endl
      << "  for (int value : IddObjectType::getValues()) {" << std::endl
      << "    IddObjectType candidate(value);" << std::endl
      << "    if (boost::regex_match(candidate.valueName(),objectRegex) || " << std::endl
      << "        boost::regex_match(candidate.valueDescription(),objectRegex))" << std::endl
      << "    {" << std::endl
      << "      if (OptionalIddObject object = getObject(candidate)) {" << std::endl
      << "        result.push_back(*object);" << std::endl
      << "      }" << std::endl
      << "    }" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "std::vector<IddObject> IddFactorySingleton::getObjects(const boost::regex& objectRegex," << std::endl
      << "                                                       IddFileType fileType) const " << std::endl
      << "{" << std::endl
      << "  IddObjectVector result;" << std::endl
      << std::endl
      << "  for (int value : IddObjectType::getValues()) {" << std::endl
      << "    IddObjectType candidate(value);" << std::endl
      << "    if (isInFile(candidate,fileType) && " << std::endl
      << "        (boost::regex_match(candidate.valueName(),objectRegex) || " << std::endl
      << "         boost::regex_match(candidate.valueDescription(),objectRegex)))" << std::endl
      << "    {" << std::endl
      << "      if (OptionalIddObject object = getObject(candidate)) {" << std::endl
      << "        result.push_back(*object);" << std::endl
      << "      }" << std::endl
      << "    }" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "IddObject IddFactorySingleton::getVersionObject(IddFileType fileType) const {" << std::endl
      << "  if (fileType == IddFileType::EnergyPlus) {" << std::endl
      << "    return getObject(IddObjectType(IddObjectType::Version)).get();" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  if (fileType == IddFileType::OpenStudio) {" << std::endl
      << "    return getObject(IddObjectType(IddObjectType::OS_Version)).get();" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  LOG_AND_THROW(\"Unable to identify unique version object for IddFileType \" << fileType.valueName() << \".\");" << std::endl
      << "  return IddObject();" << std::endl
      << "}" << std::endl
      << std::endl
      << "boost::optional<IddObject> IddFactorySingleton::getObject(const std::string& objectName) const" << std::endl
      << "{" << std::endl
      << "  OptionalIddObject result;" << std::endl
      << std::endl
      << "  // let IddObjectType OPENSTUDIO_ENUM handle the string processing" << std::endl
      << "  try {" << std::endl
      << "    IddObjectType objectType(objectName);" << std::endl
      << "    result = getObject(objectType);" << std::endl
      << "  }" << std::endl
      << "  catch (...) {}" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl
      << std::endl
      << "boost::optional<IddObject> IddFactorySingleton::getObject(IddObjectType objectType) const" << std::endl
      << "{" << std::endl
      << "  OptionalIddObject result;" << std::endl
      << std::endl
      << "  IddObjectCallbackMap::const_iterator lookupPair;" << std::endl
      << "  lookupPair = m_callbackMap.find(objectType);" << std::endl
      << "  if (lookupPair != m_callbackMap.end()) { " << std::endl
      << "    QMutexLocker l(&m_callbackmutex);" << std::endl
      << "    result = lookupPair->second(); " << std::endl
      << "  }" << std::endl
      << "  else { " << std::endl
      << "    OS_ASSERT(objectType == IddObjectType::UserCustom); " << std::endl
      << "    LOG(Info,\"UserCustom objects are not available through the IddFactory. Please query your IddFile by IddObject.name().\");" << std::endl
      << "  }" << std::endl
      << std::endl
      << "  return result;" << std::endl
      << "}" << std::endl;

  // required, unique, and required or unique objects
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "std::vector<IddObject> IddFactorySingleton::requiredObjects() const {" << std::endl
    << std::endl
    << "  IddObjectVector result;" << std::endl
    << std::endl
    << "  for (IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
    << "    itEnd = m_callbackMap.end(); it != itEnd; ++it) {" << std::endl
    << "    // This lock is necessary to protect construction of the statics used in the callbacks " << std::endl
    << "    QMutexLocker l(&m_callbackmutex);" << std::endl
    << "    IddObject candidate = it->second();" << std::endl
    << "    l.unlock(); " << std::endl
    << "    if (candidate.properties().required) {" << std::endl
    << "      result.push_back(candidate);" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return result;" << std::endl
    << "}" << std::endl
    << std::endl
    << "std::vector<IddObject> IddFactorySingleton::getRequiredObjects(IddFileType fileType) const {" << std::endl
    << std::endl
    << "  IddObjectVector result; " << std::endl
    << std::endl
    << "  for(IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
    << "      itEnd = m_callbackMap.end(); it != itEnd; ++it) {" << std::endl
    << "    if (isInFile(it->first,fileType)) {" << std::endl
    << "      OptionalIddObject candidate = getObject(it->first);" << std::endl
    << "      if (candidate->properties().required) {" << std::endl
    << "        result.push_back(*candidate);" << std::endl
    << "      }" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return result;" << std::endl
    << "}" << std::endl
    << std::endl
    << "std::vector<IddObject> IddFactorySingleton::uniqueObjects() const {" << std::endl
    << std::endl
    << "  IddObjectVector result;" << std::endl
    << std::endl
    << "  for (IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
    << "    itEnd = m_callbackMap.end(); it != itEnd; ++it) {" << std::endl
    << "    QMutexLocker l(&m_callbackmutex);" << std::endl
    << "    IddObject candidate = it->second();" << std::endl
    << "    l.unlock(); " << std::endl
    << "    if (candidate.properties().unique) {" << std::endl
    << "      result.push_back(candidate);" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return result;" << std::endl
    << "}" << std::endl
    << std::endl
    << "std::vector<IddObject> IddFactorySingleton::getUniqueObjects(IddFileType fileType) const {" << std::endl
    << std::endl
    << "  IddObjectVector result; " << std::endl
    << std::endl
    << "   for(IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
    << "      itEnd = m_callbackMap.end(); it != itEnd; ++it) {" << std::endl
    << "    if (isInFile(it->first,fileType)) {" << std::endl
    << "      OptionalIddObject candidate = getObject(it->first);" << std::endl
    << "      if (candidate->properties().unique) {" << std::endl
    << "        result.push_back(*candidate);" << std::endl
    << "      }" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return result;" << std::endl
    << std::endl
    << "}" << std::endl;

  // iddFile getters
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "IddFile IddFactorySingleton::getIddFile(IddFileType fileType) const {" << std::endl
    << "  IddFile result;" << std::endl
    << std::endl
    << "  if (fileType == IddFileType::UserCustom) {" << std::endl
    << "    return result; " << std::endl
    << "  }" << std::endl
    << std::endl
    << "  // Add the IddObjects." << std::endl
    << "  for(IddObjectCallbackMap::const_iterator it = m_callbackMap.begin()," << std::endl
    << "      itend = m_callbackMap.end(); it != itend; ++it) {" << std::endl
    << "    if (isInFile(it->first,fileType)) {" << std::endl
    << "      // This lock is necessary to protect construction of the statics used in the callbacks " << std::endl
    << "      QMutexLocker l(&m_callbackmutex);" << std::endl
    << "      result.addObject(it->second());" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  // Set the file version and header." << std::endl
    << "  try {" << std::endl
    << "    result.setVersion(getVersion(fileType));" << std::endl
    << "    result.setHeader(getHeader(fileType));" << std::endl
    << "  }" << std::endl
    << "  catch (...) {}" << std::endl
    << std::endl
    << "  return result;" << std::endl
    << "}" << std::endl
    << std::endl
    << "boost::optional<IddFile> IddFactorySingleton::getIddFile(IddFileType fileType, const VersionString& version) const {" << std::endl
    << "  OptionalIddFile result;" << std::endl
    << std::endl
    << "  if (fileType == IddFileType::UserCustom) {" << std::endl
    << "    return result; " << std::endl
    << "  }" << std::endl
    << std::endl
    << "  if (fileType == IddFileType::WholeFactory) {" << std::endl
    << "    LOG(Warn,\"Cannot return the WholeFactory IddFile by version.\");" << std::endl
    << "    return result;" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  if (fileType == IddFileType::EnergyPlus) {" << std::endl
    << "    LOG(Warn,\"At this time, OpenStudio cannot return EnergyPlus IDD files by version.\");" << std::endl
    << "    return result;" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  VersionString currentVersion(openStudioVersion());" << std::endl
    << "  OS_ASSERT(fileType == IddFileType::OpenStudio);" << std::endl
    << "  if (version == currentVersion) {" << std::endl
    << "    return getIddFile(fileType);" << std::endl
    << "  }" << std::endl
    << "  else {" << std::endl
    << "    std::map<VersionString, IddFile>::const_iterator it = m_osIddFiles.find(version);" << std::endl
    << "    if (it != m_osIddFiles.end()) {" << std::endl
    << "      return it->second;" << std::endl
    << "    }" << std::endl
    << "    std::string iddPath = \":/idd/versions\";" << std::endl
    << "    std::stringstream folderString;" << std::endl
    << "    folderString << version.major() << \"_\" << version.minor() << \"_\" << version.patch().get();" << std::endl
    << "    iddPath += \"/\" + folderString.str() + \"/OpenStudio.idd\";" << std::endl
    << "    if (::openstudio::embedded_files::hasFile(iddPath) && (version < currentVersion)) {" << std::endl
    << "      std::stringstream ss;" << std::endl
    << "      ss << ::openstudio::embedded_files::getFileAsString(iddPath);" << std::endl
    << "      result = IddFile::load(ss);" << std::endl
    << "    }" << std::endl
    << "    if (result) {" << std::endl
    << "      QMutexLocker l(&m_callbackmutex);" << std::endl
    << "      m_osIddFiles[version] = *result;" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << "  return result;" << std::endl
    << "}" << std::endl;

  // query whether object is in file
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "bool IddFactorySingleton::isInFile(IddObjectType objectType, IddFileType fileType) const {" << std::endl
    << "  typedef IddObjectSourceFileMap::const_iterator const_iterator;" << std::endl
    << "  std::pair<const_iterator,const_iterator> range;" << std::endl
    << "  range = m_sourceFileMap.equal_range(objectType);" << std::endl
    << "  for (const_iterator it = range.first; it != range.second; ++it) {" << std::endl
    << "    if ((it->second == fileType) || (fileType == IddFileType::WholeFactory)) {" << std::endl
    << "      return true;" << std::endl
    << "    }" << std::endl
    << "  }" << std::endl
    << std::endl
    << "  return false;" << std::endl
    << "}" << std::endl;

  // Implementation for IddObjectType and IddFileType
  writeBuildStringVec(outFiles.iddFactoryCxx.tempFile, "IddObjectType", objtypes, false);
  writeBuildStringVec(outFiles.iddFactoryCxx.tempFile, "IddFileType", filetypes, false);

  // close out file
  outFiles.iddFactoryCxx.tempFile
    << std::endl
    << "} // openstudio" << std::endl;

  // close out other IddFactory cxx files
  for (std::shared_ptr<IddFactoryOutFile>& cxxFile : outFiles.iddFactoryIddFileCxxs) {
    cxxFile->tempFile
      << std::endl
      << "} // openstudio" << std::endl;
  }

  outFiles.finalize();

  std::cout << "IddFactory files generated." << std::endl;
}