<commit_before># This file is part of LiSE, a framework for life simulation games.
# Copyright (c) <NAME>,  <EMAIL>
"""The sort of node that is ultimately located in a Place.

Things may be located in other Things as well, but eventually must be
recursively located in a Place.

There's a subtle distinction between "location" and "containment": a
Thing may be contained by a Portal, but cannot be located there --
only in one of the Portal's endpoints. Things are both located in and
contained by Places, or possibly other Things.

"""
import networkx as nx
from .node import Node
from .util import path_len
from .exc import TravelException


def roerror(*args, **kwargs):
    raise ValueError("Read-only")


class Thing(Node):

    """The sort of item that has a particular location at any given time.

    If a Thing is in a Place, it is standing still. If it is in a
    Portal, it is moving through that Portal however fast it must in
    order to arrive at the other end when it is scheduled to. If it is
    in another Thing, then it is wherever that is, and moving the
    same.

    """

    extrakeys = {
        'name',
        'character',
        'location',
        'next_location',
        'arrival_time',
        'next_arrival_time'
    }

    def _getname(self):
        return self.name

    def _getcharname(self):
        return self.character.name

    def _getloc(self):
        return self._get_locations()[0]

    def _setloc(self, v):
        self._set_loc_and_next(v, None)

    def _getnxtloc(self):
        return self._get_locations()[1]

    def _setnxtloc(self, v):
        self._set_loc_and_next(self['location'], v)

    def _setlocs(self, v):
        self._set_loc_and_next(*v)

    def _get_arrival_time(self):
        return self.engine._things_cache.tick_before(self.character.name, self.name, *self.engine.time)

    def _get_next_arrival_time(self):
        try:
            return self.engine._things_cache.tick_after(self.character.name, self.name, *self.engine.time)
        except KeyError:
            return None

    def _get_locations(self):
        return self.engine._things_cache.retrieve(self.character.name, self.name, *self.engine.time)

    _getitem_dispatch = {
        'name': _getname,
        'character': _getcharname,
        'location': _getloc,
        'next_location': _getnxtloc,
        'locations': _get_locations,
        'arrival_time': _get_arrival_time,
        'next_arrival_time': _get_next_arrival_time
    }

    _setitem_dispatch = {
        'name': roerror,
        'character': roerror,
        'arrival_time': roerror,
        'next_arrival_time': roerror,
        'location': _setloc,
        'next_location': _setnxtloc,
        'locations': _setlocs
    }

    def __contains__(self, key):
        if key in self.extrakeys:
            return True
        return super().__contains__(key)

    def __getitem__(self, key):
        """Return one of my stats stored in the database, or a few
        special cases:

        ``name``: return the name that uniquely identifies me within
        my Character

        ``character``: return the name of my character

        ``location``: return the name of my location

        ``arrival_time``: return the tick when I arrived in the
        present location

        ``next_location``: if I'm in transit, return where to, else return None

        ``next_arrival_time``: return the tick when I'm going to
        arrive at ``next_location``

        ``locations``: return a pair of ``(location, next_location)``

        """
        try:
            return self._getitem_dispatch[key](self)
        except KeyError:
            return super().__getitem__(key)

    def __setitem__(self, key, value):
        """Set ``key``=``value`` for the present game-time."""
        try:
            self._setitem_dispatch[key](value)
        except KeyError:
            super().__setitem__(key, value)

    def __delitem__(self, key):
        """As of now, this key isn't mine."""
        if key in self.extrakeys:
            raise ValueError("Can't delete {}".format(key))
        super().__delitem__(key)

    def __repr__(self):
        """Return my character, name, and location."""
        if self['next_location'] is not None:
            return "{}.thing[{}]@{}->{}".format(
                self['character'],
                self['name'],
                self['location'],
                self['next_location']
            )
        return "{}.thing[{}]@{}".format(
            self['character'],
            self['name'],
            self['location']
        )<commit_msg>Make Thing.__setitem__ pass self into _setloc correctly<commit_after># This file is part of LiSE, a framework for life simulation games.
