void EClassManager::parseFile(const std::string& filename) { const std::string fullname = "def/" + filename; ArchiveTextFilePtr file = GlobalFileSystem().openTextFile(fullname); if (file == NULL) return; try { // Parse entity defs from the file parse(file->getInputStream(), file->getModName()); } catch (parser::ParseException& e) { rError() << "[eclassmgr] failed to parse " << filename << " (" << e.what() << ")" << std::endl; } }
void ParticlesManager::saveParticleDef(const std::string& particleName) { ParticleDefMap::const_iterator found = _particleDefs.find(particleName); if (found == _particleDefs.end()) { throw std::runtime_error(_("Cannot save particle, it has not been registered yet.")); } ParticleDefPtr particle = found->second; std::string relativePath = PARTICLES_DIR + particle->getFilename(); fs::path particlesModPath = GlobalGameManager().getModPath(); particlesModPath /= PARTICLES_DIR; // Ensure the particles folder exists fs::create_directories(particlesModPath); fs::path targetFile = particlesModPath / particle->getFilename(); // If the file doesn't exist yet, let's check if we need to inherit stuff first from the VFS if (!fs::exists(targetFile)) { ArchiveTextFilePtr inheritFile = GlobalFileSystem().openTextFile(relativePath); if (inheritFile != NULL) { // There is a file with that name already in the VFS, copy it to the target file TextInputStream& inheritStream = inheritFile->getInputStream(); std::ofstream outFile(targetFile.string().c_str()); if (!outFile.is_open()) { throw std::runtime_error( (boost::format(_("Cannot open file for writing: %s")) % targetFile.string()).str()); } char buf[16384]; std::size_t bytesRead = inheritStream.read(buf, sizeof(buf)); while (bytesRead > 0) { outFile.write(buf, bytesRead); bytesRead = inheritStream.read(buf, sizeof(buf)); } outFile.close(); } } // Open a temporary file fs::path tempFile = targetFile; tempFile.remove_filename(); tempFile /= "_" + os::filename_from_path(targetFile); std::ofstream tempStream(tempFile.string().c_str()); if (!tempStream.is_open()) { throw std::runtime_error( (boost::format(_("Cannot open file for writing: %s")) % tempFile.string()).str()); } std::string tempString; // If a previous file exists, open it for reading and filter out the particle def we'll be writing if (fs::exists(targetFile)) { std::ifstream inheritStream(targetFile.string().c_str()); if (!inheritStream.is_open()) { throw std::runtime_error( (boost::format(_("Cannot open file for reading: %s")) % targetFile.string()).str()); } // Write the file to the output stream, up to the point the particle def should be written to stripParticleDefFromStream(inheritStream, tempStream, particleName); if (inheritStream.eof()) { // Particle def was not found in the inherited stream, write our comment tempStream << std::endl << std::endl; writeParticleCommentHeader(tempStream); } // We're at the insertion point (which might as well be EOF of the inheritStream) // Write the particle declaration tempStream << *particle << std::endl; tempStream << inheritStream.rdbuf(); inheritStream.close(); } else { // Just put the particle def into the file and that's it, leave a comment at the head of the decl writeParticleCommentHeader(tempStream); // Write the particle declaration tempStream << *particle << std::endl; } tempStream.close(); // Move the temporary stream over the actual file, removing the target first if (fs::exists(targetFile)) { try { fs::remove(targetFile); } catch (fs::filesystem_error& e) { rError() << "Could not remove the file " << targetFile.string() << std::endl << e.what() << std::endl; throw std::runtime_error( (boost::format(_("Could not remove the file %s")) % targetFile.string()).str()); } } try { fs::rename(tempFile, targetFile); } catch (fs::filesystem_error& e) { rError() << "Could not rename the temporary file " << tempFile.string() << std::endl << e.what() << std::endl; throw std::runtime_error( (boost::format(_("Could not rename the temporary file %s")) % tempFile.string()).str()); } }