Lines
100.00%
37 / 37
Methods
100.00%
10 / 10
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| socketId | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| player | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| location | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| state | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| away | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| hear | 100.00% | 22 / 22 | 100.00% | 1 / 1 | 8 | ||
| [Lorekeeper\Client\Observable] subscribe | 100.00% | 3 / 3 | 100.00% | 1 / 1 | 2 | ||
| [Lorekeeper\Client\Observable] unsubscribe | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 1 | ||
| [Lorekeeper\Client\Observable] notify | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 2 | ||
| 21 | final class Character implements SubjectInterface | |
| 22 | { | |
| 23 | use Observable; | |
| 24 | ||
| 25 | public function __construct( | |
| 26 | private readonly SocketId $socketId, | |
| 27 | private Player $player, | |
| 28 | private Location $location, | |
| 29 | private CombatState $state, | |
| 30 | private bool $away, | |
| 31 | ) {} | |
| 32 | ||
| 33 | public function socketId(): SocketId | |
| 34 | { | |
| 35 | return $this->socketId; | |
| 36 | } | |
| 37 | ||
| 38 | public function player(): Player | |
| 39 | { | |
| 40 | return $this->player; | |
| 41 | } | |
| 42 | ||
| 43 | public function location(): Location | |
| 44 | { | |
| 45 | return $this->location; | |
| 46 | } | |
| 47 | ||
| 48 | public function state(): CombatState | |
| 49 | { | |
| 50 | return $this->state; | |
| 51 | } | |
| 52 | ||
| 53 | public function away(): bool | |
| 54 | { | |
| 55 | return $this->away; | |
| 56 | } | |
| 57 | ||
| 58 | public function hear(Event $event): void | |
| 59 | { | |
| 60 | $me = new Identity($this->socketId, $this->player->name); | |
| 61 | $was = $this->player; | |
| 62 | ||
| 63 | $level = LevelTracking::follow($was->level, $event); | |
| 64 | $vitals = VitalsTracking::follow($was->vitals, $event, $me); | |
| 65 | $class = ClassTracking::follow($was->class, $event, $me); | |
| 66 | $inventory = InventoryTracking::follow($was->inventory, $event); | |
| 67 | $location = LocationTracking::follow($this->location, $event, $me); | |
| 68 | $state = StateTracking::follow($this->state, $event, $me); | |
| 69 | $away = AwayTracking::follow($this->away, $event, $me); | |
| 70 | ||
| 71 | if ( | |
| 72 | $level === $was->level | |
| 73 | && $vitals === $was->vitals | |
| 74 | && $class === $was->class | |
| 75 | && $inventory === $was->inventory | |
| 76 | && $location === $this->location | |
| 77 | && $state === $this->state | |
| 78 | && $away === $this->away | |
| 79 | ) { | |
| 80 | return; | |
| 81 | } | |
| 82 | ||
| 83 | $this->player = new Player($was->name, $level, $vitals, $class, $inventory); | |
| 84 | $this->location = $location; | |
| 85 | $this->state = $state; | |
| 86 | $this->away = $away; | |
| 87 | $this->notify(); | |
| 88 | } | |
| 89 | } |
From Lorekeeper\Client\Observable
| 11 | trait Observable | |
| 12 | { | |
| 13 | /** @var list<ObserverInterface<SubjectInterface>> */ | |
| 14 | private array $observers = []; | |
| 15 | ||
| 16 | /** @param ObserverInterface<SubjectInterface> $observer */ | |
| 17 | public function subscribe(ObserverInterface $observer): void | |
| 18 | { | |
| 19 | if (in_array($observer, $this->observers, strict: true)) { | |
| 20 | return; | |
| 21 | } | |
| 22 | ||
| 23 | $this->observers[] = $observer; | |
| 24 | } | |
| 25 | ||
| 26 | /** @param ObserverInterface<SubjectInterface> $observer */ | |
| 27 | public function unsubscribe(ObserverInterface $observer): void | |
| 28 | { | |
| 29 | $this->observers = array_values(array_filter( | |
| 30 | $this->observers, | |
| 31 | static fn(ObserverInterface $subscribed): bool => $subscribed !== $observer, | |
| 32 | )); | |
| 33 | } | |
| 34 | ||
| 35 | public function notify(): void | |
| 36 | { | |
| 37 | foreach ($this->observers as $observer) { | |
| 38 | $observer->update($this); | |
| 39 | } | |
| 40 | } | |
| 41 | } |