# Copyright (c) <NAME>,  <EMAIL>
"""The sort of node that is ultimately located in a Place.

Things may be located in other Things as well, but eventually must be
recursively located in a Place.

There's a subtle distinction between "location" and "containment": a
Thing may be contained by a Portal, but cannot be located there --
only in one of the Portal's endpoints. Things are both located in and
contained by Places, or possibly other Things.

"""
import networkx as nx
from .node import Node
from .util import path_len
from .exc import TravelException


def roerror(*args, **kwargs):
    raise ValueError("Read-only")


class Thing(Node):

    """The sort of item that has a particular location at any given time.

    If a Thing is in a Place, it is standing still. If it is in a
    Portal, it is moving through that Portal however fast it must in
    order to arrive at the other end when it is scheduled to. If it is
    in another Thing, then it is wherever that is, and moving the
    same.

    """

    extrakeys = {
        'name',
        'character',
        'location',
        'next_location',
        'arrival_time',
        'next_arrival_time'
    }

    def _getname(self):
        return self.name

    def _getcharname(self):
        return self.character.name

    def _getloc(self):
        return self._get_locations()[0]

    def _setloc(self, v):
        self._set_loc_and_next(v, None)

    def _getnxtloc(self):
        return self._get_locations()[1]

    def _setnxtloc(self, v):
        self._set_loc_and_next(self['location'], v)

    def _setlocs(self, v):
        self._set_loc_and_next(*v)

    def _get_arrival_time(self):
        return self.engine._things_cache.tick_before(self.character.name, self.name, *self.engine.time)

    def _get_next_arrival_time(self):
        try:
            return self.engine._things_cache.tick_after(self.character.name, self.name, *self.engine.time)
        except KeyError:
            return None

    def _get_locations(self):
        return self.engine._things_cache.retrieve(self.character.name, self.name, *self.engine.time)

    _getitem_dispatch = {
        'name': _getname,
        'character': _getcharname,
        'location': _getloc,
        'next_location': _getnxtloc,
        'locations': _get_locations,
        'arrival_time': _get_arrival_time,
        'next_arrival_time': _get_next_arrival_time
    }

    _setitem_dispatch = {
        'name': roerror,
        'character': roerror,
        'arrival_time': roerror,
        'next_arrival_time': roerror,
        'location': _setloc,
        'next_location': _setnxtloc,
        'locations': _setlocs
    }

    def __contains__(self, key):
        if key in self.extrakeys:
            return True
        return super().__contains__(key)

    def __getitem__(self, key):
        """Return one of my stats stored in the database, or a few
        special cases:

        ``name``: return the name that uniquely identifies me within
        my Character

        ``character``: return the name of my character

        ``location``: return the name of my location

        ``arrival_time``: return the tick when I arrived in the
        present location

        ``next_location``: if I'm in transit, return where to, else return None

        ``next_arrival_time``: return the tick when I'm going to
        arrive at ``next_location``

        ``locations``: return a pair of ``(location, next_location)``

        """
        try:
            return self._getitem_dispatch[key](self)
        except KeyError:
            return super().__getitem__(key)

    def __setitem__(self, key, value):
        """Set ``key``=``value`` for the present game-time."""
        try:
            self._setitem_dispatch[key](self, value)
        except KeyError:
            super().__setitem__(key, value)

    def __delitem__(self, key):
        """As of now, this key isn't mine."""
        if key in self.extrakeys:
            raise ValueError("Can't delete {}".format(key))
        super().__delitem__(key)

    def __repr__(self):
        """Return my character, name, and location."""
        if self['next_location'] is not None:
            return "{}.thing[{}]@{}->{}".format(
                self['character'],
                self['name'],
                self['location'],
                self['next_location']
            )
        return "{}.thing[{}]@{}".format(
            self['character'],
            self['name'],
            self['location']
        )
{'fraction_non_alphanumeric': 0.10514928602336651, 'fraction_numerical': 0.00043271311120726956, 'mean_word_length': 2.42534271952575, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2835443', 'n_tokens_mistral': 2760, 'n_tokens_neox': 2609, 'n_words': 865}