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)
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