Skip to content

Commit

Permalink
#5108: Move implementation to .cpp file, remove migrated code from Ma…
Browse files Browse the repository at this point in the history
…pResource class.
  • Loading branch information
codereader committed Nov 28, 2020
1 parent 3659978 commit d1a3727
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 194 deletions.
1 change: 1 addition & 0 deletions radiantcore/Makefile.am
Expand Up @@ -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 \
Expand Down
111 changes: 0 additions & 111 deletions radiantcore/map/MapResource.cpp
Expand Up @@ -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<RootNode>(_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<void(std::istream&)>& streamProcessor)
{
if (path_is_absolute(path.c_str()))
Expand Down
7 changes: 0 additions & 7 deletions radiantcore/map/MapResource.h
Expand Up @@ -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<void(std::istream&)>& streamProcessor);
Expand Down
86 changes: 86 additions & 0 deletions 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<RootNode>("");

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;
}
}

}
88 changes: 12 additions & 76 deletions radiantcore/map/MapResourceLoader.h
@@ -1,16 +1,13 @@
#pragma once

#include <istream>

#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
{
Expand All @@ -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<RootNode>("");

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);
};

}
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -132,6 +132,7 @@
<ClCompile Include="..\..\radiantcore\map\MapPositionManager.cpp" />
<ClCompile Include="..\..\radiantcore\map\MapPropertyInfoFileModule.cpp" />
<ClCompile Include="..\..\radiantcore\map\MapResource.cpp" />
<ClCompile Include="..\..\radiantcore\map\MapResourceLoader.cpp" />
<ClCompile Include="..\..\radiantcore\map\MapResourceManager.cpp" />
<ClCompile Include="..\..\radiantcore\map\mru\MRU.cpp" />
<ClCompile Include="..\..\radiantcore\map\namespace\ComplexName.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/DarkRadiantCore.vcxproj.filters
Expand Up @@ -1000,6 +1000,9 @@
<ClCompile Include="..\..\radiantcore\model\export\PatchSurface.cpp">
<Filter>src\model\export</Filter>
</ClCompile>
<ClCompile Include="..\..\radiantcore\map\MapResourceLoader.cpp">
<Filter>src\map</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\radiantcore\modulesystem\ModuleLoader.h">
Expand Down

0 comments on commit d1a3727

Please sign in to comment.