Пример #1
0
 def __init__(self):
     self.db = Database()
     self.cache = {}
     self.live_set = set() # The live set tracks ThingProxies that are keeping Things loaded
     self.cache_task = task.LoopingCall(self.purge_cache)
     self.cache_task.start(300)
     self.ThingProxy = ThingProxyFactory(self)
Пример #2
0
class World(object):
    """
    The World class represents the game world. It manages the collection of objects that together comprise the world.
    """

    def __init__(self):
        self.db = Database()
        self.cache = {}
        self.live_set = set() # The live set tracks ThingProxies that are keeping Things loaded
        self.cache_task = task.LoopingCall(self.purge_cache)
        self.cache_task.start(300)
        self.ThingProxy = ThingProxyFactory(self)

    def close(self):
        # Immediately purge (and save, if neccessary) all cached objects
        self.purge_cache(-1)
        self.db.close()
    
    def connect(self, username, password=None):
        """Connects a player to the world."""
        if password is not None:
            obj = self.db.player_login(username, password)
            if obj == -1: return None
        else:
            obj = self.db.get_player_id(username)
        return self.get_thing(obj) if obj else None

    def get_thing(self, obj):
        """
        Retrieves the Thing with the given database ID.

        Actually returns a ThingProxy that facilitates lazy-loading of Things and
        allows Things to be unloaded in the background to save memory, and transparently
        loaded again upon demand.
        """
        if not obj in self.cache:
            log(LogLevel.Trace, "Cache: MISS #{0}".format(obj))
            return self.ThingProxy(self, obj)
        else:
            log(LogLevel.Trace, "Cache: Hit #{0}".format(obj))
            return self.cache[obj]

    def purge_cache(self, expiry=3600): #TODO: Rename this function?
        """
        Remove from the cache all cached objects older than the given time.
        
        Save any objects that have been modified since they were cached.
        """
        threshold = int(time.time()) - expiry # Threshold is a time in the past
        cachesize = len(self.cache)
        #self.cache = [x for x in self.cache if x[1] > threshold]
        objects = self.live_set.copy()
        for obj in objects:
            if obj.cachetime < threshold:
                obj.unload() # Save and unload the object
            elif obj.dirty:
                obj.save()
        log(LogLevel.Trace, "Cache: Purged {0} stale objects from memory".format(len(objects)-len(self.live_set)))

    def get_contents(self, thing):
        """Returns a tuple of Things that the given Thing contains."""
        try:
            # Get list of IDs
            items = self.db.get_contents(thing.id)
            # Get Things and return them
            return map(lambda x: self.get_thing(x), items)
        except AttributeError:
            raise TypeError("Expected a Thing as argument")

    def save_thing(self, thing):
        #TODO: Review this function vs. calling thing.force_save()
        # Save Thing basic info
        self.db.save_object(thing)
        # Save any modified properties of the Thing
        for prop in thing._propdirty:
            self.db.set_property(thing.id, prop, thing._propcache[prop])

    def find_user(self, name):
        """
        Find a connected user by the given character name.
        """
        #TODO: Return user
        pass

    def list_players(self):
        """
        Return a list of all connected characters as Player objects.
        """
        pass