added better headlines for tabs in vote menu
[twcon.git] / datasrc / datatypes.py
blobddb3c9e3282dddeed03ee1c36d0b454add510dc1
1 import sys
3 GlobalIdCounter = 0
4 def GetID():
5 global GlobalIdCounter
6 GlobalIdCounter += 1
7 return GlobalIdCounter
8 def GetUID():
9 return "x%d"%GetID()
11 def FixCasing(Str):
12 NewStr = ""
13 NextUpperCase = True
14 for c in Str:
15 if NextUpperCase:
16 NextUpperCase = False
17 NewStr += c.upper()
18 else:
19 if c == "_":
20 NextUpperCase = True
21 else:
22 NewStr += c.lower()
23 return NewStr
25 def FormatName(type, name):
26 if "*" in type:
27 return "m_p" + FixCasing(name)
28 if "[]" in type:
29 return "m_a" + FixCasing(name)
30 return "m_" + FixCasing(name)
32 class BaseType:
33 def __init__(self, type_name):
34 self._type_name = type_name
35 self._target_name = "INVALID"
36 self._id = GetID() # this is used to remember what order the members have in structures etc
38 def Identifyer(self): return "x"+str(self._id)
39 def TargetName(self): return self._target_name
40 def TypeName(self): return self._type_name
41 def ID(self): return self._id;
43 def EmitDeclaration(self, name):
44 return ["%s %s;"%(self.TypeName(), FormatName(self.TypeName(), name))]
45 def EmitPreDefinition(self, target_name):
46 self._target_name = target_name
47 return []
48 def EmitDefinition(self, name):
49 return []
51 class MemberType:
52 def __init__(self, name, var):
53 self.name = name
54 self.var = var
56 class Struct(BaseType):
57 def __init__(self, type_name):
58 BaseType.__init__(self, type_name)
59 def Members(self):
60 def sorter(a):
61 return a.var.ID()
62 m = []
63 for name in self.__dict__:
64 if name[0] == "_":
65 continue
66 m += [MemberType(name, self.__dict__[name])]
67 try:
68 m.sort(key = sorter)
69 except:
70 for v in m:
71 print(v.name, v.var)
72 sys.exit(-1)
73 return m
75 def EmitTypeDeclaration(self, name):
76 lines = []
77 lines += ["struct " + self.TypeName()]
78 lines += ["{"]
79 for member in self.Members():
80 lines += ["\t"+l for l in member.var.EmitDeclaration(member.name)]
81 lines += ["};"]
82 return lines
84 def EmitPreDefinition(self, target_name):
85 BaseType.EmitPreDefinition(self, target_name)
86 lines = []
87 for member in self.Members():
88 lines += member.var.EmitPreDefinition(target_name+"."+member.name)
89 return lines
90 def EmitDefinition(self, name):
91 lines = ["/* %s */ {" % self.TargetName()]
92 for member in self.Members():
93 lines += ["\t" + " ".join(member.var.EmitDefinition("")) + ","]
94 lines += ["}"]
95 return lines
97 class Array(BaseType):
98 def __init__(self, type):
99 BaseType.__init__(self, type.TypeName())
100 self.type = type
101 self.items = []
102 def Add(self, instance):
103 if instance.TypeName() != self.type.TypeName():
104 error("bah")
105 self.items += [instance]
106 def EmitDeclaration(self, name):
107 return ["int m_Num%s;"%(FixCasing(name)),
108 "%s *%s;"%(self.TypeName(), FormatName("[]", name))]
109 def EmitPreDefinition(self, target_name):
110 BaseType.EmitPreDefinition(self, target_name)
112 lines = []
113 i = 0
114 for item in self.items:
115 lines += item.EmitPreDefinition("%s[%d]"%(self.Identifyer(), i))
116 i += 1
118 if len(self.items):
119 lines += ["static %s %s[] = {"%(self.TypeName(), self.Identifyer())]
120 for item in self.items:
121 itemlines = item.EmitDefinition("")
122 lines += ["\t" + " ".join(itemlines).replace("\t", " ") + ","]
123 lines += ["};"]
124 else:
125 lines += ["static %s *%s = 0;"%(self.TypeName(), self.Identifyer())]
127 return lines
128 def EmitDefinition(self, name):
129 return [str(len(self.items))+","+self.Identifyer()]
131 # Basic Types
133 class Int(BaseType):
134 def __init__(self, value):
135 BaseType.__init__(self, "int")
136 self.value = value
137 def Set(self, value):
138 self.value = value
139 def EmitDefinition(self, name):
140 return ["%d"%self.value]
141 #return ["%d /* %s */"%(self.value, self._target_name)]
143 class Float(BaseType):
144 def __init__(self, value):
145 BaseType.__init__(self, "float")
146 self.value = value
147 def Set(self, value):
148 self.value = value
149 def EmitDefinition(self, name):
150 return ["%f"%self.value]
151 #return ["%d /* %s */"%(self.value, self._target_name)]
153 class String(BaseType):
154 def __init__(self, value):
155 BaseType.__init__(self, "const char*")
156 self.value = value
157 def Set(self, value):
158 self.value = value
159 def EmitDefinition(self, name):
160 return ['"'+self.value+'"']
162 class Pointer(BaseType):
163 def __init__(self, type, target):
164 BaseType.__init__(self, "%s*"%type().TypeName())
165 self.target = target
166 def Set(self, target):
167 self.target = target
168 def EmitDefinition(self, name):
169 return ["&"+self.target.TargetName()]
171 # helper functions
173 def EmitTypeDeclaration(root):
174 for l in root().EmitTypeDeclaration(""):
175 print(l)
177 def EmitDefinition(root, name):
178 for l in root.EmitPreDefinition(name):
179 print(l)
180 print("%s %s = " % (root.TypeName(), name))
181 for l in root.EmitDefinition(name):
182 print(l)
183 print(";")
185 # Network stuff after this
187 class Object:
188 pass
190 class Enum:
191 def __init__(self, name, values):
192 self.name = name
193 self.values = values
195 class Flags:
196 def __init__(self, name, values):
197 self.name = name
198 self.values = values
200 class NetObject:
201 def __init__(self, name, variables):
202 l = name.split(":")
203 self.name = l[0]
204 self.base = ""
205 if len(l) > 1:
206 self.base = l[1]
207 self.base_struct_name = "CNetObj_%s" % self.base
208 self.struct_name = "CNetObj_%s" % self.name
209 self.enum_name = "NETOBJTYPE_%s" % self.name.upper()
210 self.variables = variables
211 def emit_declaration(self):
212 if self.base:
213 lines = ["struct %s : public %s"%(self.struct_name,self.base_struct_name), "{"]
214 else:
215 lines = ["struct %s"%self.struct_name, "{"]
216 for v in self.variables:
217 lines += ["\t"+line for line in v.emit_declaration()]
218 lines += ["};"]
219 return lines
220 def emit_validate(self):
221 lines = ["case %s:" % self.enum_name]
222 lines += ["{"]
223 lines += ["\t%s *pObj = (%s *)pData;"%(self.struct_name, self.struct_name)]
224 lines += ["\tif(sizeof(*pObj) != Size) return -1;"]
225 for v in self.variables:
226 lines += ["\t"+line for line in v.emit_validate()]
227 lines += ["\treturn 0;"]
228 lines += ["}"]
229 return lines
232 class NetEvent(NetObject):
233 def __init__(self, name, variables):
234 NetObject.__init__(self, name, variables)
235 self.base_struct_name = "NETEVENT_%s" % self.base.upper()
236 self.struct_name = "NETEVENT_%s" % self.name.upper()
237 self.enum_name = "NETEVENTTYPE_%s" % self.name.upper()
239 class NetMessage(NetObject):
240 def __init__(self, name, variables):
241 NetObject.__init__(self, name, variables)
242 self.base_struct_name = "CNetMsg_%s" % self.base
243 self.struct_name = "CNetMsg_%s" % self.name
244 self.enum_name = "NETMSGTYPE_%s" % self.name.upper()
245 def emit_unpack(self):
246 lines = []
247 lines += ["case %s:" % self.enum_name]
248 lines += ["{"]
249 lines += ["\t%s *pMsg = (%s *)m_aMsgData;" % (self.struct_name, self.struct_name)]
250 lines += ["\t(void)pMsg;"]
251 for v in self.variables:
252 lines += ["\t"+line for line in v.emit_unpack()]
253 for v in self.variables:
254 lines += ["\t"+line for line in v.emit_unpack_check()]
255 lines += ["} break;"]
256 return lines
257 def emit_declaration(self):
258 extra = []
259 extra += ["\tint MsgID() const { return %s; }" % self.enum_name]
260 extra += ["\t"]
261 extra += ["\tbool Pack(CMsgPacker *pPacker)"]
262 extra += ["\t{"]
263 #extra += ["\t\tmsg_pack_start(%s, flags);"%self.enum_name]
264 for v in self.variables:
265 extra += ["\t\t"+line for line in v.emit_pack()]
266 extra += ["\t\treturn pPacker->Error() != 0;"]
267 extra += ["\t}"]
270 lines = NetObject.emit_declaration(self)
271 lines = lines[:-1] + extra + lines[-1:]
272 return lines
275 class NetVariable:
276 def __init__(self, name):
277 self.name = name
278 def emit_declaration(self):
279 return []
280 def emit_validate(self):
281 return []
282 def emit_pack(self):
283 return []
284 def emit_unpack(self):
285 return []
286 def emit_unpack_check(self):
287 return []
289 class NetString(NetVariable):
290 def emit_declaration(self):
291 return ["const char *%s;"%self.name]
292 def emit_unpack(self):
293 return ["pMsg->%s = pUnpacker->GetString();" % self.name]
294 def emit_pack(self):
295 return ["pPacker->AddString(%s, -1);" % self.name]
297 class NetStringStrict(NetVariable):
298 def emit_declaration(self):
299 return ["const char *%s;"%self.name]
300 def emit_unpack(self):
301 return ["pMsg->%s = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);" % self.name]
302 def emit_pack(self):
303 return ["pPacker->AddString(%s, -1);" % self.name]
305 class NetIntAny(NetVariable):
306 def emit_declaration(self):
307 return ["int %s;"%self.name]
308 def emit_unpack(self):
309 return ["pMsg->%s = pUnpacker->GetInt();" % self.name]
310 def emit_pack(self):
311 return ["pPacker->AddInt(%s);" % self.name]
313 class NetIntRange(NetIntAny):
314 def __init__(self, name, min, max):
315 NetIntAny.__init__(self,name)
316 self.min = str(min)
317 self.max = str(max)
318 def emit_validate(self):
319 return ["ClampInt(\"%s\", pObj->%s, %s, %s);"%(self.name,self.name, self.min, self.max)]
320 def emit_unpack_check(self):
321 return ["if(pMsg->%s < %s || pMsg->%s > %s) { m_pMsgFailedOn = \"%s\"; break; }" % (self.name, self.min, self.name, self.max, self.name)]
323 class NetBool(NetIntRange):
324 def __init__(self, name):
325 NetIntRange.__init__(self,name,0,1)
327 class NetTick(NetIntRange):
328 def __init__(self, name):
329 NetIntRange.__init__(self,name,0,'max_int')