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