Index: runtime/vm/service/vmservice.dart |
diff --git a/runtime/vm/service/vmservice.dart b/runtime/vm/service/vmservice.dart |
index 35fdb84aa8f151a2d4bd0d8f7e917eebece12f65..9183453e1a8cc19ded66773737f8865f4824ec1e 100644 |
--- a/runtime/vm/service/vmservice.dart |
+++ b/runtime/vm/service/vmservice.dart |
@@ -20,12 +20,56 @@ class VMService extends MessageRouter { |
static VMService _instance; |
/// Collection of currently connected clients. |
final Set<Client> clients = new Set<Client>(); |
+ |
+ // A map encoding which clients are interested in which kinds of events. |
+ final Map<int, Set<Client>> eventMap = new Map<int, 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) { |
+ /// A port used to receive events from the VM. |
+ final RawReceivePort eventPort; |
+ |
+ void _addClient(Client client) { |
+ clients.add(client); |
+ } |
+ |
+ void _removeClient(Client client) { |
+ clients.remove(client); |
+ } |
+ |
+ int eventTypeCode(String eventType) { |
+ switch(eventType) { |
+ case 'debug': |
+ return Constants.EVENT_FAMILY_DEBUG; |
+ default: |
+ return -1; |
+ } |
+ } |
+ |
+ void _updateEventMask() { |
+ int mask = 0; |
+ for (var key in eventMap.keys) { |
+ var subscribers = eventMap[key]; |
+ if (subscribers.isNotEmpty) { |
+ mask |= (1 << key); |
+ } |
+ } |
+ _setEventMask(mask); |
+ } |
+ |
+ void subscribe(String eventType, Client client) { |
+ int eventCode = eventTypeCode(eventType); |
+ assert(eventCode >= 0); |
+ var subscribers = eventMap.putIfAbsent(eventCode, () => new Set<Client>()); |
+ subscribers.add(client); |
+ _updateEventMask(); |
+ } |
+ |
+ 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); |
@@ -36,24 +80,30 @@ class VMService extends MessageRouter { |
} |
} |
- void _addClient(Client client) { |
- clients.add(client); |
- } |
- |
- void _removeClient(Client client) { |
- clients.remove(client); |
+ void _eventMessageHandler(int eventType, String eventMessage) { |
+ var subscribers = eventMap[eventType]; |
+ if (subscribers == null) { |
+ return; |
+ } |
+ for (var subscriber in subscribers) { |
+ subscriber.post(null, eventMessage); |
+ } |
} |
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]); |
+ _controlMessageHandler(message[0], message[1], message[2], message[3]); |
+ } else if (message is List && message.length == 2) { |
+ _eventMessageHandler(message[0], message[1]); |
+ } else { |
+ Logger.root.severe('Unexpected message: $message'); |
} |
} |
- VMService._internal() : receivePort = new RawReceivePort() { |
- receivePort.handler = messageHandler; |
+ VMService._internal() |
+ : eventPort = new RawReceivePort() { |
+ eventPort.handler = messageHandler; |
} |
factory VMService() { |
@@ -92,10 +142,13 @@ class VMService extends MessageRouter { |
RawReceivePort boot() { |
// Boot the VMService. |
// Return the port we expect isolate startup and shutdown messages on. |
- return new VMService().receivePort; |
+ return new VMService().eventPort; |
} |
void _registerIsolate(int port_id, SendPort sp, String name) { |
var service = new VMService(); |
service.runningIsolates.isolateStartup(port_id, sp, name); |
} |
+ |
+void _setEventMask(int mask) |
+ native "VMService_SetEventMask"; |