mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Cleanup of options methods, callables
This commit is contained in:
parent
6ddc98a947
commit
f2d9391827
3 changed files with 90 additions and 58 deletions
|
|
@ -35,32 +35,34 @@ class Container(object):
|
|||
"""
|
||||
self.loaded_data = None
|
||||
|
||||
def _load_data(self):
|
||||
def load_data(self):
|
||||
"""
|
||||
Delayed import to avoid eventual circular imports from inside
|
||||
the storage modules.
|
||||
|
||||
"""
|
||||
if self.loaded_data is None:
|
||||
self.loaded_data = {}
|
||||
for module in self.storage_modules:
|
||||
self.loaded_data.update(callables_from_module(module))
|
||||
|
||||
def __getattr__(self, key):
|
||||
self._load_data()
|
||||
return self.loaded_data.get(key)
|
||||
return self.get(key)
|
||||
|
||||
def get(self, key):
|
||||
def get(self, key, default=None):
|
||||
"""
|
||||
Retrive data by key (in case of not knowing it beforehand).
|
||||
|
||||
Args:
|
||||
key (str): The name of the script.
|
||||
default (any, optional): Value to return if key is not found.
|
||||
|
||||
Returns:
|
||||
any (any): The data loaded on this container.
|
||||
|
||||
"""
|
||||
return self.__getattr__(key)
|
||||
self.load_data()
|
||||
return self.loaded_data.get(key, default)
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
|
|
@ -70,7 +72,7 @@ class Container(object):
|
|||
scripts (list): All global script objects stored on the container.
|
||||
|
||||
"""
|
||||
self._load_data()
|
||||
self.load_data()
|
||||
return list(self.loaded_data.values())
|
||||
|
||||
|
||||
|
|
@ -121,12 +123,7 @@ class GlobalScriptContainer(Container):
|
|||
self.script_storage = {}
|
||||
self.typeclass_storage = None
|
||||
|
||||
def __getattr__(self, key):
|
||||
if key not in self.loaded_data:
|
||||
return None
|
||||
return self.script_storage.get(key) or self._load_script(key)
|
||||
|
||||
def _load_data(self):
|
||||
def load_data(self):
|
||||
"""
|
||||
This delayed import avoids trying to load Scripts before they are
|
||||
initialized.
|
||||
|
|
@ -144,7 +141,7 @@ class GlobalScriptContainer(Container):
|
|||
|
||||
def _load_script(self, key):
|
||||
|
||||
self._load_data()
|
||||
self.load_data()
|
||||
|
||||
typeclass = self.typeclass_storage[key]
|
||||
found = typeclass.objects.filter(db_key=key).first()
|
||||
|
|
@ -175,6 +172,23 @@ class GlobalScriptContainer(Container):
|
|||
self.script_storage[key] = found
|
||||
return found
|
||||
|
||||
def get(self, key, default=None):
|
||||
"""
|
||||
Retrive data by key (in case of not knowing it beforehand).
|
||||
|
||||
Args:
|
||||
key (str): The name of the script.
|
||||
default (any, optional): Value to return if key is not found
|
||||
at all on this container (i.e it cannot be loaded at all).
|
||||
|
||||
Returns:
|
||||
any (any): The data loaded on this container.
|
||||
"""
|
||||
|
||||
if key not in self.loaded_data:
|
||||
return default
|
||||
return self.script_storage.get(key) or self._load_script(key)
|
||||
|
||||
def all(self):
|
||||
"""
|
||||
Get all scripts.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from evennia import logger as _log
|
|||
from evennia.utils.ansi import ANSIString as _ANSI
|
||||
from evennia.utils.validatorfuncs import _TZ_DICT
|
||||
from evennia.utils.containers import VALIDATOR_FUNCS
|
||||
from evennia.utils.utils import crop
|
||||
|
||||
|
||||
class BaseOption(object):
|
||||
|
|
@ -22,7 +23,11 @@ class BaseOption(object):
|
|||
validator_key = ''
|
||||
|
||||
def __str__(self):
|
||||
return self.key
|
||||
return "<Option {key}: {value}>".format(
|
||||
key=self.key, value=crop(str(self.value), width=10))
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
def __init__(self, handler, key, description, default, save_data=None):
|
||||
"""
|
||||
|
|
@ -163,6 +168,10 @@ class BaseOption(object):
|
|||
"""
|
||||
Renders the Option's value as something pretty to look at.
|
||||
|
||||
Kwargs:
|
||||
any (any): These are options passed by the caller to potentially
|
||||
customize display dynamically.
|
||||
|
||||
Returns:
|
||||
str: How the stored value should be projected to users (e.g. a raw
|
||||
timedelta is pretty ugly).
|
||||
|
|
@ -171,6 +180,7 @@ class BaseOption(object):
|
|||
return self.value
|
||||
|
||||
|
||||
# Option classes
|
||||
|
||||
|
||||
class Text(BaseOption):
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ from evennia.utils.containers import OPTION_CLASSES
|
|||
|
||||
class OptionHandler(object):
|
||||
"""
|
||||
This is a generic Option handler meant for Typed Objects - anything that implements AttributeHandler.
|
||||
This is a generic Option handler meant for Typed Objects - anything that
|
||||
implements AttributeHandler. Retrieve options eithers as properties on
|
||||
this handler or by using the .get method.
|
||||
|
||||
It uses a dictionary to store-and-cache frequently used settings such as colors for borders or an
|
||||
account's timezone.
|
||||
|
||||
This is used for Account.options but it could be used by Scripts or Objects just as easily. All
|
||||
it needs to be provided is an options_dict.
|
||||
This is used for Account.options but it could be used by Scripts or Objects
|
||||
just as easily. All it needs to be provided is an options_dict.
|
||||
"""
|
||||
|
||||
def __init__(self, obj, options_dict=None, save_category=None):
|
||||
|
|
@ -18,60 +17,70 @@ class OptionHandler(object):
|
|||
Initialize an OptionHandler.
|
||||
|
||||
Args:
|
||||
obj (TypedObject): The Typed Object this sits on. Obj MUST implement the Evennia AttributeHandler
|
||||
or this will barf.
|
||||
options_dict (dict): A dictionary of option keys, where the values are options. The format of those
|
||||
tuples is: ('key', "Description to show", 'option_type', <default value>)
|
||||
save_category (str): The Options data will be stored to this Attribute category on obj.
|
||||
obj (TypedObject): The Typed Object this sits on. Obj MUST
|
||||
implement the Evennia AttributeHandler or this will barf.
|
||||
options_dict (dict): A dictionary of option keys, where the values
|
||||
are options. The format of those tuples is: ('key', "Description to
|
||||
show", 'option_type', <default value>)
|
||||
save_category (str): The Options data will be stored to this
|
||||
Attribute category on obj.
|
||||
|
||||
"""
|
||||
if not options_dict:
|
||||
options_dict = dict()
|
||||
options_dict = {}
|
||||
self.options_dict = options_dict
|
||||
self.save_category = save_category
|
||||
self.obj = obj
|
||||
|
||||
# This dictionary stores the in-memory Options by their key. Values are the Option objects.
|
||||
self.options = dict()
|
||||
self.options = {}
|
||||
|
||||
# We use lazy-loading of each Option when it's called for, but it's good to have the save data
|
||||
# on hand.
|
||||
self.save_data = {s.key: s.value for s in obj.attributes.get(category=save_category,
|
||||
return_list=True, return_obj=True) if s}
|
||||
# We use lazy-loading of each Option when it's called for, but it's
|
||||
# good to have the save data on hand.
|
||||
self.save_data = {s.key: s.value for s in obj.attributes.get(
|
||||
category=save_category, return_list=True, return_obj=True) if s}
|
||||
|
||||
def __getitem__(self, item):
|
||||
"""
|
||||
Shortcut to self.get(item) used as a different syntax. This entire object is
|
||||
essentially a dictionary of option_key -> value.
|
||||
def __getattr__(self, key):
|
||||
return self.get(key).value
|
||||
|
||||
Args:
|
||||
item (str): The Key of the item to get.
|
||||
|
||||
Returns:
|
||||
The Option's value.
|
||||
"""
|
||||
return self.get(item).value
|
||||
|
||||
def get(self, item, return_obj=False):
|
||||
def get(self, key, return_obj=False):
|
||||
"""
|
||||
Retrieves an Option stored in the handler. Will load it if it doesn't exist.
|
||||
|
||||
Args:
|
||||
item (str): The key to retrieve.
|
||||
return_obj (bool): If True, returns the actual option object instead of its value.
|
||||
|
||||
key (str): The option key to retrieve.
|
||||
return_obj (bool, optional): If True, returns the actual option
|
||||
object instead of its value.
|
||||
Returns:
|
||||
An option value (varies) or the Option itself.
|
||||
option_value (any or Option): An option value the Option itself.
|
||||
Raises:
|
||||
KeyError: If option is not defined.
|
||||
|
||||
"""
|
||||
if item not in self.options_dict:
|
||||
if key not in self.options_dict:
|
||||
raise KeyError("Option not found!")
|
||||
if item in self.options:
|
||||
op_found = self.options[item]
|
||||
if key in self.options:
|
||||
op_found = self.options[key]
|
||||
else:
|
||||
op_found = self._load_option(item)
|
||||
op_found = self._load_option(key)
|
||||
if return_obj:
|
||||
return op_found
|
||||
return op_found.value
|
||||
|
||||
def all(self, return_objs=False):
|
||||
"""
|
||||
Get all options defined on this handler.
|
||||
|
||||
Args:
|
||||
return_objs (bool, optional): Return the actual Option objects rather
|
||||
than their values.
|
||||
Returns:
|
||||
all_options (dict): All options on this handler, either `{key: value}`
|
||||
or `{key: <Option>}` if `return_objs` is `True`.
|
||||
|
||||
"""
|
||||
return [self.get(key, return_obj=return_objs) for key in self.options_dict]
|
||||
|
||||
def _load_option(self, key):
|
||||
"""
|
||||
Loads option on-demand if it has not been loaded yet.
|
||||
|
|
@ -82,10 +91,10 @@ class OptionHandler(object):
|
|||
Returns:
|
||||
|
||||
"""
|
||||
option_def = self.options_dict[key]
|
||||
desc, clsname, default_val = self.options_dict[key]
|
||||
save_data = self.save_data.get(key, None)
|
||||
self.obj.msg(save_data)
|
||||
loaded_option = OPTION_CONTAINER[option_def[1]](self, key, option_def[0], option_def[2], save_data)
|
||||
loaded_option = OPTION_CLASSES.get(clsname)(self, key, desc, default_val, save_data)
|
||||
self.options[key] = loaded_option
|
||||
return loaded_option
|
||||
|
||||
|
|
@ -96,6 +105,8 @@ class OptionHandler(object):
|
|||
Args:
|
||||
option (str): The key of an option that can be changed. Allows partial matching.
|
||||
value (str): The value that should be checked, coerced, and stored.
|
||||
kwargs (any, optional): These are passed into the Option's validation function,
|
||||
save function and display function and allows to customize either.
|
||||
|
||||
Returns:
|
||||
New value
|
||||
|
|
@ -110,7 +121,4 @@ class OptionHandler(object):
|
|||
found = found[0]
|
||||
op = self.get(found, return_obj=True)
|
||||
op.set(value, **kwargs)
|
||||
return op.display()
|
||||
|
||||
|
||||
|
||||
return op.display(**kwargs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue