Mercurial > fife-parpg
changeset 567:9152ed2b5bb8
Created SimpleXMLSerializer which makes loading and saving variables to an XML file simple. In the process I removed the the XML code from the Settings class. It now uses SimpleXMLSerializer to load and save settings.
I have also updated the RPG demo to use the SimpleXMLSerializer for loading and saving game specific data.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Mon, 28 Jun 2010 18:41:23 +0000 |
parents | 90d369c788c0 |
children | bfbf329e1da8 |
files | demos/rpg/scripts/quests/questmanager.py demos/rpg/scripts/scene.py engine/python/fife/extensions/fife_settings.py |
diffstat | 3 files changed, 35 insertions(+), 214 deletions(-) [+] |
line wrap: on
line diff
--- a/demos/rpg/scripts/quests/questmanager.py Mon Jun 28 15:43:42 2010 +0000 +++ b/demos/rpg/scripts/quests/questmanager.py Mon Jun 28 18:41:23 2010 +0000 @@ -26,7 +26,7 @@ from fife import fife -from fife.extensions.fife_settings import Setting +from fife.extensions.serializers.simplexml import SimpleXMLSerializer from scripts.quests.basequest import Quest, ReturnItemQuest, QuestTypes from scripts.misc.serializer import Serializer @@ -46,7 +46,7 @@ def deserialize(self, valuedict=None): questfile = self._gamecontroller.settings.get("RPG", "QuestFile", "maps/quests.xml") - self._questsettings = Setting(settings_file=questfile) + self._questsettings = SimpleXMLSerializer(questfile) for identifier in self._questsettings.get("QuestGivers", "list", []): for quest in self._questsettings.get(identifier, "questlist", []):
--- a/demos/rpg/scripts/scene.py Mon Jun 28 15:43:42 2010 +0000 +++ b/demos/rpg/scripts/scene.py Mon Jun 28 18:41:23 2010 +0000 @@ -28,7 +28,7 @@ from fife import fife from fife.extensions.loaders import loadMapFile from fife.extensions.loaders import loadImportFile -from fife.extensions.fife_settings import Setting +from fife.extensions.serializers.simplexml import SimpleXMLSerializer from scripts.actors.baseactor import Actor from scripts.actors.questgiver import QuestGiver @@ -120,7 +120,7 @@ playerfilename = os.path.join("saves", "player_save.xml") if os.path.isfile(playerfilename): - player_settings = Setting(settings_file=playerfilename, copy_dist=False) + player_settings = SimpleXMLSerializer(playerfilename) pvals = player_settings.get("player", "player", {}) self._player.deserialize(pvals) @@ -142,8 +142,8 @@ modelfile = self._gamecontroller.settings.get("RPG", "AllObjectFile", "maps/allobjects.xml") questfile = self._gamecontroller.settings.get("RPG", "QuestFile", "maps/quests.xml") - self._objectsettings = Setting(settings_file=objectfile) - self._modelsettings = Setting(settings_file=modelfile) + self._objectsettings = SimpleXMLSerializer(objectfile) + self._modelsettings = SimpleXMLSerializer(modelfile) for cam in self._map.getCameras(): self._cameras[cam.getId()] = cam @@ -236,8 +236,8 @@ def serialize(self): filename = os.path.join("saves", self._mapname + "_save.xml") playerfilename = os.path.join("saves", "player_save.xml") - map_settings = Setting(settings_file=filename, copy_dist=False) - player_settings = Setting(settings_file=playerfilename, copy_dist=False) + map_settings = SimpleXMLSerializer(filename) + player_settings = SimpleXMLSerializer(playerfilename) objectlist = [] @@ -251,8 +251,8 @@ pvals = self._player.serialize() player_settings.set("player", "player", pvals) - map_settings.saveSettings() - player_settings.saveSettings() + map_settings.save() + player_settings.save() def deserialize(self): if self._mapname:
--- a/engine/python/fife/extensions/fife_settings.py Mon Jun 28 15:43:42 2010 +0000 +++ b/engine/python/fife/extensions/fife_settings.py Mon Jun 28 18:41:23 2010 +0000 @@ -38,12 +38,13 @@ from fife.extensions import pychan from fife.extensions.fife_utils import getUserDataDirectory +from fife.extensions.serializers.simplexml import SimpleXMLSerializer + try: import xml.etree.cElementTree as ET except: import xml.etree.ElementTree as ET - SETTINGS_GUI_XML="""\ <Window name="Settings" title="Settings"> <Label text="Settings menu!" /> @@ -78,13 +79,6 @@ </Window> """ -EMPTY_SETTINGS="""\ -<?xml version='1.0' encoding='UTF-8'?> -<Settings> - -</Settings> -""" - FIFE_MODULE = "FIFE" class Setting(object): @@ -123,6 +117,8 @@ # Holds SettingEntries self._entries = {} + + self._xmlserializer = None if self._settings_file == "": self._settings_file = "settings.xml" @@ -142,10 +138,6 @@ if not os.path.exists(os.path.join(self._appdata, self._settings_file)): if os.path.exists('settings-dist.xml') and copy_dist: shutil.copyfile('settings-dist.xml', os.path.join(self._appdata, self._settings_file)) - else: - #no settings file found - tree = ET.parse(StringIO(EMPTY_SETTINGS)) - tree.write(os.path.join(self._appdata, self._settings_file), 'UTF-8') #default settings self._resolutions = ['640x480', '800x600', '1024x768', '1280x800', '1440x900'] @@ -154,9 +146,9 @@ #Used to stylize the options gui self._gui_style = "default" + #Initialize the XML serializer self.loadSettings() - self._initDefaultSettingEntries() def _initDefaultSettingEntries(self): @@ -212,51 +204,12 @@ print "It's probably missing in settings-dist.xml as well!" def loadSettings(self): - self._tree = ET.parse(os.path.join(self._appdata, self._settings_file)) - - self._root_element = self._tree.getroot() - self.validateTree() - - def setGuiStyle(self, style): - """ Set a custom gui style used for the option dialog. - @param style: Pychan style to be used - @type style: C{string} - """ - self._gui_style = style + self._xmlserializer = SimpleXMLSerializer(os.path.join(self._appdata, self._settings_file)) - def validateTree(self): - """ Iterates the settings tree and prints warning when an invalid tag is found """ - for c in self._root_element.getchildren(): - if c.tag != "Module": - print "Invalid tag in settings.xml. Expected Module, got: ", c.tag - elif c.get("name", "") == "": - print "Invalid tag in settings.xml. Module name is empty." - else: - for e in c.getchildren(): - if e.tag != "Setting": - print "Invalid tag in settings.xml in module: ",c.tag, - print ". Expected Setting, got: ", e.tag - elif c.get("name", "") == "": - print "Invalid tag in settings.xml in module: ",c.tag, - print ". Setting name is empty", e.tag - - def getModuleTree(self, module): - """ - Returns a module element from the settings tree. If no module with the specified - name exists, a new element will be created. - - @param module: The module to get from the settings tree - @type module: C{string} - """ - if not isinstance(module, str) and not isinstance(module, unicode): - raise AttributeError("Settings:getModuleTree: Invalid type for module argument.") - - for c in self._root_element.getchildren(): - if c.tag == "Module" and c.get("name", "") == module: - return c - - # Create module - return ET.SubElement(self._root_element, "Module", {"name":module}) + def saveSettings(self): + """ Writes the settings to the settings file """ + if self._xmlserializer: + self._xmlserializer.save() def get(self, module, name, defaultValue=None): """ Gets the value of a specified setting @@ -266,55 +219,11 @@ @param defaultValue: Specifies the default value to return if the setting is not found @type defaultValue: C{str} or C{unicode} or C{int} or C{float} or C{bool} or C{list} or C{dict} """ - if not isinstance(name, str) and not isinstance(name, unicode): - raise AttributeError("Settings:get: Invalid type for name argument.") - - moduleTree = self.getModuleTree(module) - element = None - for e in moduleTree.getchildren(): - if e.tag == "Setting" and e.get("name", "") == name: - element = e - break + if self._xmlserializer: + return self._xmlserializer.get(module, name, defaultValue) else: - return defaultValue - - e_value = element.text - e_strip = element.get("strip", "1").strip().lower() - e_type = str(element.get("type", "str")).strip() - - if e_value is None: - return defaultValue - - # Strip value - if e_strip == "" or e_strip == "false" or e_strip == "no" or e_strip == "0": - e_strip = False - else: e_strip = True - - if e_type == "str" or e_type == "unicode": - if e_strip: e_value = e_value.strip() - else: - e_value = e_value.strip() - - # Return value - if e_type == 'int': - return int(e_value) - elif e_type == 'float': - return float(e_value) - elif e_type == 'bool': - e_value = e_value.lower() - if e_value == "" or e_value == "false" or e_value == "no" or e_value == "0": - return False - else: - return True - elif e_type == 'str': - return str(e_value) - elif e_type == 'unicode': - return unicode(e_value) - elif e_type == 'list': - return self._deserializeList(e_value) - elif e_type == 'dict': - return self._deserializeDict(e_value) - + return None + def set(self, module, name, value, extra_attrs={}): """ Sets a setting to specified value. @@ -326,103 +235,16 @@ @param extra_attrs: Extra attributes to be stored in the XML-file @type extra_attrs: C{dict} """ - if not isinstance(name, str) and not isinstance(name, unicode): - raise AttributeError("Settings:set: Invalid type for name argument.") - - moduleTree = self.getModuleTree(module) - e_type = "str" + if self._xmlserializer: + self._xmlserializer.set(module, name, value, extra_attrs) - if isinstance(value, bool): # This must be before int - e_type = "bool" - value = str(value) - elif isinstance(value, int): - e_type = "int" - value = str(value) - elif isinstance(value, float): - e_type = "float" - value = str(value) - elif isinstance(value, unicode): - e_type = "unicode" - value = unicode(value) - elif isinstance(value, list): - e_type = "list" - value = self._serializeList(value) - elif isinstance(value, dict): - e_type = "dict" - value = self._serializeDict(value) - else: - e_type = "str" - value = str(value) - - for e in moduleTree.getchildren(): - if e.tag != "Setting": continue - if e.get("name", "") == name: - e.text = value - break - else: - attrs = {"name":name, "type":e_type} - for k in extra_attrs: - if k not in attrs: - attrs[k] = extra_args[k] - elm = ET.SubElement(moduleTree, "Setting", attrs) - elm.text = value - - def saveSettings(self): - """ Writes the settings to the settings file """ - self._indent(self._root_element) - self._tree.write(os.path.join(self._appdata, self._settings_file), 'UTF-8') - - def _indent(self, elem, level=0): + def setGuiStyle(self, style): + """ Set a custom gui style used for the option dialog. + @param style: Pychan style to be used + @type style: C{string} """ - Adds whitespace, so the resulting XML-file is properly indented. - Shamelessly stolen from http://effbot.org/zone/element-lib.htm - """ - i = "\n" + level*" " - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + " " - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for elem in elem: - self._indent(elem, level+1) - if not elem.tail or not elem.tail.strip(): - elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i - - # FIXME: - # These serialization functions are not reliable at all - # This will only serialize the first level of a dict or list - # It will not check the types nor the content for conflicts. - # Perhaps we should add a small serialization library? - def _serializeList(self, list): - """ Serializes a list, so it can be stored in a text file """ - return " ; ".join(list) - - def _deserializeList(self, string): - """ Deserializes a list back into a list object """ - return string.split(" ; ") - - def _serializeDict(self, dict): - """ Serializes a list, so it can be stored in a text file """ - serial = "" - for key in dict: - value = dict[key] - if serial != "": serial += " ; " - serial += str(key)+" : "+str(value) - - return serial - - def _deserializeDict(self, serial): - """ Deserializes a list back into a dict object """ - dict = {} - items = serial.split(" ; ") - for i in items: - kv_pair = i.split(" : ") - dict[kv_pair[0]] = kv_pair[1] - return dict - + self._gui_style = style + def onOptionsPress(self): """ Opens the options dialog box. Usually you would bind this to a button. @@ -447,7 +269,6 @@ else: return pychan.loadXML(StringIO(dialog)) - def fillWidgets(self): for module in self._entries.itervalues(): for entry in module.itervalues(): @@ -518,10 +339,10 @@ shutil.copyfile('settings-dist.xml', os.path.join(self._appdata, self._settings_file)) self.changesRequireRestart = True self.loadSettings() - self._showChangeRequireRestartDialog() + #self._showChangeRequireRestartDialog() - if self.OptionsDlg: - self.OptionsDlg.hide() + #if self.OptionsDlg: + # self.OptionsDlg.hide() def _getEntries(self): return self._entries