added string-pooling for shader variable names and entity keys
[xonotic/netradiant.git] / plugins / mapq3 / write.cpp
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #include "write.h"
23
24 #include "ientity.h"
25 #include "iscriplib.h"
26 #include "scenelib.h"
27
28 inline MapExporter* Node_getMapExporter(scene::Node& node)
29 {
30   return NodeTypeCast<MapExporter>::cast(node);
31 }
32
33
34 static std::size_t g_count_entities;
35 static std::size_t g_count_brushes;
36
37
38 void Entity_ExportTokens(const Entity& entity, TokenWriter& writer)
39 {
40   g_count_brushes = 0;
41
42   class WriteKeyValue : public Entity::Visitor
43   {
44     TokenWriter& m_writer;
45   public:
46     WriteKeyValue(TokenWriter& writer)
47       : m_writer(writer)
48     {
49     }
50
51     void visit(const char* key, const char* value)
52     {
53       m_writer.writeString(key);
54       m_writer.writeString(value);
55       m_writer.nextLine();
56     }
57
58   } visitor(writer);
59
60   entity.forEachKeyValue(visitor);
61 }
62
63 class WriteTokensWalker : public scene::Traversable::Walker
64 {
65   mutable Stack<bool> m_stack;
66   TokenWriter& m_writer;
67   bool m_ignorePatches;
68 public:
69   WriteTokensWalker(TokenWriter& writer, bool ignorePatches)
70     : m_writer(writer), m_ignorePatches(ignorePatches)
71   {
72   }
73   bool pre(scene::Node& node) const
74   {
75     m_stack.push(false);
76
77     Entity* entity = Node_getEntity(node);
78     if(entity != 0)
79     {
80       m_writer.writeToken("//");
81       m_writer.writeToken("entity");
82       m_writer.writeUnsigned(g_count_entities++);
83       m_writer.nextLine();
84
85       m_writer.writeToken("{");
86       m_writer.nextLine();
87       m_stack.top() = true;
88
89       Entity_ExportTokens(*entity, m_writer);
90     }
91     else
92     {
93       MapExporter* exporter = Node_getMapExporter(node);
94       if(exporter != 0
95       && !(m_ignorePatches && Node_isPatch(node)))
96       {
97         m_writer.writeToken("//");
98         m_writer.writeToken("brush");
99         m_writer.writeUnsigned(g_count_brushes++);
100         m_writer.nextLine();
101
102         exporter->exportTokens(m_writer);
103       }
104     }
105
106     return true;
107   }
108   void post(scene::Node& node) const
109   {
110     if(m_stack.top())
111     {
112       m_writer.writeToken("}");
113       m_writer.nextLine();
114     }
115     m_stack.pop();
116   }
117 };
118
119 void Map_Write(scene::Node& root, GraphTraversalFunc traverse, TokenWriter& writer, bool ignorePatches)
120 {
121   g_count_entities = 0;
122   traverse(root, WriteTokensWalker(writer, ignorePatches));
123 }
124