• R/O
  • SSH

Commit

Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Just a simple, and painful to use calculator for the game Factorio written in Python


Commit MetaInfo

Révision462d2d0e4160c79b389278dde46bd2e215989fd7 (tree)
l'heure2018-02-03 03:37:30
AuteurEric Hopper <hopper@omni...>
CommiterEric Hopper

Message de Log

Added code to read and parse XML database.

Change Summary

Modification

diff -r 92eacb0dd71e -r 462d2d0e4160 factorio_calc.py
--- a/factorio_calc.py Mon Dec 18 08:05:13 2017 -0800
+++ b/factorio_calc.py Fri Feb 02 10:37:30 2018 -0800
@@ -5,7 +5,11 @@
55 import sys
66 from collections import namedtuple
77 import re
8+from xml.etree import ElementTree
89
10+def _checkXMLHasNoText(xmlel):
11+ return ((xmlel.text is None) or (xmlel.text.strip() == '')) \
12+ and ((xmlel.tail is None) or (xmlel.tail.strip() == ''))
913
1014 class ProductionItem:
1115 __slots__ = ('_name', '_time', '_ingredients', '_produced', '__weakref__')
@@ -17,7 +21,6 @@
1721 self._time = time
1822 def lookup_ingredients(ingredients):
1923 for ct, item in ingredients:
20- print(f"Lookup up ({ct}, {item!s})", file=sys.stderr)
2124 if not isinstance(item, ProductionItem):
2225 item = item_db[item]
2326 print(f"Wasn't already an item, found {item!s}",
@@ -113,6 +116,67 @@
113116 yield from self._itemAsXML(item, item_idmap)
114117 yield '</factorio_calc_item_db>\n'
115118
119+ @staticmethod
120+ def createFromXML(infile):
121+ newdb = ItemSet()
122+ ET = ElementTree
123+ parser = ET.XMLParser()
124+ block = infile.read(4 * 1024 * 1024)
125+ while len(block) > 0:
126+ parser.feed(block)
127+ block = infile.read(4 * 1024 * 1024)
128+ block = None
129+ tree = parser.close()
130+ parser = None
131+ if tree.tag != 'factorio_calc_item_db':
132+ raise ValueError("Not an XML item database.")
133+ if tree.attrib.get('version', '1.0') != '1.0':
134+ raise ValueError(f"Do not know how to handle version "
135+ f"{tree.attrib['version']}.")
136+ if not _checkXMLHasNoText(tree):
137+ raise ValueError("Invalid XML database.")
138+ item_idmap = {}
139+ for itemel in tree.getchildren():
140+ itemid, item = ItemSet.itemFromXML(item_idmap, itemel)
141+ item_idmap[itemid] = item
142+ newdb.add(item)
143+ return newdb
144+
145+ @staticmethod
146+ def itemFromXML(item_idmap, itemel):
147+ if itemel.tag != 'item':
148+ raise ValueError(f"Got element '{itemel.tag}', expecting 'item'.")
149+ itemid = itemel.attrib['id']
150+ if not _checkXMLHasNoText(itemel):
151+ raise ValueError(f"Invalid item {itemid}")
152+ if itemid in item_idmap:
153+ raise ValueError(f"Item {itemid} defined twice.")
154+ name = itemel.attrib['name']
155+ time = itemel.attrib.get('time', None)
156+ produced = itemel.attrib.get('produced', None)
157+ if (produced is None) != (time is None):
158+ raise ValueError(f"Invalid item '{itemid}'.")
159+ if time is not None:
160+ time = _F(time)
161+ produced = int(produced)
162+ ingredients = []
163+ for ingredientel in itemel.getchildren():
164+ if ingredientel.tag != 'ingredient':
165+ raise ValueError(f"Item {itemid} has {ingredientel.tag}")
166+ ingid = ingredientel.attrib['idref']
167+ if not _checkXMLHasNoText(ingredientel):
168+ raise ValueError(f"Invalid ingredient '{ingid}' in '{itemid}'")
169+ ingcount = int(ingredientel.attrib['count'])
170+ if ingid not in item_idmap:
171+ raise ValueError(f"Item '{itemid}' mentions ingredient "
172+ f"'{ingid}' before it's defined.")
173+ ingredients.append((ingcount, item_idmap[ingid]))
174+ if (len(ingredients) > 0) and (time is None):
175+ raise ValueError(f"Item '{itemid}' has ingredients but "
176+ "no production time.")
177+ return (itemid,
178+ ProductionItem(name, time, tuple(ingredients), produced))
179+
116180 _mod_dir = _osp.dirname(__file__)
117181 db_fname = _osp.join(_mod_dir, 'item-db.pickle')
118182
diff -r 92eacb0dd71e -r 462d2d0e4160 item-db.pickle
Binary file item-db.pickle has changed