// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'dart:async'; import 'dart:convert'; import 'package:dwds/data/connect_request.dart'; import 'package:dwds/data/hot_restart_request.dart'; import 'package:dwds/data/run_request.dart'; import 'package:dwds/data/serializers.dart'; import 'package:dwds/src/handlers/socket_connections.dart'; import 'package:dwds/src/utilities/shared.dart'; /// A connection between the application loaded in the browser and DWDS. class AppConnection { /// The initial connection request sent from the application in the browser. final ConnectRequest request; final _startedCompleter = Completer(); final _doneCompleter = Completer(); final SocketConnection _connection; final Future _readyToRunMain; bool get hasStarted => _startedCompleter.isCompleted; AppConnection(this.request, this._connection, this._readyToRunMain) { safeUnawaited(_connection.sink.done.then((v) => _doneCompleter.complete())); } bool get isInKeepAlivePeriod => _connection.isInKeepAlivePeriod; void shutDown() => _connection.shutdown(); bool get isStarted => _startedCompleter.isCompleted; Future get onStart => _startedCompleter.future; bool get isDone => _doneCompleter.isCompleted; Future get onDone => _doneCompleter.future; void runMain() { if (_startedCompleter.isCompleted) { throw StateError('Main has already started.'); } safeUnawaited(_runMain()); } Future _runMain() async { await _readyToRunMain; _connection.sink.add(jsonEncode(serializers.serialize(RunRequest()))); _startedCompleter.complete(); } /// The request to restart when no debugger attached. /// /// In this case, there's no need to block main execution until the debugger /// resends breakpoints. void hotRestart(HotRestartRequest request) => _connection.sink.add(jsonEncode(serializers.serialize(request))); }