Mercurial > fife-parpg
comparison engine/python/fife/extensions/savers.py @ 378:64738befdf3b
bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author | vtchill@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 11 Jan 2010 23:34:52 +0000 |
parents | |
children | 9d94f4676d17 |
comparison
equal
deleted
inserted
replaced
377:fe6fb0e0ed23 | 378:64738befdf3b |
---|---|
1 # -*- coding: utf-8 -*- | |
2 | |
3 # #################################################################### | |
4 # Copyright (C) 2005-2009 by the FIFE team | |
5 # http://www.fifengine.de | |
6 # This file is part of FIFE. | |
7 # | |
8 # FIFE is free software; you can redistribute it and/or | |
9 # modify it under the terms of the GNU Lesser General Public | |
10 # License as published by the Free Software Foundation; either | |
11 # version 2.1 of the License, or (at your option) any later version. | |
12 # | |
13 # This library is distributed in the hope that it will be useful, | |
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 # Lesser General Public License for more details. | |
17 # | |
18 # You should have received a copy of the GNU Lesser General Public | |
19 # License along with this library; if not, write to the | |
20 # Free Software Foundation, Inc., | |
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 # #################################################################### | |
23 | |
24 import os | |
25 from xml.sax.saxutils import XMLGenerator | |
26 from xml.sax.xmlreader import AttributesNSImpl | |
27 from fife.extensions.serializers import * | |
28 | |
29 from fife import fife | |
30 | |
31 MAPFORMAT = '1.0' | |
32 | |
33 fileExtensions = ('xml',) | |
34 class ModelSaver: | |
35 | |
36 def __init__(self, filepath, engine, state = 0, datastate = 0): | |
37 self.SModel, self.SMap, self.SLayer, self.SInstances, self.SObject, self.SAction = range(6) | |
38 | |
39 self.engine = engine | |
40 self.model = self.engine.getModel() | |
41 self.pool = self.engine.getImagePool() | |
42 self.anim_pool = self.engine.getAnimationPool() | |
43 | |
44 if (state): | |
45 self.state = state | |
46 if (state == self.SMap): | |
47 self.map = datastate | |
48 else: | |
49 assert 0, "Invalid initialization state." | |
50 else: | |
51 self.state = self.SModel | |
52 | |
53 self.stack = [ self.SModel ] | |
54 self.datastack = [ ] | |
55 | |
56 self.file = open(filepath, 'w') | |
57 self.xmlout = XMLGenerator(self.file, 'ascii') | |
58 self.xmlout.startDocument() | |
59 | |
60 self.indent_level = '' | |
61 | |
62 self.nspace = None | |
63 | |
64 def startElement(self, name, attrs): | |
65 self.file.write(self.indent_level) | |
66 self.xmlout.startElementNS((None, name), name, attrs) | |
67 self.file.write('\n') | |
68 self.indent_level = self.indent_level + '\t' | |
69 | |
70 def endElement(self, name): | |
71 self.indent_level = self.indent_level[0:(len(self.indent_level) - 1)] | |
72 self.file.write(self.indent_level) | |
73 self.xmlout.endElementNS((None, name), name) | |
74 self.file.write('\n') | |
75 | |
76 def write_map(self, map, importList): | |
77 assert self.state == self.SModel, "Declaration of <map> not at the top level." | |
78 | |
79 attr_vals = { | |
80 (None, 'id'): map.getId(), | |
81 (None, 'format'): MAPFORMAT, | |
82 } | |
83 attr_names = { | |
84 (None, 'id'): 'id', | |
85 (None, 'format'): 'format', | |
86 } | |
87 attrs = AttributesNSImpl(attr_vals, attr_names) | |
88 self.startElement('map', attrs) | |
89 self.state = self.SMap | |
90 self.write_imports(map, importList) | |
91 self.write_layers(map) | |
92 self.write_camera(map) | |
93 self.endElement('map') | |
94 | |
95 def write_imports(self, map, importList): | |
96 for importdir in importList: | |
97 self.write_importdir(root_subfile(map.getResourceFile(), importdir)) | |
98 | |
99 imports = [] | |
100 for layer in map.getLayers(): | |
101 for instance in layer.getInstances(): | |
102 file = instance.getObject().getResourceFile() | |
103 if not (file in imports): | |
104 if not self.have_superdir(file, importList): | |
105 imports.append(file) | |
106 self.write_import(root_subfile(map.getResourceFile(), file)) | |
107 | |
108 def have_superdir(self, file, importList): | |
109 '''returns true, if file is in directories given in importList''' | |
110 for dir in importList: | |
111 have = True | |
112 for test in zip(dir.split(os.path.sep), file.split(os.path.sep)): | |
113 if test[0] != test[1]: have = False | |
114 if have: return True | |
115 | |
116 return False | |
117 | |
118 def write_import(self, file): | |
119 attr_vals = { | |
120 (None, 'file'): file, | |
121 } | |
122 attr_names = { | |
123 (None, 'file'): 'file', | |
124 } | |
125 attrs = AttributesNSImpl(attr_vals, attr_names) | |
126 self.file.write(self.indent_level) | |
127 self.xmlout.startElementNS((None, 'import'), 'import', attrs) | |
128 self.xmlout.endElementNS((None, 'import'), 'import') | |
129 self.file.write('\n') | |
130 | |
131 def write_importdir(self, dir): | |
132 attr_vals = { | |
133 (None, 'dir'): dir, | |
134 } | |
135 attr_names = { | |
136 (None, 'dir'): 'dir', | |
137 } | |
138 attrs = AttributesNSImpl(attr_vals, attr_names) | |
139 self.file.write(self.indent_level) | |
140 self.xmlout.startElementNS((None, 'import'), 'import', attrs) | |
141 self.xmlout.endElementNS((None, 'import'), 'import') | |
142 self.file.write('\n') | |
143 | |
144 def pathing_val_to_str(self, val): | |
145 if val == fife.CELL_EDGES_AND_DIAGONALS: | |
146 return "cell_edges_and_diagonals" | |
147 if val == fife.FREEFORM: | |
148 return "freeform" | |
149 return "cell_edges_only" | |
150 | |
151 def write_layers(self, map): | |
152 for layer in map.getLayers(): | |
153 cellgrid = layer.getCellGrid() | |
154 attr_vals = { | |
155 (None, 'id'): layer.getId(), | |
156 (None, 'grid_type'): cellgrid.getType(), | |
157 (None, 'x_scale'): str(cellgrid.getXScale()), | |
158 (None, 'y_scale'): str(cellgrid.getYScale()), | |
159 (None, 'rotation'): str(cellgrid.getRotation()), | |
160 (None, 'x_offset'): str(cellgrid.getXShift()), | |
161 (None, 'y_offset'): str(cellgrid.getYShift()), | |
162 (None, 'pathing'): self.pathing_val_to_str(layer.getPathingStrategy()), | |
163 (None, 'transparency'): str(layer.getLayerTransparency()), | |
164 } | |
165 attr_names = { | |
166 (None, 'id'): 'id', | |
167 (None, 'grid_type'): 'grid_type', | |
168 (None, 'scaling'): 'scaling', | |
169 (None, 'rotation'): 'rotation', | |
170 (None, 'x_offset'): 'x_offset', | |
171 (None, 'y_offset'): 'y_offset', | |
172 (None, 'pathing'): 'pathing', | |
173 } | |
174 attrs = AttributesNSImpl(attr_vals, attr_names) | |
175 self.startElement('layer', attrs) | |
176 self.write_instances(layer) | |
177 self.endElement('layer') | |
178 | |
179 def write_instances(self, layer): | |
180 attrs = AttributesNSImpl({}, {}) | |
181 self.startElement('instances', attrs) | |
182 | |
183 for inst in layer.getInstances(): | |
184 position = inst.getLocationRef().getExactLayerCoordinates() | |
185 attr_vals = { | |
186 (None, 'o'): inst.getObject().getId(), | |
187 (None, 'x'): str(position.x), | |
188 (None, 'y'): str(position.y), | |
189 (None, 'z'): str(position.z), | |
190 (None, 'r'): str(inst.getRotation()), | |
191 } | |
192 attr_names = { | |
193 (None, 'o'): 'o', | |
194 (None, 'x'): 'x', | |
195 (None, 'y'): 'y', | |
196 (None, 'z'): 'z', | |
197 (None, 'r'): 'r', | |
198 } | |
199 | |
200 nspace = inst.getObject().getNamespace() | |
201 if nspace != self.nspace: | |
202 attr_vals[(None, 'ns')] = inst.getObject().getNamespace() | |
203 attr_names[(None, 'ns')] = 'ns' | |
204 self.nspace = nspace | |
205 | |
206 instId = inst.getId() | |
207 if instId: | |
208 attr_vals[(None, 'id')] = inst.getId() | |
209 attr_names[(None, 'id')] = 'id' | |
210 | |
211 attrs = AttributesNSImpl(attr_vals, attr_names) | |
212 self.file.write(self.indent_level) | |
213 self.xmlout.startElementNS((None, 'i'), 'i', attrs) | |
214 self.xmlout.endElementNS((None, 'i'), 'i') | |
215 self.file.write('\n') | |
216 | |
217 self.endElement('instances') | |
218 | |
219 # Save the linked camera of a map. | |
220 def write_camera( self, map ): | |
221 cameralist = self.engine.getView().getCameras() | |
222 | |
223 for cam in cameralist: | |
224 if cam.getLocationRef().getMap().getId() == map.getId(): | |
225 celldimensions = cam.getCellImageDimensions() | |
226 viewport = cam.getViewPort(); | |
227 | |
228 attr_names = { | |
229 (None, 'id'): 'id', | |
230 (None, 'zoom'): 'zoom', | |
231 (None, 'tilt'): 'tile', | |
232 (None, 'rotation'): 'rotation', | |
233 (None, 'ref_layer_id'): 'ref_layer_id', | |
234 (None, 'ref_cell_width'): 'ref_cell_width', | |
235 (None, 'ref_cell_height'): 'ref_cell_height', | |
236 } | |
237 | |
238 attr_vals = { | |
239 (None, 'id'): cam.getId(), | |
240 (None, 'zoom'): str( cam.getZoom()), | |
241 (None, 'tilt'): str( cam.getTilt()), | |
242 (None, 'rotation'): str( cam.getRotation()), | |
243 (None, 'ref_layer_id'): cam.getLocation().getLayer().getId(), | |
244 (None, 'ref_cell_width'): str( celldimensions.x ), | |
245 (None, 'ref_cell_height'): str( celldimensions.y ), | |
246 } | |
247 | |
248 # add a viewport entry if the cam isn't full sized | |
249 if not (viewport == self.engine.getRenderBackend().getArea()): | |
250 attr_names[(None,'viewport')] = 'viewport' | |
251 attr_vals[(None,'viewport')] = '%d,%d,%d,%d' % (viewport.x, viewport.y, viewport.w, viewport.h) | |
252 | |
253 attrs = AttributesNSImpl( attr_vals, attr_names ) | |
254 self.startElement( 'camera', attrs ); | |
255 self.endElement( 'camera' ); | |
256 | |
257 def flush(self): | |
258 self.xmlout.endDocument() | |
259 self.file.close() | |
260 | |
261 def saveMapFile(path, engine, map, importList=[]): | |
262 map.setResourceFile(path) | |
263 writer = ModelSaver(path, engine) | |
264 writer.write_map(map, importList) |