Mercurial > traipse_dev
comparison orpg/mapper/base_msg.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children | 78407d627cba |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4385a7d0efd1 |
---|---|
1 # Copyright (C) 2000-2001 The OpenRPG Project | |
2 # | |
3 # openrpg-dev@lists.sourceforge.net | |
4 # | |
5 # This program is free software; you can redistribute it and/or modify | |
6 # it under the terms of the GNU General Public License as published by | |
7 # the Free Software Foundation; either version 2 of the License, or | |
8 # (at your option) any later version. | |
9 # | |
10 # This program is distributed in the hope that it will be useful, | |
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 # GNU General Public License for more details. | |
14 # | |
15 # You should have received a copy of the GNU General Public License | |
16 # along with this program; if not, write to the Free Software | |
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
18 # -- | |
19 # | |
20 # File: mapper/base_msg.py | |
21 # Author: Chris Davis | |
22 # Maintainer: | |
23 # Version: | |
24 # $Id: base_msg.py,v 1.9 2007/03/09 14:11:55 digitalxero Exp $ | |
25 # | |
26 # Description: | |
27 # | |
28 __version__ = "$Id: base_msg.py,v 1.9 2007/03/09 14:11:55 digitalxero Exp $" | |
29 | |
30 from threading import RLock | |
31 from orpg.networking.mplay_client import * | |
32 | |
33 class map_element_msg_base: | |
34 # This is a base class | |
35 | |
36 def __init__(self,reentrant_lock_object = None): | |
37 | |
38 if not hasattr(self,"tagname"): | |
39 raise Exception, "This is a virtual class that cannot be directly instantiated. Set self.tagname in derived class." | |
40 | |
41 self._props = {} | |
42 # This is a dictionary that holds (value,changed) 2-tuples, indexed by attribute | |
43 # Avoid manipulating these values directly. Instead, use the provided accessor methods. | |
44 # If there is not one that suits your needs, please add one to this class and | |
45 # use it instead. | |
46 | |
47 self.children = {} | |
48 # This next clause will set self.p_lock to a passed-in RLock object, if present. | |
49 # Otherwise, it will create it's very own for this instance. | |
50 # Using a passed in object is useful to protect an entire <map/> element from | |
51 # being changed by another thread when any part of it is being change by another | |
52 # thread. Just pass the map_msg's p_lock object in to it's descendents. | |
53 if reentrant_lock_object: | |
54 self.p_lock = reentrant_lock_object | |
55 else: | |
56 self.p_lock = RLock() | |
57 | |
58 def clear(self): | |
59 self.p_lock.acquire() | |
60 | |
61 for child in self.children.keys(): | |
62 self.children[child].clear() | |
63 self.children[child] = None | |
64 del self.children[child] | |
65 | |
66 for p in self._props.keys(): | |
67 self._props[p] = None | |
68 | |
69 self.p_lock.release() | |
70 | |
71 | |
72 ######################################### | |
73 # Accessor functions begin | |
74 | |
75 # Access single property | |
76 | |
77 def init_prop(self,prop,value): # set's the changed flag to False and assigns | |
78 self.p_lock.acquire() | |
79 self._props[prop] = (value, 0) | |
80 self.p_lock.release() | |
81 | |
82 def set_prop(self,prop,value): # set's the changed flag to True and assigns | |
83 self.p_lock.acquire() | |
84 self._props[prop] = (value, 1) | |
85 self.p_lock.release() | |
86 | |
87 def get_prop(self,prop): # returns None if prop not found | |
88 self.p_lock.acquire() | |
89 if prop in self._props.keys(): | |
90 (p,c) = self._props[prop] | |
91 self.p_lock.release() | |
92 return p | |
93 else: | |
94 self.p_lock.release() | |
95 return None | |
96 | |
97 def is_prop_changed(self,prop): # returns None if prop not found | |
98 self.p_lock_acquire() | |
99 if prop in self._props.keys(): | |
100 (p,c) = self._props[prop] | |
101 self.p_lock.release() | |
102 return c | |
103 else: | |
104 self.p_lock.release() | |
105 return None | |
106 | |
107 def get_child(self,key): # returns None if key not found in children list | |
108 self.p_lock_acquire() | |
109 if self.children.has_key(key): | |
110 self.p_lock.release() | |
111 return self.children[key] | |
112 else: | |
113 self.p_lock.release() | |
114 return None | |
115 | |
116 # Access multiple properties | |
117 | |
118 def init_props(self,props): # same as init_prop(), but takes dictionary of props | |
119 self.p_lock.acquire() | |
120 for k in props.keys(): | |
121 self._props[k] = (props[k],0) | |
122 self.p_lock.release() | |
123 | |
124 def set_props(self,props): # same as set_prop(), but takes dictionary of props | |
125 self.p_lock.acquire() | |
126 for k in props.keys(): | |
127 self._props[k] = (props[k],1) | |
128 self.p_lock.release() | |
129 | |
130 def get_all_props(self): # returns dictionary of all properties, regardless of change | |
131 self.p_lock.acquire() | |
132 | |
133 result = {} | |
134 for k in self._props.keys(): | |
135 (p,c) = self._props[k] | |
136 result[k] = p | |
137 | |
138 self.p_lock.release() | |
139 return result | |
140 | |
141 def get_changed_props(self): # returns dictionary of all properties that have been changed | |
142 self.p_lock.acquire() | |
143 result = {} | |
144 for k in self._props.keys(): | |
145 (p,c) = self._props[k] | |
146 if c: | |
147 result[k] = p | |
148 self.p_lock.release() | |
149 return result | |
150 | |
151 def get_children(self): # returns dictionary of children | |
152 return self.children | |
153 | |
154 | |
155 # Accessor functions end | |
156 ######################################### | |
157 | |
158 ######################################### | |
159 # XML emitters begin | |
160 def get_all_xml(self,action="new",output_action = 0): # outputs a tag with all attributes it contains | |
161 self.p_lock.acquire() | |
162 xml_str = "<" + self.tagname | |
163 if action and output_action: | |
164 xml_str += " action='" + action + "'" | |
165 for k in self._props.keys(): | |
166 (p,c) = self._props[k] | |
167 if k != "action" or not action: | |
168 xml_str += " " + k + "='" + p + "'" | |
169 if self.children: | |
170 xml_str += ">" | |
171 for child in self.children.keys(): | |
172 xml_str += self.children[child].get_all_xml(action) | |
173 xml_str += "</" + self.tagname + ">" | |
174 else: | |
175 xml_str += "/>" | |
176 self.p_lock.release() | |
177 return xml_str | |
178 | |
179 def get_changed_xml(self,action="update",output_action = 0): # outputs a tag with all changed attributes | |
180 self.p_lock.acquire() | |
181 xml_str = "<" + self.tagname | |
182 if action and output_action: | |
183 xml_str += " action='" + action + "'" | |
184 | |
185 # if present, always send the id, even if it didn't change | |
186 if self._props.has_key("id"): | |
187 (p,c) = self._props["id"] | |
188 xml_str += " id='" + p + "'" | |
189 for k in self._props.keys(): | |
190 (p,c) = self._props[k] | |
191 if (k != "id" or k != "action") and c == 1: # don't duplicate the id attribute | |
192 xml_str += " " + k + "='" + p + "'" | |
193 if self.children: | |
194 xml_str += ">" | |
195 for child in self.children.keys(): | |
196 xml_str += self.children[child].get_changed_xml(action) | |
197 xml_str += "</" + self.tagname + ">" | |
198 else: | |
199 xml_str += "/>" | |
200 self.p_lock.release() | |
201 return xml_str | |
202 | |
203 # convenience method to use if only this tag is modified | |
204 # outputs a <map/> element containing only the changes to this tag | |
205 def standalone_update_text(self,update_id_string): | |
206 buffer = "<map id='" + update_id_string + "'>" | |
207 buffer += self.get_changed_xml("update") | |
208 buffer += "<map/>" | |
209 return buffer | |
210 | |
211 # XML emitters end | |
212 ######################################### | |
213 | |
214 ######################################### | |
215 # XML importers begin | |
216 | |
217 def _from_dom(self,xml_dom,prop_func): | |
218 self.p_lock.acquire() | |
219 if xml_dom.tagName == self.tagname: | |
220 if xml_dom.getAttributeKeys(): | |
221 for k in xml_dom.getAttributeKeys(): | |
222 prop_func(k,xml_dom.getAttribute(k)) | |
223 else: | |
224 self.p_lock.release() | |
225 raise Exception, "Error attempting to modify a " + self.tagname + " from a non-<" + self.tagname + "/> element" | |
226 self.p_lock.release() | |
227 | |
228 def init_from_dom(self,xml_dom): | |
229 # xml_dom must be pointing to an empty tag. Override in a derived class for <map/> and other similar tags. | |
230 self._from_dom(xml_dom,self.init_prop) | |
231 | |
232 def set_from_dom(self,xml_dom): | |
233 # xml_dom must be pointing to an empty tag. Override in a derived class for <map/> and other similar tags | |
234 self._from_dom(xml_dom,self.set_prop) | |
235 | |
236 def init_from_xml(self,xml): | |
237 xml_dom = parseXml(xml) | |
238 node_list = xml_dom.getElementsByTagName(self.tagname) | |
239 if len(node_list) < 1: | |
240 print "Warning: no <" + self.tagname + "/> elements found in DOM." | |
241 else: | |
242 while len(node_list): | |
243 self.init_from_dom(node_list.pop()) | |
244 if xml_dom: | |
245 xml_dom.unlink() | |
246 | |
247 def set_from_xml(self,xml): | |
248 xml_dom = parseXml(xml) | |
249 node_list = xml_dom.getElementsByTagName(self.tagname) | |
250 if len(node_list) < 1: | |
251 print "Warning: no <" + self.tagname + "/> elements found in DOM." | |
252 else: | |
253 while len(node_list): | |
254 self.set_from_dom(node_list.pop()) | |
255 if xml_dom: | |
256 xml_dom.unlink() | |
257 | |
258 # XML importers end | |
259 ######################################### |