Make ContentsHandler retain insert order
This commit is contained in:
parent
5e2372f79d
commit
4582eb4085
2 changed files with 43 additions and 17 deletions
|
|
@ -41,11 +41,15 @@ class ContentsHandler:
|
||||||
obj (Object): The object on which the
|
obj (Object): The object on which the
|
||||||
handler is defined
|
handler is defined
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
This was changed from using `set` to using `dict` internally
|
||||||
|
in order to retain insertion order.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
self._pkcache = set()
|
self._pkcache = {}
|
||||||
self._idcache = obj.__class__.__instance_cache__
|
self._idcache = obj.__class__.__instance_cache__
|
||||||
self._typecache = defaultdict(set)
|
self._typecache = defaultdict(dict)
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
|
|
@ -63,10 +67,10 @@ class ContentsHandler:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
objects = self.load()
|
objects = self.load()
|
||||||
self._pkcache = {obj.pk for obj in objects}
|
self._pkcache = {obj.pk: True for obj in objects}
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
for ctype in obj._content_types:
|
for ctype in obj._content_types:
|
||||||
self._typecache[ctype].add(obj.pk)
|
self._typecache[ctype][obj.pk] = True
|
||||||
|
|
||||||
def get(self, exclude=None, content_type=None):
|
def get(self, exclude=None, content_type=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -81,11 +85,11 @@ class ContentsHandler:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if content_type is not None:
|
if content_type is not None:
|
||||||
pks = self._typecache[content_type]
|
pks = self._typecache[content_type].keys()
|
||||||
else:
|
else:
|
||||||
pks = self._pkcache
|
pks = self._pkcache.keys()
|
||||||
if exclude:
|
if exclude:
|
||||||
pks = pks - {excl.pk for excl in make_iter(exclude)}
|
pks = set(pks) - {excl.pk for excl in make_iter(exclude)}
|
||||||
try:
|
try:
|
||||||
return [self._idcache[pk] for pk in pks]
|
return [self._idcache[pk] for pk in pks]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
@ -107,9 +111,9 @@ class ContentsHandler:
|
||||||
obj (Object): object to add
|
obj (Object): object to add
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._pkcache.add(obj.pk)
|
self._pkcache[obj.pk] = obj
|
||||||
for ctype in obj._content_types:
|
for ctype in obj._content_types:
|
||||||
self._typecache[ctype].add(obj.pk)
|
self._typecache[ctype][obj.pk] = True
|
||||||
|
|
||||||
def remove(self, obj):
|
def remove(self, obj):
|
||||||
"""
|
"""
|
||||||
|
|
@ -119,15 +123,10 @@ class ContentsHandler:
|
||||||
obj (Object): object to remove
|
obj (Object): object to remove
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
self._pkcache.pop(obj.pk, None)
|
||||||
self._pkcache.remove(obj.pk)
|
|
||||||
except KeyError:
|
|
||||||
# not in pk cache, but can happen deletions happens
|
|
||||||
# remotely from out-of-thread.
|
|
||||||
pass
|
|
||||||
for ctype in obj._content_types:
|
for ctype in obj._content_types:
|
||||||
if obj.pk in self._typecache[ctype]:
|
if obj.pk in self._typecache[ctype]:
|
||||||
self._typecache[ctype].remove(obj.pk)
|
self._typecache[ctype].pop(obj.pk, None)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -135,7 +134,7 @@ class ContentsHandler:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._pkcache = {}
|
self._pkcache = {}
|
||||||
self._typecache = defaultdict(set)
|
self._typecache = defaultdict(dict)
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,3 +199,30 @@ class TestContentHandler(BaseEvenniaTest):
|
||||||
set(self.room1.contents_get(content_type="character")), set([self.char1, self.char2])
|
set(self.room1.contents_get(content_type="character")), set([self.char1, self.char2])
|
||||||
)
|
)
|
||||||
self.assertEqual(set(self.room1.contents_get(content_type="exit")), set([self.exit]))
|
self.assertEqual(set(self.room1.contents_get(content_type="exit")), set([self.exit]))
|
||||||
|
|
||||||
|
def test_contents_order(self):
|
||||||
|
"""Move object from room to room in various ways"""
|
||||||
|
self.assertEqual(self.room1.contents, [
|
||||||
|
self.exit, self.obj1, self.obj2, self.char1, self.char2])
|
||||||
|
self.assertEqual(self.room2.contents, [])
|
||||||
|
|
||||||
|
# use move_to hook to move obj1
|
||||||
|
self.obj1.move_to(self.room2)
|
||||||
|
self.assertEqual(self.room1.contents, [self.exit, self.obj2, self.char1, self.char2 ])
|
||||||
|
self.assertEqual(self.room2.contents, [self.obj1])
|
||||||
|
|
||||||
|
# move obj2
|
||||||
|
self.obj2.move_to(self.room2)
|
||||||
|
self.assertEqual(self.room1.contents, [self.exit, self.char1, self.char2 ])
|
||||||
|
self.assertEqual(self.room2.contents, [self.obj1, self.obj2])
|
||||||
|
|
||||||
|
# move back and forth - it should
|
||||||
|
self.obj1.move_to(self.room1)
|
||||||
|
self.assertEqual(self.room1.contents, [self.exit, self.char1, self.char2, self.obj1])
|
||||||
|
self.obj1.move_to(self.room2)
|
||||||
|
self.assertEqual(self.room2.contents, [self.obj2, self.obj1])
|
||||||
|
|
||||||
|
# use move_to hook
|
||||||
|
self.obj2.move_to(self.room1)
|
||||||
|
self.obj2.move_to(self.room2)
|
||||||
|
self.assertEqual(self.room2.contents, [self.obj1, self.obj2])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue