From d1a3727fb4ae6231397249277ed833d52516cc9c Mon Sep 17 00:00:00 2001 From: codereader Date: Sat, 28 Nov 2020 04:17:46 +0100 Subject: [PATCH] #5108: Move implementation to .cpp file, remove migrated code from MapResource class. --- radiantcore/Makefile.am | 1 + radiantcore/map/MapResource.cpp | 111 --------------------- radiantcore/map/MapResource.h | 7 -- radiantcore/map/MapResourceLoader.cpp | 86 ++++++++++++++++ radiantcore/map/MapResourceLoader.h | 88 +++------------- tools/msvc/DarkRadiantCore.vcxproj | 1 + tools/msvc/DarkRadiantCore.vcxproj.filters | 3 + 7 files changed, 103 insertions(+), 194 deletions(-) create mode 100644 radiantcore/map/MapResourceLoader.cpp diff --git a/radiantcore/Makefile.am b/radiantcore/Makefile.am index 5037cc1a7f..81a8d143e8 100644 --- a/radiantcore/Makefile.am +++ b/radiantcore/Makefile.am @@ -155,6 +155,7 @@ libradiantcore_la_SOURCES = Radiant.cpp \ map/MapPositionManager.cpp \ map/MapPropertyInfoFileModule.cpp \ map/MapResource.cpp \ + map/MapResourceLoader.cpp \ map/MapResourceManager.cpp \ map/PointFile.cpp \ map/RegionManager.cpp \ diff --git a/radiantcore/map/MapResource.cpp b/radiantcore/map/MapResource.cpp index 836b9f44d5..ff5e21be8d 100644 --- a/radiantcore/map/MapResource.cpp +++ b/radiantcore/map/MapResource.cpp @@ -318,117 +318,6 @@ RootNodePtr MapResource::loadMapNode() return rootNode; } -RootNodePtr MapResource::loadMapNodeFromStream(std::istream& stream, const std::string& fullpath) -{ - // Get the mapformat - auto format = map::algorithm::determineMapFormat(stream, _extension); - - if (!format) - { - throw OperationException(fmt::format(_("Could not determine map format of file:\n{0}"), fullpath)); - } - - // Create a new map root node - auto root = std::make_shared(_name); - - if (loadFile(stream, *format, root, fullpath)) - { - return root; - } - - return RootNodePtr(); -} - -bool MapResource::loadFile(std::istream& mapStream, const MapFormat& format, const RootNodePtr& root, const std::string& filename) -{ - try - { - // Our importer taking care of scene insertion - MapImporter importFilter(root, mapStream); - - // Acquire a map reader/parser - IMapReaderPtr reader = format.getMapReader(importFilter); - - rMessage() << "Using " << format.getMapFormatName() << " format to load the data." << std::endl; - - // Start parsing - reader->readFromStream(mapStream); - - // Prepare child primitives - scene::addOriginToChildPrimitives(root); - - if (!format.allowInfoFileCreation()) - { - // No info file handling, just return success - return true; - } - - // Check for an additional info file - loadInfoFile(root, filename, importFilter.getNodeMap()); - - return true; - } - catch (map::FileOperation::OperationCancelled&) - { - // Clear out the root node, otherwise we end up with half a map - scene::NodeRemover remover; - root->traverseChildren(remover); - - throw OperationException(_("Map loading cancelled")); - } - catch (IMapReader::FailureException& e) - { - // Clear out the root node, otherwise we end up with half a map - scene::NodeRemover remover; - root->traverseChildren(remover); - - throw OperationException( - fmt::format(_("Failure reading map file:\n{0}\n\n{1}"), filename, e.what())); - } -} - -void MapResource::loadInfoFile(const RootNodePtr& root, const std::string& filename, const NodeIndexMap& nodeMap) -{ - try - { - std::string infoFilename(filename.substr(0, filename.rfind('.'))); - infoFilename += getInfoFileExtension(); - - openFileStream(infoFilename, [&](std::istream& infoFileStream) - { - loadInfoFileFromStream(infoFileStream, root, nodeMap); - }); - } - catch (std::runtime_error& ex) - { - rWarning() << ex.what() << std::endl; - } -} - -void MapResource::loadInfoFileFromStream(std::istream& infoFileStream, const RootNodePtr& root, const NodeIndexMap& nodeMap) -{ - if (!infoFileStream.good()) - { - rError() << "[MapResource] No valid info file stream" << std::endl; - return; - } - - rMessage() << "Parsing info file..." << std::endl; - - try - { - // Read the infofile - InfoFile infoFile(infoFileStream, root, nodeMap); - - // Start parsing, this will throw if any errors occur - infoFile.parse(); - } - catch (parser::ParseException& e) - { - rError() << "[MapResource] Unable to parse info file: " << e.what() << std::endl; - } -} - void MapResource::openFileStream(const std::string& path, const std::function& streamProcessor) { if (path_is_absolute(path.c_str())) diff --git a/radiantcore/map/MapResource.h b/radiantcore/map/MapResource.h index 98a5bcb159..f4d35bf9ec 100644 --- a/radiantcore/map/MapResource.h +++ b/radiantcore/map/MapResource.h @@ -60,16 +60,9 @@ class MapResource : bool saveBackup(); RootNodePtr loadMapNode(); - RootNodePtr loadMapNodeFromStream(std::istream& stream, const std::string& fullPath); void connectMap(); - bool loadFile(std::istream& mapStream, const MapFormat& format, - const RootNodePtr& root, const std::string& filename); - - void loadInfoFile(const RootNodePtr& root, const std::string& filename, const NodeIndexMap& nodeMap); - void loadInfoFileFromStream(std::istream& infoFileStream, const RootNodePtr& root, const NodeIndexMap& nodeMap); - // Opens a stream for the given path, which might be VFS path or an absolute one. The streamProcessor // function is then called with the opened stream. Throws std::runtime_error on stream open failure. void openFileStream(const std::string& path, const std::function& streamProcessor); diff --git a/radiantcore/map/MapResourceLoader.cpp b/radiantcore/map/MapResourceLoader.cpp new file mode 100644 index 0000000000..283c2be6bd --- /dev/null +++ b/radiantcore/map/MapResourceLoader.cpp @@ -0,0 +1,86 @@ +#include "MapResourceLoader.h" + +#include "fmt/format.h" +#include "scene/ChildPrimitives.h" +#include "scenelib.h" +#include "algorithm/MapImporter.h" +#include "messages/MapFileOperation.h" + +namespace map +{ + +MapResourceLoader::MapResourceLoader(std::istream& stream, const MapFormat& format) : + _stream(stream), + _format(format) +{} + +RootNodePtr MapResourceLoader::load() +{ + // Create a new map root node + auto root = std::make_shared(""); + + try + { + // Our importer taking care of scene insertion + MapImporter importFilter(root, _stream); + + // Acquire a map reader/parser + IMapReaderPtr reader = _format.getMapReader(importFilter); + + rMessage() << "Using " << _format.getMapFormatName() << " format to load the data." << std::endl; + + // Start parsing + reader->readFromStream(_stream); + + // Prepare child primitives + scene::addOriginToChildPrimitives(root); + + // Move the index mapping to this class before destroying the import filter + _indexMapping.swap(importFilter.getNodeMap()); + + return root; + } + catch (FileOperation::OperationCancelled&) + { + // Clear out the root node, otherwise we end up with half a map + scene::NodeRemover remover; + root->traverseChildren(remover); + + throw; // leak this exception + } + catch (IMapReader::FailureException& e) + { + // Clear out the root node, otherwise we end up with half a map + scene::NodeRemover remover; + root->traverseChildren(remover); + + // Convert the exception, pass the same message + throw IMapResource::OperationException(e.what()); + } +} + +void MapResourceLoader::loadInfoFile(std::istream& stream, const RootNodePtr& root) +{ + if (!stream.good()) + { + rError() << "[MapResource] No valid info file stream" << std::endl; + return; + } + + rMessage() << "Parsing info file..." << std::endl; + + try + { + // Read the infofile + InfoFile infoFile(stream, root, _indexMapping); + + // Start parsing, this will throw if any errors occur + infoFile.parse(); + } + catch (parser::ParseException& e) + { + rError() << "[MapResource] Unable to parse info file: " << e.what() << std::endl; + } +} + +} diff --git a/radiantcore/map/MapResourceLoader.h b/radiantcore/map/MapResourceLoader.h index baa8d8b7a6..220ee7074b 100644 --- a/radiantcore/map/MapResourceLoader.h +++ b/radiantcore/map/MapResourceLoader.h @@ -1,16 +1,13 @@ #pragma once #include + #include "imapresource.h" #include "itextstream.h" #include "imapformat.h" -#include "fmt/format.h" -#include "scene/ChildPrimitives.h" -#include "scenelib.h" - -#include "algorithm/MapImporter.h" #include "infofile/InfoFile.h" +#include "RootNode.h" namespace map { @@ -25,82 +22,21 @@ class MapResourceLoader std::istream& _stream; const MapFormat& _format; + // Maps entity,primitive indices to nodes, used in infofile parsing code NodeIndexMap _indexMapping; public: - MapResourceLoader(std::istream& stream, const MapFormat& format) : - _stream(stream), - _format(format) - {} - - RootNodePtr load() - { - // Create a new map root node - auto root = std::make_shared(""); - - try - { - // Our importer taking care of scene insertion - MapImporter importFilter(root, _stream); - - // Acquire a map reader/parser - IMapReaderPtr reader = _format.getMapReader(importFilter); - - rMessage() << "Using " << _format.getMapFormatName() << " format to load the data." << std::endl; - - // Start parsing - reader->readFromStream(_stream); - - // Prepare child primitives - scene::addOriginToChildPrimitives(root); - - // Move the index mapping to this class before destroying the import filter - _indexMapping.swap(importFilter.getNodeMap()); - - return root; - } - catch (FileOperation::OperationCancelled&) - { - // Clear out the root node, otherwise we end up with half a map - scene::NodeRemover remover; - root->traverseChildren(remover); - - throw; // leak this exception - } - catch (IMapReader::FailureException& e) - { - // Clear out the root node, otherwise we end up with half a map - scene::NodeRemover remover; - root->traverseChildren(remover); - - // Convert the exception, pass the same message - throw IMapResource::OperationException(e.what()); - } - } - - void loadInfoFile(std::istream& stream, const RootNodePtr& root) - { - if (!stream.good()) - { - rError() << "[MapResource] No valid info file stream" << std::endl; - return; - } - - rMessage() << "Parsing info file..." << std::endl; + MapResourceLoader(std::istream& stream, const MapFormat& format); - try - { - // Read the infofile - InfoFile infoFile(stream, root, _indexMapping); + // Process the stream passed to the constructor, returns + // the root node + // Throws exceptions on failure: + // - FileOperation::OperationCancelled in case the user cancelled + // - IMapResource::OperationException in other cases + RootNodePtr load(); - // Start parsing, this will throw if any errors occur - infoFile.parse(); - } - catch (parser::ParseException& e) - { - rError() << "[MapResource] Unable to parse info file: " << e.what() << std::endl; - } - } + // Load the info file from the given stream, apply it to the root node + void loadInfoFile(std::istream& stream, const RootNodePtr& root); }; } diff --git a/tools/msvc/DarkRadiantCore.vcxproj b/tools/msvc/DarkRadiantCore.vcxproj index 5f2711bc9f..2373bd5573 100644 --- a/tools/msvc/DarkRadiantCore.vcxproj +++ b/tools/msvc/DarkRadiantCore.vcxproj @@ -132,6 +132,7 @@ + diff --git a/tools/msvc/DarkRadiantCore.vcxproj.filters b/tools/msvc/DarkRadiantCore.vcxproj.filters index 522e2e123b..c3046ac9bc 100644 --- a/tools/msvc/DarkRadiantCore.vcxproj.filters +++ b/tools/msvc/DarkRadiantCore.vcxproj.filters @@ -1000,6 +1000,9 @@ src\model\export + + src\map +