<commit_before>"""Undocumented Module"""

__all__ = ['Messenger']


from PythonUtil import *
from direct.directnotify import DirectNotifyGlobal
from direct.stdpy.threading import Lock
import types

class Messenger:

    notify = DirectNotifyGlobal.directNotify.newCategory("Messenger")

    def __init__(self):
        """
        One is keyed off the event name. It has the following structure:
            {event1: {object1: [method, extraArgs, persistent],
                       object2: [method, extraArgs, persistent]},
             event2: {object1: [method, extraArgs, persistent],
                       object2: [method, extraArgs, persistent]}}

        This dictionary allow for efficient callbacks when the messenger
        hears an event.

        A second dictionary remembers which objects are accepting which
        events. This allows for efficient ignoreAll commands.


        Or, for an example with more real data:
            {'mouseDown': {avatar: [avatar.jump, [2.0], 1]}}
        """
        self.__callbacks = {}
        self.__objectEvents = {}
        self._messengerIdGen = 0
        self._id2object = {}

        # A mapping of taskChain -> eventList, used for sending events
        # across task chains (and therefore across threads).
        self._eventQueuesByTaskChain = {}

        # This protects the data structures within this object from
        # multithreaded access.
        self.lock = Lock()

        if __debug__:
            self.__isWatching=0
            self.__watching={}
        # I'd like this to be in the __debug__, but I fear that someone will
        # want this in a release build.  If you're sure that that will not be
        # then please remove this comment and put the quiet/verbose stuff
        # under __debug__.
        self.quieting={"NewFrame":1,
                       "avatarMoving":1,
                       "event-loop-done":1,
                       } # see def quiet()

    def _getMessengerId(self, object):
        # TODO: allocate this id in DirectObject.__init__ and get derived
        # classes to call down (speed optimization, assuming objects
        # accept/ignore more than once over their lifetime)
        # get unique messenger id for this object
        # assumes lock is held.
        if not hasattr(object, '_messengerId'):
            object._messengerId = (object.__class__.__name__, self._messengerIdGen)
            self._messengerIdGen += 1
        return object._messengerId

    def _storeObject(self, object):
        # store reference-counted reference to object in case we need to
        # retrieve it later.  assumes lock is held.
        id = self._getMessengerId(object)
        if id not in self._id2object:
            self._id2object[id] = [1, object]
        else:
            self._id2object[id][0] += 1

    def _getObject(self, id):
        return self._id2object[id][1]

    def _getObjects(self):
        self.lock.acquire()
        try:
            objs = []
            for refCount, obj in self._id2object.itervalues():
                objs.append(obj)
            return objs
        finally:
            self.lock.release()

    def _getNumListeners(self, event):
        return len(self.__callbacks.get(event, {}))

    def _getEvents(self):
        return self.__callbacks.keys()

    def _releaseObject(self, object):
        # assumes lock is held.
        id = self._getMessengerId(object)
        if id in self._id2object:
            record = self._id2object[id]
            record[0] -= 1
            if record[0] <= 0:
                del self._id2object[id]

    def accept(self, event, object, method, extraArgs=[], persistent=1):
        """ accept(self, string, DirectObject, Function, List, Boolean)

        Make this object accept this event. When the event is
        sent (using Messenger.send or from C++), method will be executed,
        optionally passing in extraArgs.

        If the persistent flag is set, it will continue to respond
        to this event, otherwise it will respond only once.
        """
        notifyDebug = Messenger.notify.getDebug()
        if notifyDebug:
            Messenger.notify.debug(
                "object: %s\n accepting: %s\n method: %s\n extraArgs: %s\n persistent: %s" %
                (object, event, method, extraArgs, persistent))

        # Make the the method is callable
        assert callable(method), (
            "method not callable in accept (ignoring): %s %s"%
            (method, extraArgs))

        self.lock.acquire()
        try:
            acceptorDict = self.__callbacks.setdefault(event, {})

            id = self._getMessengerId(object)<commit_msg>Throw error when extraArgs is not a list<commit_after>"""Undocumented Module"""

__all__ = ['Messenger']


from PythonUtil import *
from direct.directnotify import DirectNotifyGlobal
from direct.stdpy.threading import Lock
import types

