61 lines
1.6 KiB
Dart
61 lines
1.6 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:friendly_map/modules/core/core.dart';
|
|
|
|
/// 메모리 안에서 여러 기기를 흉내 내는 연결망 (시험·화면 미리보기용).
|
|
/// 받는 사람이 꺼져 있으면 보관함처럼 쌓아 두었다가 [MemoryTransport.fetchPending] 으로 가져간다.
|
|
class MemoryHub {
|
|
final Map<String, MemoryTransport> _online = {};
|
|
final Map<String, List<Envelope>> _mailbox = {};
|
|
|
|
/// 지금까지 오간 봉투 수 (시험에서 확인용).
|
|
int delivered = 0;
|
|
|
|
/// 보관함에 쌓인 것을 쓰지 않는 직접 연결만 흉내 내려면 false.
|
|
bool mailboxEnabled = true;
|
|
|
|
bool _deliver(Envelope e) {
|
|
final target = _online[e.to];
|
|
if (target != null && target._started) {
|
|
delivered++;
|
|
target._in.add(e);
|
|
return true;
|
|
}
|
|
if (!mailboxEnabled) return false;
|
|
_mailbox.putIfAbsent(e.to, () => []).add(e);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class MemoryTransport implements Transport {
|
|
MemoryTransport(this.phone, this._hub) {
|
|
_hub._online[phone] = this;
|
|
}
|
|
|
|
final String phone;
|
|
final MemoryHub _hub;
|
|
final StreamController<Envelope> _in = StreamController<Envelope>.broadcast(sync: true);
|
|
bool _started = false;
|
|
|
|
@override
|
|
Stream<Envelope> get incoming => _in.stream;
|
|
|
|
@override
|
|
Future<void> start() async => _started = true;
|
|
|
|
@override
|
|
Future<void> stop() async => _started = false;
|
|
|
|
@override
|
|
Future<bool> send(Envelope envelope) async => _hub._deliver(envelope);
|
|
|
|
@override
|
|
Future<int> fetchPending() async {
|
|
final items = _hub._mailbox.remove(phone) ?? const <Envelope>[];
|
|
for (final e in items) {
|
|
_in.add(e);
|
|
}
|
|
return items.length;
|
|
}
|
|
}
|