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 "NodeWriter.h"
21 
22 #include "IO/MapFileSerializer.h"
23 #include "IO/MapStreamSerializer.h"
24 #include "Model/AssortNodesVisitor.h"
25 #include "Model/Brush.h"
26 #include "Model/Entity.h"
27 #include "Model/Group.h"
28 #include "Model/Layer.h"
29 #include "Model/Node.h"
30 #include "Model/World.h"
31 
32 namespace TrenchBroom {
33     namespace IO {
34         class NodeWriter::CollectEntityBrushesStrategy {
35         public:
36             typedef Model::AssortNodesVisitorT<Model::SkipLayersStrategy, Model::CollectGroupsStrategy, Model::CollectEntitiesStrategy, CollectEntityBrushesStrategy> AssortNodesVisitor;
37         private:
38             EntityBrushesMap m_entityBrushes;
39             Model::BrushList m_worldBrushes;
40 
41             class VisitParent : public Model::NodeVisitor {
42             private:
43                 Model::Brush* m_brush;
44                 EntityBrushesMap& m_entityBrushes;
45                 Model::BrushList& m_worldBrushes;
46             public:
VisitParent(Model::Brush * brush,EntityBrushesMap & entityBrushes,Model::BrushList & worldBrushes)47                 VisitParent(Model::Brush* brush, EntityBrushesMap& entityBrushes, Model::BrushList& worldBrushes) :
48                 m_brush(brush),
49                 m_entityBrushes(entityBrushes),
50                 m_worldBrushes(worldBrushes) {}
51             private:
doVisit(Model::World * world)52                 void doVisit(Model::World* world)   { m_worldBrushes.push_back(m_brush);  }
doVisit(Model::Layer * layer)53                 void doVisit(Model::Layer* layer)   { m_worldBrushes.push_back(m_brush);  }
doVisit(Model::Group * group)54                 void doVisit(Model::Group* group)   { m_worldBrushes.push_back(m_brush);  }
doVisit(Model::Entity * entity)55                 void doVisit(Model::Entity* entity) { m_entityBrushes[entity].push_back(m_brush); }
doVisit(Model::Brush * brush)56                 void doVisit(Model::Brush* brush)   {}
57             };
58         public:
entityBrushes() const59             const EntityBrushesMap& entityBrushes() const {
60                 return m_entityBrushes;
61             }
62 
worldBrushes() const63             const Model::BrushList& worldBrushes() const {
64                 return m_worldBrushes;
65             }
66 
addBrush(Model::Brush * brush)67             void addBrush(Model::Brush* brush) {
68                 VisitParent visitParent(brush, m_entityBrushes, m_worldBrushes);
69                 Model::Node* parent = brush->parent();
70                 parent->accept(visitParent);
71             }
72         };
73 
74         class NodeWriter::WriteNode : public Model::NodeVisitor {
75         private:
76             NodeSerializer& m_serializer;
77             const Model::EntityAttribute::List m_parentAttributes;
78         public:
WriteNode(NodeSerializer & serializer,const Model::Node * parent=NULL)79             WriteNode(NodeSerializer& serializer, const Model::Node* parent = NULL) :
80             m_serializer(serializer),
81             m_parentAttributes(m_serializer.parentAttributes(parent)) {}
82 
doVisit(Model::World * world)83             void doVisit(Model::World* world)   { stopRecursion(); }
doVisit(Model::Layer * layer)84             void doVisit(Model::Layer* layer)   { stopRecursion(); }
85 
doVisit(Model::Group * group)86             void doVisit(Model::Group* group)   {
87                 m_serializer.group(group, m_parentAttributes);
88                 WriteNode visitor(m_serializer, group);
89                 group->iterate(visitor);
90                 stopRecursion();
91             }
92 
doVisit(Model::Entity * entity)93             void doVisit(Model::Entity* entity) {
94                 m_serializer.entity(entity, entity->attributes(), m_parentAttributes, entity);
95                 stopRecursion();
96             }
97 
doVisit(Model::Brush * brush)98             void doVisit(Model::Brush* brush)   { stopRecursion();  }
99         };
100 
NodeWriter(Model::World * world,FILE * stream)101         NodeWriter::NodeWriter(Model::World* world, FILE* stream) :
102         m_world(world),
103         m_serializer(MapFileSerializer::create(m_world->format(), stream)) {}
104 
NodeWriter(Model::World * world,std::ostream & stream)105         NodeWriter::NodeWriter(Model::World* world, std::ostream& stream) :
106         m_world(world),
107         m_serializer(MapStreamSerializer::create(m_world->format(), stream)) {}
108 
writeMap()109         void NodeWriter::writeMap() {
110             writeDefaultLayer();
111             writeCustomLayers();
112         }
113 
writeDefaultLayer()114         void NodeWriter::writeDefaultLayer() {
115             m_serializer->defaultLayer(m_world);
116 
117             const Model::NodeList& children = m_world->defaultLayer()->children();
118             WriteNode visitor(*m_serializer);
119             Model::Node::accept(children.begin(), children.end(), visitor);
120         }
121 
writeCustomLayers()122         void NodeWriter::writeCustomLayers() {
123             const Model::LayerList customLayers = m_world->customLayers();
124             Model::LayerList::const_iterator it, end;
125             for (it = customLayers.begin(), end = customLayers.end(); it != end; ++it) {
126                 Model::Layer* layer = *it;
127                 writeCustomLayer(layer);
128             }
129         }
130 
writeCustomLayer(Model::Layer * layer)131         void NodeWriter::writeCustomLayer(Model::Layer* layer) {
132             m_serializer->customLayer(layer);
133 
134             const Model::NodeList& children = layer->children();
135             WriteNode visitor(*m_serializer, layer);
136             Model::Node::accept(children.begin(), children.end(), visitor);
137         }
138 
writeNodes(const Model::NodeList & nodes)139         void NodeWriter::writeNodes(const Model::NodeList& nodes) {
140             typedef Model::AssortNodesVisitorT<Model::SkipLayersStrategy, Model::CollectGroupsStrategy, Model::CollectEntitiesStrategy, CollectEntityBrushesStrategy> CollectNodes;
141 
142             CollectNodes collect;
143             Model::Node::accept(nodes.begin(), nodes.end(), collect);
144 
145             writeWorldBrushes(collect.worldBrushes());
146             writeEntityBrushes(collect.entityBrushes());
147 
148             const Model::GroupList& groups = collect.groups();
149             const Model::EntityList& entities = collect.entities();
150 
151             WriteNode visitor(*m_serializer);
152             Model::Node::accept(groups.begin(), groups.end(), visitor);
153             Model::Node::accept(entities.begin(), entities.end(), visitor);
154         }
155 
writeWorldBrushes(const Model::BrushList & brushes)156         void NodeWriter::writeWorldBrushes(const Model::BrushList& brushes) {
157             if (!brushes.empty())
158                 m_serializer->entity(m_world, m_world->attributes(), Model::EntityAttribute::EmptyList, brushes);
159         }
160 
writeEntityBrushes(const EntityBrushesMap & entityBrushes)161         void NodeWriter::writeEntityBrushes(const EntityBrushesMap& entityBrushes) {
162             EntityBrushesMap::const_iterator it, end;
163             for (it = entityBrushes.begin(), end = entityBrushes.end(); it != end; ++it) {
164                 Model::Entity* entity = it->first;
165                 const Model::BrushList& brushes = it->second;
166                 m_serializer->entity(entity, entity->attributes(), Model::EntityAttribute::EmptyList, brushes);
167             }
168         }
169 
writeBrushFaces(const Model::BrushFaceList & faces)170         void NodeWriter::writeBrushFaces(const Model::BrushFaceList& faces) {
171             m_serializer->brushFaces(faces);
172         }
173     }
174 }
175