-
Notifications
You must be signed in to change notification settings - Fork 11
/
pixorama_endpoint.dart
77 lines (65 loc) · 2.36 KB
/
pixorama_endpoint.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// lib/src/endpoints/pixorama_endpoint.dart
import 'dart:typed_data';
import 'package:pixorama_server/src/generated/protocol.dart';
import 'package:serverpod/serverpod.dart';
class PixoramaEndpoint extends Endpoint {
static const _imageWidth = 64;
static const _imageHeight = 64;
static const _numPixels = _imageWidth * _imageHeight;
static const _numColorsInPalette = 16;
static const _defaultPixelColor = 2;
final _pixelData = Uint8List(_numPixels)
..fillRange(
0,
_numPixels,
_defaultPixelColor,
);
static const _channelPixelAdded = 'pixel-added';
/// Sets a single pixel and notifies all connected clients about the change.
Future<void> setPixel(
Session session, {
required int colorIndex,
required int pixelIndex,
}) async {
// Check that the input parameters are valid. If not, throw a
// `FormatException`, which will be logged and thrown as
// `ServerpodClientException` in the app.
if (colorIndex < 0 || colorIndex >= _numColorsInPalette) {
throw FormatException('colorIndex is out of range: $colorIndex');
}
if (pixelIndex < 0 || pixelIndex >= _numPixels) {
throw FormatException('pixelIndex is out of range: $pixelIndex');
}
// Update our global image.
_pixelData[pixelIndex] = colorIndex;
// Notify all connected clients that we set a pixel, by posting a message
// to the _channelPixelAdded channel.
session.messages.postMessage(
_channelPixelAdded,
ImageUpdate(
pixelIndex: pixelIndex,
colorIndex: colorIndex,
),
);
}
/// Returns a stream of image updates. The first message will always be a
/// `ImageData` object, which contains the full image. Sequential updates
/// will be `ImageUpdate` objects, which contains a single updated pixel.
Stream imageUpdates(Session session) async* {
// Request a stream of updates from the pixel-added channel in
// MessageCentral.
var updateStream =
session.messages.createStream<ImageUpdate>(_channelPixelAdded);
// Yield a first full image to the client.
yield ImageData(
pixels: _pixelData.buffer.asByteData(),
width: _imageWidth,
height: _imageHeight,
);
// Relay all individual pixel updates from the pixel-added channel to
// the client.
await for (var imageUpdate in updateStream) {
yield imageUpdate;
}
}
}