| // Copyright (c) 2013, 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. |
| |
| library vmservice; |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| import 'dart:isolate'; |
| import 'dart:typed_data'; |
| |
| part 'client.dart'; |
| part 'constants.dart'; |
| part 'running_isolate.dart'; |
| part 'running_isolates.dart'; |
| part 'message.dart'; |
| part 'message_router.dart'; |
| |
| class VMService extends MessageRouter { |
| static VMService _instance; |
| /// Collection of currently connected clients. |
| final Set<Client> clients = new Set<Client>(); |
| /// Collection of currently running isolates. |
| RunningIsolates runningIsolates = new RunningIsolates(); |
| /// Isolate startup and shutdown messages are sent on this port. |
| final RawReceivePort receivePort; |
| |
| void controlMessageHandler(int code, int port_id, SendPort sp, String name) { |
| switch (code) { |
| case Constants.ISOLATE_STARTUP_MESSAGE_ID: |
| runningIsolates.isolateStartup(port_id, sp, name); |
| break; |
| case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID: |
| runningIsolates.isolateShutdown(port_id, sp); |
| break; |
| } |
| } |
| |
| void _addClient(Client client) { |
| clients.add(client); |
| } |
| |
| void _removeClient(Client client) { |
| clients.remove(client); |
| } |
| |
| void messageHandler(message) { |
| assert(message is List); |
| assert(message.length == 4); |
| if (message is List && message.length == 4) { |
| controlMessageHandler(message[0], message[1], message[2], message[3]); |
| } |
| } |
| |
| VMService._internal() : receivePort = new RawReceivePort() { |
| receivePort.handler = messageHandler; |
| } |
| |
| factory VMService() { |
| if (VMService._instance == null) { |
| VMService._instance = new VMService._internal(); |
| } |
| return _instance; |
| } |
| |
| void _clientCollection(Message message) { |
| var members = []; |
| var result = {}; |
| clients.forEach((client) { |
| members.add(client.toJson()); |
| }); |
| result['type'] = 'ClientList'; |
| result['members'] = members; |
| message.setResponse(JSON.encode(result)); |
| } |
| |
| Future<String> route(Message message) { |
| if (message.completed) { |
| return message.response; |
| } |
| if ((message.path.length == 1) && (message.path[0] == 'clients')) { |
| _clientCollection(message); |
| return message.response; |
| } |
| if (message.path[0] == 'isolates') { |
| return runningIsolates.route(message); |
| } |
| return message.sendToVM(); |
| } |
| } |
| |
| RawReceivePort boot() { |
| // Boot the VMService. |
| // Return the port we expect isolate startup and shutdown messages on. |
| return new VMService().receivePort; |
| } |
| |
| void _registerIsolate(int port_id, SendPort sp, String name) { |
| var service = new VMService(); |
| service.runningIsolates.isolateStartup(port_id, sp, name); |
| } |