예제 #1
0
 def __init__(self) :
     self.properties = PropertyTable()
     self.property_types = dict() # name -> Property
     self.inv_property_types = dict() # Property -> name
     self.modified_properties = dict()
     self.game_defined = False
     self.relations = dict()
     self.relation_handlers = []
     self.name_to_relation = dict()
     self._activities = dict()
     self.activity = ActivityHelperObject(self)
예제 #2
0
class World(object) :
    def __init__(self) :
        self.properties = PropertyTable()
        self.property_types = dict() # name -> Property
        self.inv_property_types = dict() # Property -> name
        self.modified_properties = dict()
        self.game_defined = False
        self.relations = dict()
        self.relation_handlers = []
        self.name_to_relation = dict()
        self._activities = dict()
        self.activity = ActivityHelperObject(self)
    def set_game_defined(self) :
        """Set when it's time to close off arbitrary property
        definitions."""
        self.game_defined = True
    def __setitem__(self, item, value) :
        if self.game_defined :
            self.modified_properties[item] = value
        else :
            self.properties[item] = value
    def __getitem__(self, item) :
        if self.modified_properties.has_key(item) :
            return self.modified_properties[item]
        return self.properties.get_property(item, {"world" : self})
    def handler(self, item) :
        return self.properties.handler(item)

    def _make_property(self, numargs, name) :
        class _NewProperty(BasicPattern) :
            def __init__(self, *args) :
                if len(args) != numargs :
                    raise Exception("Property requires exactly "+str(numargs)+" arguments.")
                self.args = args
        _NewProperty.__name__ = name
        return self.define_property(_NewProperty)
    def define_property(self, prop) :
        if self.property_types.has_key(prop.__name__) :
            raise Exception("Property with name %r already defined" % prop.__name__)
        self.property_types[prop.__name__] = prop
        self.inv_property_types[prop] = prop.__name__
        return prop
    def set_property(self, name, *args, **kwargs) :
        """This is __setitem__ but by the registered name of the property."""
        self[self.property_types[name](*args)] = kwargs["value"]
    def get_property(self, name, *args) :
        """This is __getitem__ but by name."""
        return self[self.property_types[name](*args)]

    def add_relation(self, relation) :
        relation.add_relation(self.relations[type(relation)])
    def remove_relation(self, relation) :
        relation.remove_relation(self.relations[type(relation)])
    def define_relation(self, r) :
        if self.game_defined :
            raise Exception("Can't define new relation when game is defined.")
        self.relation_handlers.append(r)
        self.relations[r] = r.setup_table()
        self.name_to_relation[r.__name__] = r
        return r
    def query_relation(self, relation, var=None) :
        res = relation.query_relation(self.relations[type(relation)])
        if var is None :
            return res
        else :
            return [r[var.varName] for r in res]
    def r_path_to(self, r, a, b, **kwargs) :
        return r.path_to(self.relations[r], a, b, **kwargs)
    def get_relation(self, name) :
        return self.name_to_relation[name]

    def define_activity(self, name, **kwargs) :
        self._activities[name] = ActivityTable(**kwargs)
    def to(self, name, **kwargs) :
        if self.game_defined :
            raise Exception("Can't add new actions when game is defined.")
        def _to(f) :
            if not self._activities.has_key(name) :
                self._activities[name] = ActivityTable()
            self._activities[name].add_handler(f, **kwargs)
            return f
        return _to
    def call_activity(self, name, *args, **kwargs) :
        data = {"world" : self}
        data.update(kwargs)
        return self._activities[name].notify(args, data)
    def activity_table(self, name) :
        """Gets the action table of the given name."""
        return self._activities[name]

    def copy(self) :
        """Makes a copy of the world which behaves the same as the
        present one, but is disconnected.  However, the values of
        modified_properties are not copied but referenced."""
        newworld = World()
        newworld.properties = self.properties.copy()
        newworld.property_types = self.property_types.copy()
        newworld.inv_property_types = self.inv_property_types.copy() # Property -> name
        for k,v in self.modified_properties.iteritems() :
            newworld.modified_properties[k] = v
        newworld.game_defined = self.game_defined
        for r,data in self.relations.iteritems() :
            newworld.relations[r] = r.copy(data)
        newworld.relation_handlers = list(self.relation_handlers)
        newworld.name_to_relation = self.name_to_relation.copy()
        for name, table in self._activities.iteritems() :
            newworld._activities[name] = table.copy()
        return newworld
    def serialize(self) :
        import pickle
        mp = []
        for k,v in self.modified_properties.iteritems() :
            mp.append((self.inv_property_types[type(k)], k.args, v))
        return pickle.dumps((mp, self.relations))
    def deserialize(self, data) :
        import pickle
        import copy
        mp, rel = pickle.loads(data)
        newworld = copy.copy(self)
        newworld.modified_properties = dict()
        for name, args, v in mp :
            newworld.modified_properties[self.property_types[name](*args)] = v
        newworld.relations = rel
        return newworld

    def dump(self) :
        print "**Property table:**"
        self.properties.dump()
        print "\n**Modified property table:**"
        for k,v in self.modified_properties.iteritems() :
            print "%r = %r" % (k,v)
        print "\n**Relation tables:**"
        for r in self.relation_handlers :
            print " * For %s *" % r.__name__
            r.dump(self.relations[r])
    def make_documentation(self, escape, heading_level=1) :
        hls = str(heading_level)
        print "<h"+hls+">World</h"+hls+">"
        print "<p>This is the documentation for the game world object.</p>"
        shls = str(heading_level+1)
        print "<h"+shls+">Property table</h"+shls+">"
        self.properties.make_documentation(escape, heading_level=heading_level+2)
        print "<h"+shls+">Relation tables</h"+shls+">"
        sshls = str(heading_level+2)
        for r in self.relation_handlers :
            print "<h"+sshls+">"+escape(r.__name__)+"</h"+sshls+">"
            print "<p><i>"+(escape(r.__doc__) or "(No documentation)")+"</i></p>"
            print "<pre>"
            r.dump(self.relations[r])
            print "</pre>"
        print "<h"+shls+">Activity tables</h"+shls+">"
        for name, table in self._activities.iteritems() :
            print "<h"+sshls+">to "+escape(name)+"</h"+sshls+">"
            table.make_documentation(escape, heading_level=heading_level+3)