openlp/openlp/core/common/registry.py

148 lines
5.8 KiB
Python
Raw Normal View History

2013-12-13 18:42:26 +00:00
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2016-12-31 11:05:48 +00:00
# Copyright (c) 2008-2017 OpenLP Developers #
2013-12-13 18:42:26 +00:00
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Provide Registry Services
"""
import logging
import sys
2013-12-15 16:50:09 +00:00
from openlp.core.common import trace_error_handler
2013-12-13 18:42:26 +00:00
log = logging.getLogger(__name__)
class Registry(object):
"""
This is the Component Registry. It is a singleton object and is used to provide a look up service for common
objects.
"""
log.info('Registry loaded')
__instance__ = None
def __new__(cls):
"""
Re-implement the __new__ method to make sure we create a true singleton.
"""
if not cls.__instance__:
cls.__instance__ = object.__new__(cls)
return cls.__instance__
@classmethod
def create(cls):
"""
The constructor for the component registry providing a single registry of objects.
"""
log.info('Registry Initialising')
registry = cls()
registry.service_list = {}
registry.functions_list = {}
# Allow the tests to remove Registry entries but not the live system
2014-03-31 17:32:49 +00:00
registry.running_under_test = 'nose' in sys.argv[0]
registry.initialising = True
2013-12-13 18:42:26 +00:00
return registry
def get(self, key):
"""
Extracts the registry value from the list based on the key passed in
2014-03-17 19:05:55 +00:00
:param key: The service to be retrieved.
2013-12-13 18:42:26 +00:00
"""
if key in self.service_list:
return self.service_list[key]
else:
if not self.initialising:
trace_error_handler(log)
log.error('Service %s not found in list' % key)
raise KeyError('Service %s not found in list' % key)
2013-12-13 18:42:26 +00:00
def register(self, key, reference):
"""
Registers a component against a key.
2014-03-17 19:05:55 +00:00
:param key: The service to be created this is usually a major class like "renderer" or "main_window" .
:param reference: The service address to be saved.
2013-12-13 18:42:26 +00:00
"""
if key in self.service_list:
2013-12-15 16:50:09 +00:00
trace_error_handler(log)
2013-12-13 18:42:26 +00:00
log.error('Duplicate service exception %s' % key)
raise KeyError('Duplicate service exception %s' % key)
else:
self.service_list[key] = reference
def remove(self, key):
"""
Removes the registry value from the list based on the key passed in (Only valid and active for testing
framework).
2014-03-17 19:05:55 +00:00
:param key: The service to be deleted.
2013-12-13 18:42:26 +00:00
"""
if key in self.service_list:
del self.service_list[key]
def register_function(self, event, function):
2013-12-13 18:42:26 +00:00
"""
Register an event and associated function to be called
2014-03-17 19:05:55 +00:00
:param event: The function description like "live_display_hide" where a number of places in the code
2013-12-13 18:42:26 +00:00
will/may need to respond to a single action and the caller does not need to understand or know about the
recipients.
2014-03-17 19:05:55 +00:00
:param function: The function to be called when the event happens.
2013-12-13 18:42:26 +00:00
"""
if event in self.functions_list:
2013-12-13 18:42:26 +00:00
self.functions_list[event].append(function)
else:
self.functions_list[event] = [function]
def remove_function(self, event, function):
"""
Remove an event and associated handler
2014-03-17 19:05:55 +00:00
:param event: The function description..
:param function: The function to be called when the event happens.
2013-12-13 18:42:26 +00:00
"""
if event in self.functions_list:
self.functions_list[event].remove(function)
def execute(self, event, *args, **kwargs):
"""
Execute all the handlers associated with the event and return an array of results.
2014-03-17 19:05:55 +00:00
:param event: The function to be processed
:param args: Parameters to be passed to the function.
:param kwargs: Parameters to be passed to the function.
2013-12-13 18:42:26 +00:00
"""
results = []
if event in self.functions_list:
for function in self.functions_list[event]:
try:
result = function(*args, **kwargs)
if result:
results.append(result)
except TypeError:
# Who has called me can help in debugging
2013-12-15 16:50:09 +00:00
trace_error_handler(log)
2013-12-13 18:42:26 +00:00
log.exception('Exception for function %s', function)
2013-12-15 16:50:09 +00:00
else:
trace_error_handler(log)
2013-12-31 20:29:03 +00:00
log.error("Event %s called but not registered" % event)
2013-12-13 18:42:26 +00:00
return results