"""
Observers are objects listening to EventDispatchers.

They are mostly used as bases for UIs in the context of the DC.
"""

#c Copyright 2008-2025, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.

from gavo.utils.dachstypes import Callable
from gavo.base.events import EventDispatcher


def listensTo(*args: str) -> Callable:
	"""a decorator to make a method listen to a set of events.

	It receives one or more event names.
	"""
	def deco(meth: Callable) -> Callable:
		meth.listensTo = args # type: ignore # setting a sentinel
		return meth
	return deco


class ObserverBase:
	"""a base class for observers.

	Observers have methods listening to certain events.  Use the listen
	decorator above to make the connections.  The actual event subscriptions
	are done in the constructor.

	The signature of the listeners always is::
	
	  listener(dispatcher, arg) -> ignored
	
	dispatcher is the EventDispatcher instance propagating the event.  It
	has lots of useful attributes explained in base.event's notifyXXX docstrings.

	You can listen to anything that has a notify method in the EventDispatcher.

	Observers are used in DaCHS for both logging and notification of users.
	Code generally does not use them directly but instead calls
	base.ui.notifyXXX; where you don't have base, try the slower
	utils.misctricks.sendUIEvent.
	"""
	def __init__(self, dispatcher: EventDispatcher) -> None:
		self.dispatcher = dispatcher
		for name in dir(self):
			att = getattr(self, name)
			if hasattr(att, "listensTo"):
				for ev in att.listensTo:
					dispatcher.subscribe(ev, att)
