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
|
self.loaded_data = None
|
||||||
|
|
||||||
def _load_data(self):
|
def load_data(self):
|
||||||
"""
|
"""
|
||||||
Delayed import to avoid eventual circular imports from inside
|
Delayed import to avoid eventual circular imports from inside
|
||||||
the storage modules.
|
the storage modules.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.loaded_data is None:
|
if self.loaded_data is None:
|
||||||
|
self.loaded_data = {}
|
||||||
for module in self.storage_modules:
|
for module in self.storage_modules:
|
||||||
self.loaded_data.update(callables_from_module(module))
|
self.loaded_data.update(callables_from_module(module))
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
self._load_data()
|
return self.get(key)
|
||||||
return self.loaded_data.get(key)
|
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key, default=None):
|
||||||
"""
|
"""
|
||||||
Retrive data by key (in case of not knowing it beforehand).
|
Retrive data by key (in case of not knowing it beforehand).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
key (str): The name of the script.
|
key (str): The name of the script.
|
||||||
|
default (any, optional): Value to return if key is not found.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
any (any): The data loaded on this container.
|
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):
|
def all(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -70,7 +72,7 @@ class Container(object):
|
||||||
scripts (list): All global script objects stored on the container.
|
scripts (list): All global script objects stored on the container.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._load_data()
|
self.load_data()
|
||||||
return list(self.loaded_data.values())
|
return list(self.loaded_data.values())
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -121,12 +123,7 @@ class GlobalScriptContainer(Container):
|
||||||
self.script_storage = {}
|
self.script_storage = {}
|
||||||
self.typeclass_storage = None
|
self.typeclass_storage = None
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def load_data(self):
|
||||||
if key not in self.loaded_data:
|
|
||||||
return None
|
|
||||||
return self.script_storage.get(key) or self._load_script(key)
|
|
||||||
|
|
||||||
def _load_data(self):
|
|
||||||
"""
|
"""
|
||||||
This delayed import avoids trying to load Scripts before they are
|
This delayed import avoids trying to load Scripts before they are
|
||||||
initialized.
|
initialized.
|
||||||
|
|
@ -144,7 +141,7 @@ class GlobalScriptContainer(Container):
|
||||||
|
|
||||||
def _load_script(self, key):
|
def _load_script(self, key):
|
||||||
|
|
||||||
self._load_data()
|
self.load_data()
|
||||||
|
|
||||||
typeclass = self.typeclass_storage[key]
|
typeclass = self.typeclass_storage[key]
|
||||||
found = typeclass.objects.filter(db_key=key).first()
|
found = typeclass.objects.filter(db_key=key).first()
|
||||||
|
|
@ -175,6 +172,23 @@ class GlobalScriptContainer(Container):
|
||||||
self.script_storage[key] = found
|
self.script_storage[key] = found
|
||||||
return 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):
|
def all(self):
|
||||||
"""
|
"""
|
||||||
Get all scripts.
|
Get all scripts.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from evennia import logger as _log
|
||||||
from evennia.utils.ansi import ANSIString as _ANSI
|
from evennia.utils.ansi import ANSIString as _ANSI
|
||||||
from evennia.utils.validatorfuncs import _TZ_DICT
|
from evennia.utils.validatorfuncs import _TZ_DICT
|
||||||
from evennia.utils.containers import VALIDATOR_FUNCS
|
from evennia.utils.containers import VALIDATOR_FUNCS
|
||||||
|
from evennia.utils.utils import crop
|
||||||
|
|
||||||
|
|
||||||
class BaseOption(object):
|
class BaseOption(object):
|
||||||
|
|
@ -22,7 +23,11 @@ class BaseOption(object):
|
||||||
validator_key = ''
|
validator_key = ''
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
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.
|
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:
|
Returns:
|
||||||
str: How the stored value should be projected to users (e.g. a raw
|
str: How the stored value should be projected to users (e.g. a raw
|
||||||
timedelta is pretty ugly).
|
timedelta is pretty ugly).
|
||||||
|
|
@ -171,6 +180,7 @@ class BaseOption(object):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
|
|
||||||
|
# Option classes
|
||||||
|
|
||||||
|
|
||||||
class Text(BaseOption):
|
class Text(BaseOption):
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,12 @@ from evennia.utils.containers import OPTION_CLASSES
|
||||||
|
|
||||||
class OptionHandler(object):
|
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
|
This is used for Account.options but it could be used by Scripts or Objects
|
||||||
account's timezone.
|
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):
|
def __init__(self, obj, options_dict=None, save_category=None):
|
||||||
|
|
@ -18,60 +17,70 @@ class OptionHandler(object):
|
||||||
Initialize an OptionHandler.
|
Initialize an OptionHandler.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
obj (TypedObject): The Typed Object this sits on. Obj MUST implement the Evennia AttributeHandler
|
obj (TypedObject): The Typed Object this sits on. Obj MUST
|
||||||
or this will barf.
|
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
|
options_dict (dict): A dictionary of option keys, where the values
|
||||||
tuples is: ('key', "Description to show", 'option_type', <default value>)
|
are options. The format of those tuples is: ('key', "Description to
|
||||||
save_category (str): The Options data will be stored to this Attribute category on obj.
|
show", 'option_type', <default value>)
|
||||||
|
save_category (str): The Options data will be stored to this
|
||||||
|
Attribute category on obj.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not options_dict:
|
if not options_dict:
|
||||||
options_dict = dict()
|
options_dict = {}
|
||||||
self.options_dict = options_dict
|
self.options_dict = options_dict
|
||||||
self.save_category = save_category
|
self.save_category = save_category
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|
||||||
# This dictionary stores the in-memory Options by their key. Values are the Option objects.
|
# 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
|
# We use lazy-loading of each Option when it's called for, but it's
|
||||||
# on hand.
|
# good to have the save data on hand.
|
||||||
self.save_data = {s.key: s.value for s in obj.attributes.get(category=save_category,
|
self.save_data = {s.key: s.value for s in obj.attributes.get(
|
||||||
return_list=True, return_obj=True) if s}
|
category=save_category, return_list=True, return_obj=True) if s}
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getattr__(self, key):
|
||||||
"""
|
return self.get(key).value
|
||||||
Shortcut to self.get(item) used as a different syntax. This entire object is
|
|
||||||
essentially a dictionary of option_key -> value.
|
|
||||||
|
|
||||||
Args:
|
def get(self, key, return_obj=False):
|
||||||
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):
|
|
||||||
"""
|
"""
|
||||||
Retrieves an Option stored in the handler. Will load it if it doesn't exist.
|
Retrieves an Option stored in the handler. Will load it if it doesn't exist.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
item (str): The key to retrieve.
|
key (str): The option key to retrieve.
|
||||||
return_obj (bool): If True, returns the actual option object instead of its value.
|
return_obj (bool, optional): If True, returns the actual option
|
||||||
|
object instead of its value.
|
||||||
Returns:
|
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!")
|
raise KeyError("Option not found!")
|
||||||
if item in self.options:
|
if key in self.options:
|
||||||
op_found = self.options[item]
|
op_found = self.options[key]
|
||||||
else:
|
else:
|
||||||
op_found = self._load_option(item)
|
op_found = self._load_option(key)
|
||||||
if return_obj:
|
if return_obj:
|
||||||
return op_found
|
return op_found
|
||||||
return op_found.value
|
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):
|
def _load_option(self, key):
|
||||||
"""
|
"""
|
||||||
Loads option on-demand if it has not been loaded yet.
|
Loads option on-demand if it has not been loaded yet.
|
||||||
|
|
@ -82,10 +91,10 @@ class OptionHandler(object):
|
||||||
Returns:
|
Returns:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
option_def = self.options_dict[key]
|
desc, clsname, default_val = self.options_dict[key]
|
||||||
save_data = self.save_data.get(key, None)
|
save_data = self.save_data.get(key, None)
|
||||||
self.obj.msg(save_data)
|
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
|
self.options[key] = loaded_option
|
||||||
return loaded_option
|
return loaded_option
|
||||||
|
|
||||||
|
|
@ -96,6 +105,8 @@ class OptionHandler(object):
|
||||||
Args:
|
Args:
|
||||||
option (str): The key of an option that can be changed. Allows partial matching.
|
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.
|
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:
|
Returns:
|
||||||
New value
|
New value
|
||||||
|
|
@ -110,7 +121,4 @@ class OptionHandler(object):
|
||||||
found = found[0]
|
found = found[0]
|
||||||
op = self.get(found, return_obj=True)
|
op = self.get(found, return_obj=True)
|
||||||
op.set(value, **kwargs)
|
op.set(value, **kwargs)
|
||||||
return op.display()
|
return op.display(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue