diff --git a/evennia/__init__.py b/evennia/__init__.py index 080114f7a0..47a6273239 100644 --- a/evennia/__init__.py +++ b/evennia/__init__.py @@ -109,6 +109,7 @@ TASK_HANDLER = None TICKER_HANDLER = None MONITOR_HANDLER = None CHANNEL_HANDLER = None +GLOBAL_HANDLER = None def _create_version(): @@ -152,7 +153,7 @@ def _init(): global search_object, search_script, search_account, search_channel, search_help, search_tag, search_message global create_object, create_script, create_account, create_channel, create_message, create_help_entry global settings, lockfuncs, logger, utils, gametime, ansi, spawn, managers - global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER + global contrib, TICKER_HANDLER, MONITOR_HANDLER, SESSION_HANDLER, CHANNEL_HANDLER, TASK_HANDLER, GLOBAL_HANDLER global EvMenu, EvTable, EvForm, EvMore, EvEditor global ANSIString @@ -213,6 +214,7 @@ def _init(): from .server.sessionhandler import SESSION_HANDLER from .comms.channelhandler import CHANNEL_HANDLER from .scripts.monitorhandler import MONITOR_HANDLER + from .scripts.globalhandler import GLOBAL_HANDLER # initialize the doc string global __doc__ diff --git a/evennia/scripts/globalhandler.py b/evennia/scripts/globalhandler.py new file mode 100644 index 0000000000..3ac7e38d40 --- /dev/null +++ b/evennia/scripts/globalhandler.py @@ -0,0 +1,45 @@ +from django.conf import settings +from evennia.utils.utils import class_from_module + + +class GlobalHandler(object): + """ + Simple Handler object loaded by the Evennia API to contain and manage a game's Global Scripts. + + This is accessed like a dictionary. + + Example: + import evennia + evennia.GLOBAL_HANDLER['key'] + """ + + def __init__(self): + self.typeclass_storage = dict() + self.script_storage = dict() + for k, v in settings.GLOBAL_SCRIPTS.items(): + self.typeclass_storage[k] = class_from_module(v) + for k, v in self.typeclass_storage.items(): + found = v.objects.filter_family(db_key=k).first() + if not found: + found = v.create(key=k, typeclass=v, persistent=True) + self.script_storage[k] = found + + def __getitem__(self, item): + + # Likely to only reach this if someone called the API wrong. + if item not in self.typeclass_storage: + return None + + # The most common outcome next! + if self.script_storage[item]: + return self.script_storage[item] + else: + # Oops, something happened to our Global Script. Let's re-create it. + reloaded = self.typeclass_storage[item].create(key=item, typeclass=self.typeclass_storage[item], + persistent=True) + self.script_storage[item] = reloaded + return reloaded + + +# Create singleton of the GlobalHandler for the API. +GLOBAL_HANDLER = GlobalHandler() diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 4e582b11e3..70ad3e8ba6 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -538,6 +538,25 @@ INLINEFUNC_MODULES = ["evennia.utils.inlinefuncs", PROTOTYPEFUNC_MODULES = ["evennia.utils.prototypefuncs", "server.conf.prototypefuncs"] +###################################################################### +# Global Scripts +###################################################################### + +# While any script that is not attached to any object is considered +# Global, any listed here will be started by Evennia during boot +# and attached to its API for an easy-lookup. This ensures the Script +# is always accessible, and re-created if it is somehow deleted. Use +# this for Scripts that absolutely MUST be running for your game as a +# simple way to get them launched. + +# One limitation with this system is that each Script must be have a +# unique Typeclass. The 'key' is a way to quickly index them but is +# not necessarily the Script Typeclasss's key. + +GLOBAL_SCRIPTS = { + # 'key': 'typeclass.path.here', +} + ###################################################################### # Default Account setup and access ######################################################################