Added CharactersHandler to account and altered all calls of add/remove characters to use it.
This commit is contained in:
parent
3c4a3f1088
commit
2bf96f7c7f
11 changed files with 112 additions and 63 deletions
|
|
@ -120,6 +120,80 @@ class AccountSessionHandler(object):
|
|||
return len(self.get())
|
||||
|
||||
|
||||
class CharactersHandler:
|
||||
"""
|
||||
A simple Handler that lives on DefaultAccount as .characters via @lazy_property used to
|
||||
wrap access to .db._playable_characters.
|
||||
"""
|
||||
|
||||
def __init__(self, owner: "DefaultAccount"):
|
||||
"""
|
||||
Create the CharactersHandler.
|
||||
|
||||
Args:
|
||||
owner: The Account that owns this handler.
|
||||
"""
|
||||
self.owner = owner
|
||||
self._ensure_playable_characters()
|
||||
self._clean()
|
||||
|
||||
def _ensure_playable_characters(self):
|
||||
if self.owner.db._playable_characters is None:
|
||||
self.owner.db._playable_characters = []
|
||||
|
||||
def _clean(self):
|
||||
# Remove all instances of None from the list.
|
||||
self.owner.db._playable_characters = [x for x in self.owner.db._playable_characters if x]
|
||||
|
||||
def add(self, character: "DefaultCharacter"):
|
||||
"""
|
||||
Add a character to this account's list of playable characters.
|
||||
|
||||
Args:
|
||||
character (DefaultCharacter): The character to add.
|
||||
"""
|
||||
self._clean()
|
||||
if character not in self.owner.db._playable_characters:
|
||||
self.owner.db._playable_characters.append(character)
|
||||
self.owner.at_post_add_character(character)
|
||||
|
||||
def remove(self, character: "DefaultCharacter"):
|
||||
"""
|
||||
Remove a character from this account's list of playable characters.
|
||||
|
||||
Args:
|
||||
character (DefaultCharacter): The character to remove.
|
||||
"""
|
||||
self._clean()
|
||||
if character in self.owner.db._playable_characters:
|
||||
self.owner.db._playable_characters.remove(character)
|
||||
self.owner.at_post_remove_character(character)
|
||||
|
||||
def all(self) -> list["DefaultCharacter"]:
|
||||
"""
|
||||
Get all playable characters.
|
||||
|
||||
Returns:
|
||||
list[DefaultCharacter]: All playable characters.
|
||||
"""
|
||||
self._clean()
|
||||
return list(self.owner.db._playable_characters)
|
||||
|
||||
def count(self) -> int:
|
||||
"""
|
||||
Get the number of playable characters.
|
||||
|
||||
Returns:
|
||||
int: The number of playable characters.
|
||||
"""
|
||||
return len(self.all())
|
||||
|
||||
__len__ = count
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.all())
|
||||
|
||||
|
||||
class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
||||
"""
|
||||
This is the base Typeclass for all Accounts. Accounts represent
|
||||
|
|
@ -219,56 +293,32 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
|||
load_kwargs={"category": "option"},
|
||||
)
|
||||
|
||||
# Do not make this a lazy property; the web UI will not refresh it!
|
||||
@property
|
||||
@lazy_property
|
||||
def characters(self):
|
||||
# Get playable characters list
|
||||
objs = self.db._playable_characters or []
|
||||
return CharactersHandler(self)
|
||||
|
||||
# Rebuild the list if legacy code left null values after deletion
|
||||
try:
|
||||
if None in objs:
|
||||
objs = [x for x in self.db._playable_characters if x]
|
||||
self.db._playable_characters = objs
|
||||
except Exception as e:
|
||||
logger.log_trace(e)
|
||||
logger.log_err(e)
|
||||
|
||||
return objs
|
||||
|
||||
def add_character_to_playable_list(self, character: "DefaultCharacter"):
|
||||
"""
|
||||
Add a character to this account's list of playable characters.
|
||||
"""
|
||||
if character not in self.db._playable_characters:
|
||||
self.db._playable_characters.append(character)
|
||||
self.at_post_add_character_to_playable_list(character)
|
||||
|
||||
def at_post_add_character_to_playable_list(self, character: "DefaultCharacter"):
|
||||
def at_post_add_character(self, character: "DefaultCharacter"):
|
||||
"""
|
||||
Called after a character is added to this account's list of playable characters.
|
||||
|
||||
Use it to easily implement custom logic when a character is added to an account.
|
||||
|
||||
Args:
|
||||
character (DefaultCharacter): The character that was added.
|
||||
"""
|
||||
pass
|
||||
|
||||
def remove_character_from_playable_list(self, character):
|
||||
"""
|
||||
Remove a character from this account's list of playable characters.
|
||||
"""
|
||||
if character in self.db._playable_characters:
|
||||
self.db._playable_characters.remove(character)
|
||||
self.at_post_remove_character_from_playable_list(character)
|
||||
|
||||
def at_post_remove_character_from_playable_list(self, character):
|
||||
def at_post_remove_character(self, character: "DefaultAccount"):
|
||||
"""
|
||||
Called after a character is removed from this account's list of playable characters.
|
||||
|
||||
Use it to easily implement custom logic when a character is removed from an account.
|
||||
|
||||
Args:
|
||||
character (DefaultCharacter): The character that was removed.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def uses_screenreader(self, session=None):
|
||||
"""
|
||||
Shortcut to determine if a session uses a screenreader. If no session given,
|
||||
|
|
@ -776,7 +826,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
|||
)
|
||||
if character:
|
||||
# Update playable character list
|
||||
self.add_character_to_playable_list(character)
|
||||
self.characters.add(character)
|
||||
|
||||
# We need to set this to have @ic auto-connect to this character
|
||||
self.db._last_puppet = character
|
||||
|
|
|
|||
|
|
@ -105,14 +105,14 @@ class TestDefaultGuest(BaseEvenniaTest):
|
|||
def test_at_server_shutdown(self):
|
||||
account, errors = DefaultGuest.create(ip=self.ip)
|
||||
self.char1.delete = MagicMock()
|
||||
account.add_character_to_playable_list(self.char1)
|
||||
account.characters.add(self.char1)
|
||||
account.at_server_shutdown()
|
||||
self.char1.delete.assert_called()
|
||||
|
||||
def test_at_post_disconnect(self):
|
||||
account, errors = DefaultGuest.create(ip=self.ip)
|
||||
self.char1.delete = MagicMock()
|
||||
account.add_character_to_playable_list(self.char1)
|
||||
account.characters.add(self.char1)
|
||||
account.at_post_disconnect()
|
||||
self.char1.delete.assert_called()
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ class TestAccountPuppetDeletion(BaseEvenniaTest):
|
|||
)
|
||||
|
||||
# Add char1 to account's playable characters
|
||||
self.account.add_character_to_playable_list(self.char1)
|
||||
self.account.characters.add(self.char1)
|
||||
self.assertTrue(self.account.characters, "Char was not added to account.")
|
||||
|
||||
# See what happens when we delete char1.
|
||||
|
|
@ -383,20 +383,19 @@ class TestDefaultAccountEv(BaseEvenniaTest):
|
|||
def test_characters_property(self):
|
||||
"test existence of None in _playable_characters Attr"
|
||||
self.account.db._playable_characters = [self.char1, None]
|
||||
chars = self.account.characters
|
||||
self.assertEqual(chars, [self.char1])
|
||||
self.assertEqual(self.account.characters.all(), [self.char1])
|
||||
self.assertEqual(self.account.db._playable_characters, [self.char1])
|
||||
|
||||
def test_add_character_to_playable_list(self):
|
||||
self.assertEqual(self.account.characters, [])
|
||||
self.account.add_character_to_playable_list(self.char1)
|
||||
self.assertEqual(self.account.characters, [self.char1])
|
||||
self.assertEqual(self.account.characters.all(), [])
|
||||
self.account.characters.add(self.char1)
|
||||
self.assertEqual(self.account.characters.all(), [self.char1])
|
||||
|
||||
def test_remove_character_from_playable_list(self):
|
||||
self.account.add_character_to_playable_list(self.char1)
|
||||
self.assertEqual(self.account.characters, [self.char1])
|
||||
self.account.remove_character_from_playable_list(self.char1)
|
||||
self.assertEqual(self.account.characters, [])
|
||||
self.account.characters.add(self.char1)
|
||||
self.assertEqual(self.account.characters.all(), [self.char1])
|
||||
self.account.characters.remove(self.char1)
|
||||
self.assertEqual(self.account.characters.all(), [])
|
||||
|
||||
def test_puppet_success(self):
|
||||
self.account.msg = MagicMock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue