Skip to content

Commit 6b14e5f

Browse files
committed
Use an interface for Message
Signed-off-by: thgs <theogpl57@gmail.com>
1 parent 34db98a commit 6b14e5f

File tree

17 files changed

+234
-153
lines changed

17 files changed

+234
-153
lines changed

examples/components/default-main-component.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ public function update(?Message $message): ?Message
2929
// we leave to the predefined (INIT/TERMINATE)
3030
// which we will override in this example just to show
3131
// how that would work (it is optional to override init/terminate).
32+
if ($message === null) {
33+
return parent::update($message);
34+
}
3235

33-
return match($message->type) {
34-
Message::KEY_PRESS => Message::quit(),
36+
return match(get_class($message)) {
37+
Message\KeyPress::class => new Message\Quit(),
3538
default => parent::update($message)
3639
};
3740
}

examples/hex-editor-with-progress-bar/hex-editor-with-progressbar.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ public function __construct(
7272
*/
7373
public function update(?Message $message): ?Message
7474
{
75-
return match ($message?->type) {
76-
Message::KEY_PRESS => $this->handleKeyPress($message['key']),
75+
if ($message === null) {
76+
return parent::update($message);
77+
}
78+
79+
return match (get_class($message)) {
80+
Message\KeyPress::class => $this->handleKeyPress($message->key),
7781
default => parent::update($message),
7882
};
7983
}
@@ -92,7 +96,7 @@ private function handleKeyPress(string $key): ?Message
9296
$a = 1;
9397
return !$this->insertMode
9498
? match (strtolower($key)) {
95-
'q', '<esc>' => Message::quit(),
99+
'q', '<esc>' => new Message\Quit(),
96100
'h', 'j', "\x0a", 'k', 'l' => $this->handleUserMoved($this->mapDirection($key)),
97101
'i' => $this->handleInsertModeEnabled(),
98102
default => null

examples/input-demo/Component/Menu.php

Lines changed: 0 additions & 26 deletions
This file was deleted.

examples/input-demo/input-demo.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,23 +137,26 @@ public function view(): string
137137

138138
public function update(?Message $message): ?Message
139139
{
140+
if ($message === null) {
141+
return parent::update($message);
142+
}
143+
140144
// reset some of the state
141145
$this->mouseEvent = null;
142146
$this->received = '';
143147

144-
return match ($message?->type) {
145-
Message::KEY_PRESS => $this->handleKeyPress($message['key'], $message['original']),
146-
Message::MOUSE_INPUT => $this->handleMouseInput($message['event']),
147-
Message::MOUSE_FOCUS_IN => $this->handleFocus(true),
148-
Message::MOUSE_FOCUS_OUT => $this->handleFocus(false),
148+
return match (get_class($message)) {
149+
Message\KeyPress::class => $this->handleKeyPress($message->key, $message->original),
150+
Message\MouseInput::class => $this->handleMouseInput($message->event),
151+
Message\MouseFocus::class => $this->handleFocus($message->focusIn),
149152
default => parent::update($message),
150153
};
151154
}
152155

153156
private function handleKeyPress(string $key, ?string $original = null): ?Message
154157
{
155158
return match (strtolower($key)) {
156-
'q' => Message::quit(),
159+
'q' => new Message\Quit(),
157160
'k' => $this->changeMode('keyboard'),
158161
'1' => $this->changeMode('normal'),
159162
'2' => $this->changeMode('anyButton'),

examples/timer/timer-alt-screen-buffer.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,23 @@ public function view(): string
6464

6565
public function update(?Message $message): ?Message
6666
{
67-
return match ($message->type) {
68-
Message::INIT => $this->init($message['reference']),
69-
Message::KEY_PRESS => Message::quit(),
70-
Message::TICK => $this->tick(),
71-
Message::TERMINATE => $this->terminate($message['reference']),
67+
if ($message === null) {
68+
return null;
69+
}
70+
71+
return match (get_class($message)) {
72+
Message\Init::class => $this->init($message->aspectus),
73+
Message\KeyPress::class => new Message\Quit(),
74+
Message\Tick::class => $this->tick(),
75+
Message\Terminate::class => $this->terminate($message->aspectus),
7276
default => null,
7377
};
7478
}
7579

7680
public function tick(): ?Message
7781
{
7882
$this->ticksLeft -= 1;
79-
return $this->ticksLeft <= 0 ? Message::quit() : null;
83+
return $this->ticksLeft <= 0 ? new Message\Quit() : null;
8084
}
8185

8286
public function init(Aspectus $aspectus): ?Message

psalm.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
>
1010
<projectFiles>
1111
<directory name="src" />
12+
<directory name="examples" />
1213
<ignoreFiles>
1314
<directory name="vendor" />
1415
<directory name="packages" />

src/Aspectus.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Aspectus;
44

55
use Aspectus\Internal\Runtime;
6+
use Aspectus\Message;
67
use Aspectus\Render\StandardRenderer;
78
use Aspectus\Terminal\Event\InputEvent;
89
use Aspectus\Terminal\Xterm;
@@ -67,7 +68,7 @@ private function installSignalHandlers(): void
6768
$this->callbackIds[] = EventLoop::onSignal(
6869
\SIGINT,
6970
function () {
70-
$this->handleAspectusMessages(Message::quit());
71+
$this->handleAspectusMessages(new Message\Quit('SIGINT received'));
7172
}
7273
);
7374
}
@@ -76,7 +77,8 @@ function () {
7677
$this->callbackIds[] = EventLoop::onSignal(
7778
\SIGWINCH,
7879
function () {
79-
$this->handleAspectusMessages(Message::resized());
80+
// todo: add actual Y and X
81+
$this->handleAspectusMessages(new Message\WindowResized(1, 1));
8082
}
8183
);
8284
}
@@ -136,7 +138,7 @@ public function enableMouseFocusHandling(): self
136138
*/
137139
public function start(): void
138140
{
139-
$this->runtime->update(Message::init($this));
141+
$this->runtime->update(new Message\Init($this));
140142
// todo: should we handle the new message returned by update() ?
141143
$this->renderer->render($this->runtime);
142144
EventLoop::run();
@@ -159,23 +161,23 @@ private function handleInputEvents(InputEvent $event): void
159161
// this has problems with function keys as well, and possibly other things
160162
// that have "escaped" being treated as special (all those start with 0x1b probably)
161163
foreach (str_split($event->data, 1) as $char) {
162-
$this->updateCycle(Message::keyPress($char));
164+
$this->updateCycle(new Message\KeyPress($char, $char));
163165
}
164166
}
165167

166168
private function handleSpecialInputEvents(SpecialKeyEvent $event): void
167169
{
168-
$this->updateCycle(Message::keyPress($event->data, $event->originalData));
170+
$this->updateCycle(new Message\KeyPress($event->data, $event->originalData));
169171
}
170172

171173
private function handleMouseInputEvents(MouseInputEvent $event): void
172174
{
173-
$this->updateCycle(Message::mouseInput($event));
175+
$this->updateCycle(new Message\MouseInput($event));
174176
}
175177

176178
private function handleMouseFocusEvents(MouseFocusEvent $event): void
177179
{
178-
$this->updateCycle($event->focus() ? Message::mouseFocusIn() : Message::mouseFocusOut());
180+
$this->updateCycle(new Message\MouseFocus($event->focus()));
179181
}
180182

181183
private function updateCycle(Message $message): void
@@ -194,8 +196,8 @@ public function handleAspectusMessages(Message $message): void
194196
// $message maybe contains Aspectus related messages, like Quit, or for example maybe ResizeTriggered.. whatever
195197
// we care about anyway. Or maybe we have another one that says SkipRender which will simply skip the renderer
196198

197-
if ($message->type == Message::QUIT) {
198-
$this->runtime->update(Message::terminate($this));
199+
if ($message->getType() == Message::QUIT) {
200+
$this->runtime->update(new Message\Terminate($this));
199201
// todo: no more message processing ? what if they want to say goodbye?
200202
201203
$this->shutdown();
@@ -220,7 +222,7 @@ function () use (&$identifier) {
220222
/** @var ?Message $message */
221223
static $message = null;
222224
if ($message === null) {
223-
$message = Message::tick((string) $identifier);
225+
$message = new Message\Tick((string) $identifier);
224226
}
225227

226228
if ($newMessage = $this->runtime->update($message)) {

src/Components/Basic/DefaultMainComponent.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function update(?Message $message): ?Message
2525
return null;
2626
}
2727

28-
return match($message->type) {
29-
Message::INIT => $this->onInit($message['reference']),
30-
Message::TERMINATE => $this->onTerminate($message['reference']),
28+
return match(get_class($message)) {
29+
Message\Init::class => $this->onInit($message->aspectus),
30+
Message\Terminate::class => $this->onTerminate($message->aspectus),
3131
default => null
3232
};
3333
}

src/Message.php

Lines changed: 6 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,19 @@
22

33
namespace Aspectus;
44

5-
use Aspectus\Terminal\Xterm\Event\MouseInputEvent;
6-
7-
/**
8-
* @template-implements \ArrayAccess<string, mixed>
9-
*/
10-
final class Message implements \Stringable, \ArrayAccess
5+
interface Message
116
{
127
/** @var string */
13-
public const INIT = 'innit';
14-
15-
/** @var string */
16-
public const KEY_PRESS = 'keyPress';
8+
final public const INIT = 'innit';
179

1810
/** @var string */
19-
public const MOUSE_INPUT = 'mouse';
11+
final public const KEY_PRESS = 'keyPress';
2012

2113
/** @var string */
22-
public const MOUSE_FOCUS_IN = 'mouseFocusIn';
14+
final public const MOUSE_INPUT = 'mouse';
2315

2416
/** @var string */
25-
public const MOUSE_FOCUS_OUT = 'mouseFocusOut';
17+
final public const MOUSE_FOCUS = 'mouseFocus';
2618

2719
/** @var string */
2820
public const TICK = 'tick';
@@ -36,88 +28,5 @@ final class Message implements \Stringable, \ArrayAccess
3628
/** @var string */
3729
public const QUIT = 'quit';
3830

39-
public function __construct(
40-
public readonly string $type,
41-
private array $data = []
42-
) {
43-
}
44-
45-
public function is(string $type): bool
46-
{
47-
return $this->type === $type;
48-
}
49-
50-
public static function init(Aspectus $aspectus): self
51-
{
52-
return new self(self::INIT, ['reference' => $aspectus]);
53-
}
54-
55-
// todo: probably need something better than just a string like that. Xterm pkg should provide
56-
// better handling for characters
57-
public static function keyPress(string $key, ?string $originalData = null): self
58-
{
59-
return new self(self::KEY_PRESS, ['key' => $key, 'original' => $originalData]);
60-
}
61-
62-
public static function mouseInput(MouseInputEvent $event): self
63-
{
64-
return new self(self::MOUSE_INPUT, ['event' => $event]);
65-
}
66-
67-
public static function mouseFocusIn(): self
68-
{
69-
return new self(self::MOUSE_FOCUS_IN);
70-
}
71-
72-
public static function mouseFocusOut(): self
73-
{
74-
return new self(self::MOUSE_FOCUS_OUT);
75-
}
76-
77-
public static function tick(string $identifier): self
78-
{
79-
return new self(self::TICK, ['id' => $identifier]);
80-
}
81-
82-
public static function resized(): self
83-
{
84-
return new self(self::RESIZED);
85-
}
86-
87-
public static function quit(): self
88-
{
89-
return new self(self::QUIT);
90-
}
91-
92-
public static function terminate(Aspectus $aspectus): self
93-
{
94-
return new self(self::TERMINATE, ['reference' => $aspectus]);
95-
}
96-
97-
public function __toString(): string
98-
{
99-
return $this->type;
100-
}
101-
102-
public function offsetExists(mixed $offset): bool
103-
{
104-
return isset($this->data[$offset]);
105-
}
106-
107-
public function offsetGet(mixed $offset): mixed
108-
{
109-
return $this->data[$offset] ?? null;
110-
}
111-
112-
public function offsetSet(mixed $offset, mixed $value): void
113-
{
114-
if ($offset !== null) {
115-
$this->data[$offset] = $value;
116-
}
117-
}
118-
119-
public function offsetUnset(mixed $offset): void
120-
{
121-
unset($this->data[$offset]);
122-
}
31+
public function getType(): string;
12332
}

src/Message/Init.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Aspectus\Message;
4+
5+
use Aspectus\Aspectus;
6+
use Aspectus\Message;
7+
8+
class Init implements Message
9+
{
10+
public function __construct(
11+
/**
12+
* Init message holds a reference to the Aspectus instance
13+
* that emitted the message.
14+
*/
15+
public Aspectus $aspectus
16+
) {
17+
}
18+
19+
public function getType(): string
20+
{
21+
return self::INIT;
22+
}
23+
}

0 commit comments

Comments
 (0)