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)