A set of `Capability`s.
| 50 | |
| 51 | |
| 52 | class Capabilities: |
| 53 | """A set of `Capability`s.""" |
| 54 | |
| 55 | _capabilities: Sequence[Capability] |
| 56 | |
| 57 | def __init__(self) -> None: |
| 58 | self._capabilities = [] |
| 59 | |
| 60 | def _extend(self, capabilities: Sequence[Capability]) -> None: |
| 61 | """Add new capabilities.""" |
| 62 | new_capabilities = list(capabilities) |
| 63 | self._capabilities = list(self._capabilities) + new_capabilities |
| 64 | |
| 65 | def remove_capability_instance(self, capability: Capability) -> None: |
| 66 | """Remove a specific capability.""" |
| 67 | |
| 68 | self._capabilities = [ |
| 69 | cap for cap in self._capabilities if not cap == capability |
| 70 | ] |
| 71 | |
| 72 | def _remove(self, capabilities: set[type[T]]) -> None: |
| 73 | """Remove all existing capabilities of the specified types.""" |
| 74 | |
| 75 | self._capabilities = [ |
| 76 | cap for cap in self._capabilities if type(cap) not in capabilities |
| 77 | ] |
| 78 | |
| 79 | def provides(self, capability: type[T]) -> bool: |
| 80 | """Report whether any capability of the specified type exists.""" |
| 81 | return len(self.get(capability)) > 0 |
| 82 | |
| 83 | def get(self, capability: type[T]) -> list[T]: |
| 84 | """Get all capabilities of the specified type.""" |
| 85 | matches: list[T] = [ |
| 86 | # NOTE: unfortunately pyright can't handle this |
| 87 | cap |
| 88 | for cap in self._capabilities |
| 89 | if type(cap) == capability # type: ignore |
| 90 | ] |
| 91 | return matches |
| 92 | |
| 93 | def get_capability_names(self, capability: type[T]) -> list[str]: |
| 94 | return [t.name for t in self.get(capability)] |
| 95 | |
| 96 | def get_free_capability_name( |
| 97 | self, capability: type[T], max_objects: int |
| 98 | ) -> str | None: |
| 99 | all_object_names = [ |
| 100 | capability.format_str().format(i) for i in range(0, max_objects) |
| 101 | ] |
| 102 | existing_object_names = self.get_capability_names(capability) |
| 103 | remaining_object_names = set(all_object_names) - set(existing_object_names) |
| 104 | return ( |
| 105 | random.choice(list(remaining_object_names)) |
| 106 | if len(remaining_object_names) > 0 |
| 107 | else None |
| 108 | ) |
| 109 |