1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "NodeReader.h"
21 
22 #include "Logger.h"
23 #include "Model/Brush.h"
24 #include "Model/Entity.h"
25 #include "Model/Layer.h"
26 #include "Model/ModelFactory.h"
27 #include "Model/World.h"
28 
29 namespace TrenchBroom {
30     namespace IO {
NodeReader(const String & str,Model::ModelFactory * factory,Logger * logger)31         NodeReader::NodeReader(const String& str, Model::ModelFactory* factory, Logger* logger) :
32         MapReader(str, logger),
33         m_factory(factory) {
34             assert(m_factory != NULL);
35         }
36 
read(const BBox3 & worldBounds)37         const Model::NodeList& NodeReader::read(const BBox3& worldBounds) {
38             try {
39                 readEntities(m_factory->format(), worldBounds);
40             } catch (const ParserException&) {
41                 VectorUtils::clearAndDelete(m_nodes);
42 
43                 try {
44                     reset();
45                     readBrushes(m_factory->format(), worldBounds);
46                 } catch (const ParserException&) {
47                     VectorUtils::clearAndDelete(m_nodes);
48                     throw;
49                 }
50             }
51             return m_nodes;
52         }
53 
initialize(const Model::MapFormat::Type format,const BBox3 & worldBounds)54         Model::ModelFactory* NodeReader::initialize(const Model::MapFormat::Type format, const BBox3& worldBounds) {
55             assert(format == m_factory->format());
56             return m_factory;
57         }
58 
onWorldspawn(const Model::EntityAttribute::List & attributes,const ExtraAttributes & extraAttributes)59         Model::Node* NodeReader::onWorldspawn(const Model::EntityAttribute::List& attributes, const ExtraAttributes& extraAttributes) {
60             Model::Entity* worldspawn = m_factory->createEntity();
61             worldspawn->setAttributes(attributes);
62             setExtraAttributes(worldspawn, extraAttributes);
63 
64             m_nodes.insert(m_nodes.begin(), worldspawn);
65             return worldspawn;
66         }
67 
onWorldspawnFilePosition(const size_t lineNumber,const size_t lineCount)68         void NodeReader::onWorldspawnFilePosition(const size_t lineNumber, const size_t lineCount) {
69             assert(!m_nodes.empty());
70             m_nodes.front()->setFilePosition(lineNumber, lineCount);
71         }
72 
onLayer(Model::Layer * layer)73         void NodeReader::onLayer(Model::Layer* layer) {
74             m_nodes.push_back(layer);
75         }
76 
onNode(Model::Node * parent,Model::Node * node)77         void NodeReader::onNode(Model::Node* parent, Model::Node* node) {
78             if (parent != NULL)
79                 parent->addChild(node);
80             else
81                 m_nodes.push_back(node);
82         }
83 
onUnresolvedNode(const ParentInfo & parentInfo,Model::Node * node)84         void NodeReader::onUnresolvedNode(const ParentInfo& parentInfo, Model::Node* node) {
85             if (parentInfo.layer()) {
86                 logger()->warn("Could not resolve parent layer for object at line %u, adding to default layer", static_cast<unsigned int>(node->lineNumber()));
87             } else if (parentInfo.group()) {
88                 logger()->warn("Could not resolve parent group for object at line %u, adding to default layer", static_cast<unsigned int>(node->lineNumber()));
89             }
90             m_nodes.push_back(node);
91         }
92 
onBrush(Model::Node * parent,Model::Brush * brush)93         void NodeReader::onBrush(Model::Node* parent, Model::Brush* brush) {
94             if (parent != NULL)
95                 parent->addChild(brush);
96             else
97                 m_nodes.push_back(brush);
98         }
99     }
100 }
101