Exemple #1
0
class SlotIndexRegister(RestrictionRegister):
    """
    Class which implements common functionality for all
    registers, which track indices of occupied slots and
    disallow multiple holders reside within slot with the
    same index.
    """

    def __init__(self, slot_index_attr, restriction_type):
        # This attribute's value on holder
        # represents their index of slot
        self.__slot_index_attr = slot_index_attr
        self.__restriction_type = restriction_type
        # All holders which possess index of slot
        # are stored in this container
        # Format: {slot index: {holders}}
        self.__slotted_holders = KeyedSet()

    def register_holder(self, holder):
        # Skip items which don't have index specifier
        slot_index = holder.item.attributes.get(self.__slot_index_attr)
        if slot_index is None:
            return
        self.__slotted_holders.add_data(slot_index, holder)

    def unregister_holder(self, holder):
        slot_index = holder.item.attributes.get(self.__slot_index_attr)
        if slot_index is None:
            return
        self.__slotted_holders.rm_data(slot_index, holder)

    def validate(self):
        tainted_holders = {}
        for slot_index in self.__slotted_holders:
            slot_index_holders = self.__slotted_holders[slot_index]
            # If more than one item occupies the same slot, all
            # holders in this slot are tainted
            if len(slot_index_holders) > 1:
                for holder in slot_index_holders:
                    tainted_holders[holder] = SlotIndexErrorData(holder_slot_index=slot_index)
        if tainted_holders:
            raise RegisterValidationError(tainted_holders)

    @property
    def restriction_type(self):
        return self.__restriction_type
Exemple #2
0
class MaxGroupRegister(RestrictionRegister):
    """
    Class which implements common functionality for all
    registers, which track maximum number of belonging to
    ship holders in certain state on per-group basis.
    """

    def __init__(self, max_group_attr, restriction_type):
        # Attribute ID whose value contains group restriction
        # of holder
        self.__max_group_attr = max_group_attr
        self.__restriction_type = restriction_type
        # Container for all tracked holders, keyed
        # by their group ID
        # Format: {group ID: {holders}}
        self.__group_all = KeyedSet()
        # Container for holders, which have max group
        # restriction to become operational
        # Format: {holders}
        self.__group_restricted = set()

    def register_holder(self, holder):
        # Ignore holders which do not belong to ship
        if holder._domain != Domain.ship:
            return
        group = holder.item.group
        # Ignore holders, whose item isn't assigned
        # to any group
        if group is None:
            return
        # Having group ID is sufficient condition
        # to enter container of all fitted holders
        self.__group_all.add_data(group, holder)
        # To enter restriction container, original
        # item must have restriction attribute
        if self.__max_group_attr not in holder.item.attributes:
            return
        self.__group_restricted.add(holder)

    def unregister_holder(self, holder):
        # Just clear data containers
        group = holder.item.group
        self.__group_all.rm_data(group, holder)
        self.__group_restricted.discard(holder)

    def validate(self):
        # Container for tainted holders
        tainted_holders = {}
        # Go through all restricted holders
        for holder in self.__group_restricted:
            # Get number of registered holders, assigned to group of current
            # restricted holder, and holder's restriction value
            group = holder.item.group
            group_holders = len(self.__group_all.get(group) or ())
            max_group_restriction = holder.item.attributes[self.__max_group_attr]
            # If number of registered holders from this group is bigger,
            # then current holder is tainted
            if group_holders > max_group_restriction:
                tainted_holders[holder] = MaxGroupErrorData(
                    holder_group=group,
                    max_group=max_group_restriction,
                    group_holders=group_holders
                )
        # Raise error if we detected any tainted holders
        if tainted_holders:
            raise RegisterValidationError(tainted_holders)

    @property
    def restriction_type(self):
        return self.__restriction_type
Exemple #3
0
class MaxGroupRegister(RestrictionRegister):
    """
    Class which implements common functionality for all
    registers, which track maximum number of belonging to
    ship holders in certain state on per-group basis.
    """
    def __init__(self, max_group_attr, restriction_type):
        # Attribute ID whose value contains group restriction
        # of holder
        self.__max_group_attr = max_group_attr
        self.__restriction_type = restriction_type
        # Container for all tracked holders, keyed
        # by their group ID
        # Format: {group ID: {holders}}
        self.__group_all = KeyedSet()
        # Container for holders, which have max group
        # restriction to become operational
        # Format: {holders}
        self.__group_restricted = set()

    def register_holder(self, holder):
        # Ignore holders which do not belong to ship
        if holder._domain != Domain.ship:
            return
        group = holder.item.group
        # Ignore holders, whose item isn't assigned
        # to any group
        if group is None:
            return
        # Having group ID is sufficient condition
        # to enter container of all fitted holders
        self.__group_all.add_data(group, holder)
        # To enter restriction container, original
        # item must have restriction attribute
        if self.__max_group_attr not in holder.item.attributes:
            return
        self.__group_restricted.add(holder)

    def unregister_holder(self, holder):
        # Just clear data containers
        group = holder.item.group
        self.__group_all.rm_data(group, holder)
        self.__group_restricted.discard(holder)

    def validate(self):
        # Container for tainted holders
        tainted_holders = {}
        # Go through all restricted holders
        for holder in self.__group_restricted:
            # Get number of registered holders, assigned to group of current
            # restricted holder, and holder's restriction value
            group = holder.item.group
            group_holders = len(self.__group_all.get(group) or ())
            max_group_restriction = holder.item.attributes[
                self.__max_group_attr]
            # If number of registered holders from this group is bigger,
            # then current holder is tainted
            if group_holders > max_group_restriction:
                tainted_holders[holder] = MaxGroupErrorData(
                    holder_group=group,
                    max_group=max_group_restriction,
                    group_holders=group_holders)
        # Raise error if we detected any tainted holders
        if tainted_holders:
            raise RegisterValidationError(tainted_holders)

    @property
    def restriction_type(self):
        return self.__restriction_type