Skip to content

Commit 653d4ff

Browse files
Merge pull request #48 from HaudinFlorence/improve_bluetooth_manager_class
Improve bluetoothManager class
2 parents 6752423 + dbe1eb2 commit 653d4ff

5 files changed

Lines changed: 72 additions & 108 deletions

File tree

src/bluetooth-extension/index.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
export namespace CommandIDs {
1717
export const openDeviceRegistryDialog =
1818
'bluetooth-manager:open-dialog-for-devices-registry';
19-
export const disconnectDevice = 'bluetooth-manager:disconnect-device';
19+
export const disconnect = 'bluetooth-manager:disconnect-device';
2020
}
2121

2222
export function buildCompleteIdentifier(native: BluetoothDevice): string {
@@ -67,13 +67,13 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
6767
const openDeviceRegistryDialogLabel = trans.__('Add a Device');
6868
let runningItemsList: Array<IRunningSessions.IRunningItem>;
6969

70-
app.commands.addCommand(CommandIDs.disconnectDevice, {
70+
app.commands.addCommand(CommandIDs.disconnect, {
7171
execute: args => {
7272
const selectedDevice = bluetoothManager.deviceList.find(
7373
device => device.native.id === (args.deviceID as string)
7474
);
7575
if (selectedDevice) {
76-
bluetoothManager.disconnectDevice(selectedDevice);
76+
bluetoothManager.disconnect(selectedDevice);
7777
return selectedDevice;
7878
} else {
7979
throw new Error('No device provided or device is invalid');
@@ -87,20 +87,24 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
8787
execute: async () => {
8888
showDialog({
8989
title: 'Select device type',
90-
body: new DropDownRegistry(bluetoothManager.registry),
90+
body: new DropDownRegistry(bluetoothManager.deviceTypeRegistry),
9191
buttons: [
9292
Dialog.okButton({ label: 'Select' }),
9393
Dialog.cancelButton({ label: 'Cancel' })
9494
]
9595
}).then(async result => {
9696
if (result.button.accept) {
97-
bluetoothManager.registry.itemsList.forEach(async item => {
98-
if (item.deviceType === result.value) {
99-
await bluetoothManager.connectDevice(item);
100-
} else {
101-
console.warn('There is no corresponding item in the registry!');
97+
bluetoothManager.deviceTypeRegistry.deviceTypes.forEach(
98+
async item => {
99+
if (item.deviceType === result.value) {
100+
await bluetoothManager.connect(item);
101+
} else {
102+
console.warn(
103+
'There is no corresponding item in the registry!'
104+
);
105+
}
102106
}
103-
});
107+
);
104108
}
105109
});
106110
}
@@ -151,12 +155,12 @@ export class DropDownRegistry
151155
extends Widget
152156
implements Dialog.IBodyWidget<string>
153157
{
154-
constructor(registry: BluetoothManager.DeviceRegistry) {
158+
constructor(registry: BluetoothManager.DeviceTypeRegistry) {
155159
super();
156160
this._selectList = document.createElement('select');
157161
this.node.appendChild(this._selectList);
158162
this.registry = registry;
159-
registry.itemsList.forEach(item => {
163+
registry.deviceTypes.forEach(item => {
160164
const option = document.createElement('option');
161165
option.value = item.deviceType;
162166
option.text = item.deviceType;
@@ -169,7 +173,7 @@ export class DropDownRegistry
169173
}
170174

171175
private _selectList: HTMLSelectElement;
172-
public registry: BluetoothManager.DeviceRegistry;
176+
public registry: BluetoothManager.DeviceTypeRegistry;
173177
}
174178

175179
const BluetoothExtensionPlugins: JupyterFrontEndPlugin<any>[] = [

src/bluetooth/BluetoothDeviceRunningItem.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { buildCompleteIdentifier } from '../bluetooth-extension';
55
import { Menu } from '@lumino/widgets';
66
import { CommandRegistry } from '@lumino/commands';
77

8-
export const disconnectDevice = 'bluetooth-manager:disconnect-device';
8+
export const disconnect = 'bluetooth-manager:disconnect-device';
99

1010
export class BluetoothDeviceRunningItem
1111
implements IRunningSessions.IRunningItem
@@ -58,7 +58,7 @@ export class BluetoothDeviceRunningItem
5858
}
5959

6060
shutdown() {
61-
this.bluetoothManager.disconnectDevice(this._device);
61+
this.bluetoothManager.disconnect(this._device);
6262
}
6363

6464
private _device: BluetoothManager.Device;

src/bluetooth/BluetoothManager.ts

Lines changed: 40 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ export class BluetoothManager implements IBluetoothManager {
1313
this.deviceListChanged = new Signal<this, Array<BluetoothManager.Device>>(
1414
this
1515
);
16-
this.registeredByAPlugin = new Signal<
17-
this,
18-
BluetoothManager.DeviceRegistry
19-
>(this);
20-
this._registry = new BluetoothManager.DeviceRegistry();
16+
this._deviceTypeRegistry = new BluetoothManager.DeviceTypeRegistry();
2117
this._deviceList = [];
2218
this._identifierRegistry = [];
2319
}
@@ -26,54 +22,50 @@ export class BluetoothManager implements IBluetoothManager {
2622
return this._deviceList;
2723
}
2824

29-
get registry(): BluetoothManager.DeviceRegistry {
30-
return this._registry;
25+
get deviceTypeRegistry(): BluetoothManager.DeviceTypeRegistry {
26+
return this._deviceTypeRegistry;
3127
}
3228

33-
get identifierRegistry(): Array<string> {
34-
return this._identifierRegistry;
35-
}
36-
37-
async connectDevice(
38-
registryItem: IDeviceRegistryItem
29+
async connect(
30+
registryItem: IDeviceTypeRegistryItem
3931
): Promise<BluetoothManager.Device | undefined> {
4032
const native = await this.requestDevice(registryItem);
4133
if (native) {
4234
const device = await registryItem.factory(native);
4335
if (device && device.isConnected) {
44-
this.addDeviceToList(device);
36+
this._addDeviceToList(device);
4537
device.disconnected.connect(async () => {
46-
this.removeDeviceFromList(device);
38+
this._removeDeviceFromList(device);
4739
});
4840
return device;
4941
}
5042
}
5143
}
5244

53-
async disconnectDevice(device: BluetoothManager.Device) {
45+
async disconnect(device: BluetoothManager.Device) {
5446
await device.disconnect();
5547
device.dispose();
5648
}
5749

5850
// Method to add a device to the list
59-
addDeviceToList(device: BluetoothManager.Device): void {
51+
private _addDeviceToList(device: BluetoothManager.Device): void {
6052
const identifier = buildCompleteIdentifier(device.native);
61-
if (this.identifierRegistry.includes(identifier) === false) {
53+
if (this._identifierRegistry.includes(identifier) === false) {
6254
this._deviceList.push(device);
63-
this.identifierRegistry.push(identifier);
55+
this._identifierRegistry.push(identifier);
6456
} else {
65-
console.warn('The device is already in the identifierRegistry');
57+
console.warn('The device is already in the registry of identifiers');
6658
}
6759
// Emit the signal when the list changes
6860
this.deviceListChanged.emit(this._deviceList);
6961
}
7062

7163
// Method to remove a device from the list
72-
removeDeviceFromList(device: BluetoothManager.Device): void {
64+
private _removeDeviceFromList(device: BluetoothManager.Device): void {
7365
const index = this._deviceList.indexOf(device);
7466
if (index > -1) {
7567
this._deviceList.splice(index, 1);
76-
this.identifierRegistry.splice(index, 1);
68+
this._identifierRegistry.splice(index, 1);
7769
// Emit the signal when the list changes
7870
this.deviceListChanged.emit(this._deviceList);
7971
}
@@ -82,20 +74,11 @@ export class BluetoothManager implements IBluetoothManager {
8274

8375
removeAllDevices() {
8476
this._deviceList.forEach((device, index) => {
85-
this.removeDeviceFromList(device);
77+
this._removeDeviceFromList(device);
8678
this.deviceListChanged.emit(this._deviceList);
8779
});
8880
}
8981

90-
register(registryItem: IDeviceRegistryItem) {
91-
this._registry.add(registryItem);
92-
this.registeredByAPlugin.emit(this._registry);
93-
console.warn(
94-
`New item from category ${registryItem.deviceType} is added to the registry.`
95-
);
96-
return this._registry;
97-
}
98-
9982
async checkWebBluetoothSupport(): Promise<boolean> {
10083
const isWebBluetoothSupported: boolean = navigator.bluetooth ? true : false;
10184
if (isWebBluetoothSupported === false) {
@@ -109,7 +92,7 @@ export class BluetoothManager implements IBluetoothManager {
10992
}
11093

11194
async requestDevice(
112-
registryItem: IDeviceRegistryItem
95+
registryItem: IDeviceTypeRegistryItem
11396
): Promise<BluetoothDevice | undefined> {
11497
const isWebBluetoothSupported = await this.checkWebBluetoothSupport();
11598
if (isWebBluetoothSupported) {
@@ -124,11 +107,7 @@ export class BluetoothManager implements IBluetoothManager {
124107

125108
private _deviceList: Array<BluetoothManager.Device>;
126109
public deviceListChanged: Signal<this, Array<BluetoothManager.Device>>;
127-
public registeredByAPlugin: Signal<
128-
BluetoothManager,
129-
BluetoothManager.DeviceRegistry
130-
>;
131-
private _registry: BluetoothManager.DeviceRegistry;
110+
private _deviceTypeRegistry: BluetoothManager.DeviceTypeRegistry;
132111
private _identifierRegistry: Array<string>;
133112
}
134113

@@ -204,32 +183,6 @@ export namespace BluetoothManager {
204183
}
205184
}
206185

207-
/*async connectAndGetAllServices(): Promise<
208-
Array<BluetoothRemoteGATTService> | undefined
209-
> {
210-
this.native.addEventListener('gattserverdisconnected', event => {
211-
this.isConnected = false;
212-
this.disconnected.emit(true);
213-
});
214-
const server = this.native.gatt
215-
if (server) {
216-
server.connect();
217-
if (server.connected === true) {
218-
const services = await server.getPrimaryServices();
219-
this.isConnected = true;
220-
if (!services || services.length === 0) {
221-
throw new Error('Server exists but no service found on the device.');
222-
} else { return services; }
223-
}
224-
else {
225-
throw new Error('There is no connection to server. No attempt to get a service.')
226-
}
227-
}
228-
else {
229-
throw new Error('Server is not defined.');
230-
}
231-
}*/
232-
233186
async disconnect(): Promise<void> {
234187
if (this.native) {
235188
this.native.gatt?.disconnect();
@@ -283,53 +236,53 @@ export namespace BluetoothManager {
283236
}
284237
}
285238

286-
export class DeviceRegistry implements IDeviceRegistry {
287-
private _registry: Array<IDeviceRegistryItem>;
288-
public registryItem: IDeviceRegistryItem;
239+
export class DeviceTypeRegistry implements IDeviceTypeRegistry {
289240
constructor() {
290-
this._registry = [];
241+
this._deviceTypes = [];
242+
this._added = new Signal<this, IDeviceTypeRegistryItem>(this);
243+
}
244+
245+
add(registryItem: IDeviceTypeRegistryItem) {
246+
this._deviceTypes.push(registryItem);
247+
this._added.emit(registryItem);
291248
}
292249

293-
add(registryItem: IDeviceRegistryItem) {
294-
this._registry.push(registryItem);
250+
get deviceTypes(): IDeviceTypeRegistryItem[] {
251+
return this._deviceTypes;
295252
}
296-
get itemsList(): Array<IDeviceRegistryItem> {
297-
return this._registry;
253+
254+
get added(): Signal<this, IDeviceTypeRegistryItem> {
255+
return this._added;
298256
}
257+
258+
private _deviceTypes: Array<IDeviceTypeRegistryItem>;
259+
private _added: Signal<this, IDeviceTypeRegistryItem>;
299260
}
300261
}
301262

302263
/**
303264
* Interface for the bluetooth manager.
304265
*/
305266
export interface IBluetoothManager {
306-
addDeviceToList(Device: BluetoothManager.Device): void;
307-
removeDeviceFromList(Device: BluetoothManager.Device): void;
308267
removeAllDevices(Devices: Array<BluetoothManager.Device>): void;
309-
register(registryItem: IDeviceRegistryItem): BluetoothManager.DeviceRegistry;
310-
connectDevice(registryItem: IDeviceRegistryItem): any;
311-
disconnectDevice(device: BluetoothManager.Device): void;
268+
connect(registryItem: IDeviceTypeRegistryItem): any;
269+
disconnect(device: BluetoothManager.Device): void;
312270
deviceListChanged: Signal<BluetoothManager, Array<BluetoothManager.Device>>;
313-
registeredByAPlugin: Signal<
314-
BluetoothManager,
315-
BluetoothManager.DeviceRegistry
316-
>;
317271
get deviceList(): Array<BluetoothManager.Device>;
318-
get registry(): BluetoothManager.DeviceRegistry;
319-
get identifierRegistry(): Array<string>;
272+
get deviceTypeRegistry(): BluetoothManager.DeviceTypeRegistry;
320273
}
321274

322-
export interface IDeviceRegistryItem {
275+
export interface IDeviceTypeRegistryItem {
323276
deviceType: string;
324277
factory: (
325278
native: BluetoothDevice
326279
) => Promise<BluetoothManager.Device | undefined>;
327280
options: IDeviceOptions;
328281
}
329282

330-
export interface IDeviceRegistry {
331-
add: (registryItem: IDeviceRegistryItem) => void;
332-
get itemsList(): Array<IDeviceRegistryItem>;
283+
export interface IDeviceTypeRegistry {
284+
add: (registryItem: IDeviceTypeRegistryItem) => void;
285+
get deviceTypes(): IDeviceTypeRegistryItem[];
333286
}
334287

335288
export const IBluetoothManager = new Token<IBluetoothManager>(

src/movehub-extension/index.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { ITranslator } from '@jupyterlab/translation';
66
import { IThemeManager, MainAreaWidget } from '@jupyterlab/apputils';
77
import { Toolbar } from '@jupyterlab/ui-components';
88
import {
9-
IDeviceRegistryItem,
9+
IDeviceTypeRegistryItem,
1010
IBluetoothManager,
1111
BluetoothManager
1212
} from '../bluetooth/BluetoothManager';
@@ -27,7 +27,7 @@ export const connectMoveHub = 'bluetooth-manager:connect-movehub';
2727
export const disconnectMoveHub = 'bluetooth-manager:disconnect-movehub';
2828
export const moveHubServiceUUID = '00001623-1212-efde-1623-785feabcd123';
2929
export const moveHubCharacteristicUUID = '00001624-1212-efde-1623-785feabcd123';
30-
export const movehubRegistryItem: IDeviceRegistryItem = {
30+
export const movehubRegistryItem: IDeviceTypeRegistryItem = {
3131
deviceType: 'LEGO® Move Hub',
3232
options: {
3333
acceptAllDevices: false,
@@ -56,7 +56,14 @@ const MoveHubRegisterPlugin: JupyterFrontEndPlugin<void> = {
5656
bluetoothManager: BluetoothManager
5757
): void => {
5858
console.log('JupyterLab move-hub-register plugin is activated!');
59-
bluetoothManager.register(movehubRegistryItem);
59+
bluetoothManager.deviceTypeRegistry.added.connect(
60+
async (sender, movehubRegistryItem) => {
61+
console.warn(
62+
`New item from category ${movehubRegistryItem.deviceType} is added to the deviceType registry.`
63+
);
64+
}
65+
);
66+
bluetoothManager.deviceTypeRegistry.add(movehubRegistryItem);
6067
}
6168
};
6269

@@ -125,7 +132,7 @@ const LEGOMoveHubControlPanelPlugin: JupyterFrontEndPlugin<void> = {
125132
device => device.native.id === (args.deviceID as string)
126133
);
127134
if (selectedDevice && selectedDevice instanceof MoveHub) {
128-
bluetoothManager.disconnectDevice(selectedDevice);
135+
bluetoothManager.disconnect(selectedDevice);
129136
return selectedDevice;
130137
} else {
131138
throw new Error('No device provided or device is invalid');
@@ -151,7 +158,7 @@ const LEGOMoveHubControlPanelPlugin: JupyterFrontEndPlugin<void> = {
151158

152159
app.commands.addCommand(connectMoveHub, {
153160
execute: args => {
154-
const newDevice = bluetoothManager.connectDevice(movehubRegistryItem);
161+
const newDevice = bluetoothManager.connect(movehubRegistryItem);
155162
return newDevice;
156163
},
157164
caption: 'Connect MoveHub',

src/movehub-extension/widget.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export class MoveHubModel extends DOMWidgetModel {
174174
console.log('not connected yet');*/
175175
if (identifier === '') {
176176
this.movehub =
177-
await MoveHubModel.bluetoothManager.connectDevice(movehubRegistryItem);
177+
await MoveHubModel.bluetoothManager.connect(movehubRegistryItem);
178178
} else {
179179
const selectedDevice = MoveHubModel.bluetoothManager.deviceList.find(
180180
device => device.native.id === identifier

0 commit comments

Comments
 (0)