class Messenger:

    notify = DirectNotifyGlobal.directNotify.newCategory("Messenger")

    def __init__(self):
        """
        One is keyed off the event name. It has the following structure:
            {event1: {object1: [method, extraArgs, persistent],
                       object2: [method, extraArgs, persistent]},
             event2: {object1: [method, extraArgs, persistent],
                       object2: [method, extraArgs, persistent]}}

        This dictionary allow for efficient callbacks when the messenger
        hears an event.

        A second dictionary remembers which objects are accepting which
        events. This allows for efficient ignoreAll commands.


        Or, for an example with more real data:
            {'mouseDown': {avatar: [avatar.jump, [2.0], 1]}}
        """
        self.__callbacks = {}
        self.__objectEvents = {}
        self._messengerIdGen = 0
        self._id2object = {}

        # A mapping of taskChain -> eventList, used for sending events
        # across task chains (and therefore across threads).
        self._eventQueuesByTaskChain = {}

        # This protects the data structures within this object from
        # multithreaded access.
        self.lock = Lock()

        if __debug__:
            self.__isWatching=0
            self.__watching={}
        # I'd like this to be in the __debug__, but I fear that someone will
        # want this in a release build.  If you're sure that that will not be
        # then please remove this comment and put the quiet/verbose stuff
        # under __debug__.
        self.quieting={"NewFrame":1,
                       "avatarMoving":1,
                       "event-loop-done":1,
                       } # see def quiet()

    def _getMessengerId(self, object):
        # TODO: allocate this id in DirectObject.__init__ and get derived
        # classes to call down (speed optimization, assuming objects
        # accept/ignore more than once over their lifetime)
        # get unique messenger id for this object
        # assumes lock is held.
        if not hasattr(object, '_messengerId'):
            object._messengerId = (object.__class__.__name__, self._messengerIdGen)
            self._messengerIdGen += 1
        return object._messengerId

    def _storeObject(self, object):
        # store reference-counted reference to object in case we need to
        # retrieve it later.  assumes lock is held.
        id = self._getMessengerId(object)
        if id not in self._id2object:
            self._id2object[id] = [1, object]
        else:
            self._id2object[id][0] += 1

    def _getObject(self, id):
        return self._id2object[id][1]

    def _getObjects(self):
        self.lock.acquire()
        try:
            objs = []
            for refCount, obj in self._id2object.itervalues():
                objs.append(obj)
            return objs
        finally:
            self.lock.release()

    def _getNumListeners(self, event):
        return len(self.__callbacks.get(event, {}))

    def _getEvents(self):
        return self.__callbacks.keys()

    def _releaseObject(self, object):
        # assumes lock is held.
        id = self._getMessengerId(object)
        if id in self._id2object:
            record = self._id2object[id]
            record[0] -= 1
            if record[0] <= 0:
                del self._id2object[id]

    def accept(self, event, object, method, extraArgs=[], persistent=1):
        """ accept(self, string, DirectObject, Function, List, Boolean)

        Make this object accept this event. When the event is
        sent (using Messenger.send or from C++), method will be executed,
        optionally passing in extraArgs.

        If the persistent flag is set, it will continue to respond
        to this event, otherwise it will respond only once.
        """
        notifyDebug = Messenger.notify.getDebug()
        if notifyDebug:
            Messenger.notify.debug(
                "object: %s\n accepting: %s\n method: %s\n extraArgs: %s\n persistent: %s" %
                (object, event, method, extraArgs, persistent))

        # Make sure that the method is callable
        assert callable(method), (
            "method not callable in accept (ignoring): %s %s"%
            (method, extraArgs))

        # Make sure extraArgs is a list or tuple
        if not (isinstance(extraArgs, list) or isinstance(extraArgs, tuple) or isinstance(extraArgs, set)):
            raise TypeError, "A list is required as extraArgs argument"

        self.lock.acquire()
        try:
            acceptorDict = self.__callbacks.setdefault(event, {})

            id = self._getMessengerId(object)
{'fraction_non_alphanumeric': 0.08718323078527479, 'fraction_numerical': 0.006882886640942747, 'mean_word_length': 2.1075826312378485, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6623853', 'n_tokens_mistral': 2608, 'n_tokens_neox': 2491, 'n_words': 860}