mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-18 08:46:33 +00:00
monitor service provider singleton
This commit is contained in:
parent
0427759fdb
commit
a4ff05a82b
@ -85,8 +85,14 @@ import { ArduinoLocalizationContribution } from './arduino-localization-contribu
|
|||||||
import { LocalizationContribution } from '@theia/core/lib/node/i18n/localization-contribution';
|
import { LocalizationContribution } from '@theia/core/lib/node/i18n/localization-contribution';
|
||||||
import { MonitorManagerProxyImpl } from './monitor-manager-proxy-impl';
|
import { MonitorManagerProxyImpl } from './monitor-manager-proxy-impl';
|
||||||
import { MonitorManager, MonitorManagerName } from './monitor-manager';
|
import { MonitorManager, MonitorManagerName } from './monitor-manager';
|
||||||
import { MonitorManagerProxy, MonitorManagerProxyClient, MonitorManagerProxyPath } from '../common/protocol/monitor-service';
|
import {
|
||||||
|
MonitorManagerProxy,
|
||||||
|
MonitorManagerProxyClient,
|
||||||
|
MonitorManagerProxyPath,
|
||||||
|
} from '../common/protocol/monitor-service';
|
||||||
import { MonitorServiceName } from './monitor-service';
|
import { MonitorServiceName } from './monitor-service';
|
||||||
|
import { MonitorSettingsProvider } from './monitor-settings/monitor-settings-provider';
|
||||||
|
import { MonitorSettingsProviderImpl } from './monitor-settings/monitor-settings-provider-impl';
|
||||||
|
|
||||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||||
bind(BackendApplication).toSelf().inSingletonScope();
|
bind(BackendApplication).toSelf().inSingletonScope();
|
||||||
@ -198,6 +204,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
// a single MonitorManager is responsible for handling the actual connections to the pluggable monitors
|
// a single MonitorManager is responsible for handling the actual connections to the pluggable monitors
|
||||||
bind(MonitorManager).toSelf().inSingletonScope();
|
bind(MonitorManager).toSelf().inSingletonScope();
|
||||||
|
|
||||||
|
bind(MonitorSettingsProviderImpl).toSelf().inSingletonScope();
|
||||||
|
bind(MonitorSettingsProvider).toService(MonitorSettingsProviderImpl);
|
||||||
|
|
||||||
// Serial client provider per connected frontend.
|
// Serial client provider per connected frontend.
|
||||||
bind(ConnectionContainerModule).toConstantValue(
|
bind(ConnectionContainerModule).toConstantValue(
|
||||||
ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
||||||
|
@ -122,10 +122,18 @@ export class MonitorService extends CoreClientAware implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.info('starting monitor');
|
this.logger.info('starting monitor');
|
||||||
this.settings = await this.monitorSettingsProvider.init(
|
|
||||||
monitorID,
|
// get default monitor settings from the CLI
|
||||||
this.coreClientProvider
|
const defaultSettings = await this.portMonitorSettings(
|
||||||
|
this.port.protocol,
|
||||||
|
this.board.fqbn
|
||||||
);
|
);
|
||||||
|
// get actual settings from the settings provider
|
||||||
|
this.settings = await this.monitorSettingsProvider.getSettings(
|
||||||
|
monitorID,
|
||||||
|
defaultSettings
|
||||||
|
);
|
||||||
|
|
||||||
await this.coreClientProvider.initialized;
|
await this.coreClientProvider.initialized;
|
||||||
const coreClient = await this.coreClient();
|
const coreClient = await this.coreClient();
|
||||||
const { client, instance } = coreClient;
|
const { client, instance } = coreClient;
|
||||||
|
@ -1,47 +1,145 @@
|
|||||||
import { injectable } from 'inversify';
|
import * as fs from 'fs';
|
||||||
import { CoreClientProvider } from '../core-client-provider';
|
import { join } from 'path';
|
||||||
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
|
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||||
|
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PluggableMonitorSettings,
|
PluggableMonitorSettings,
|
||||||
MonitorSettingsProvider,
|
MonitorSettingsProvider,
|
||||||
MonitorSettings,
|
|
||||||
} from './monitor-settings-provider';
|
} from './monitor-settings-provider';
|
||||||
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
|
|
||||||
|
const MONITOR_SETTINGS_FILE = 'pluggable-monitor-settings.json';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class MonitorSettingsProviderImpl implements MonitorSettingsProvider {
|
export class MonitorSettingsProviderImpl implements MonitorSettingsProvider {
|
||||||
// this is populated with all settings coming from the CLI. This should never get modified
|
@inject(EnvVariablesServer)
|
||||||
// as it is used to double actual values set by the user
|
protected readonly envVariablesServer: EnvVariablesServer;
|
||||||
private monitorSettings: MonitorSettings;
|
|
||||||
|
|
||||||
// this contains values for setting of the monitorSettings
|
protected ready = new Deferred<void>();
|
||||||
// the key is MonitorSetting.id, the value should be one of the MonitorSetting.values
|
|
||||||
private monitorSettingsValues: Record<string, any>;
|
|
||||||
|
|
||||||
init(
|
// this is populated with all settings coming from the CLI. This should never be modified
|
||||||
id: string,
|
// // as it is used to double check the monitorSettings attribute
|
||||||
coreClientProvider: CoreClientProvider
|
// private monitorDefaultSettings: PluggableMonitorSettings;
|
||||||
|
|
||||||
|
// this contains actual values coming from the stored file and edited by the user
|
||||||
|
// this is a map with MonitorId as key and PluggableMonitorSetting as value
|
||||||
|
private monitorSettings: Record<string, PluggableMonitorSettings>;
|
||||||
|
|
||||||
|
private pluggableMonitorSettingsPath: string;
|
||||||
|
|
||||||
|
@postConstruct()
|
||||||
|
protected async init(): Promise<void> {
|
||||||
|
// get the monitor settings file path
|
||||||
|
const configDirUri = await this.envVariablesServer.getConfigDirUri();
|
||||||
|
this.pluggableMonitorSettingsPath = join(
|
||||||
|
FileUri.fsPath(configDirUri),
|
||||||
|
MONITOR_SETTINGS_FILE
|
||||||
|
);
|
||||||
|
|
||||||
|
// read existing settings
|
||||||
|
this.readFile();
|
||||||
|
|
||||||
|
console.log(this.monitorSettings);
|
||||||
|
this.ready.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSettings(
|
||||||
|
monitorId: string,
|
||||||
|
defaultSettings: PluggableMonitorSettings
|
||||||
): Promise<PluggableMonitorSettings> {
|
): Promise<PluggableMonitorSettings> {
|
||||||
throw new Error('Method not implemented.');
|
// wait for the service to complete the init
|
||||||
|
await this.ready.promise;
|
||||||
|
|
||||||
// 1. query the CLI (via coreClientProvider) and return all available settings for the pluggable monitor.
|
const { matchingSettings } = this.longestPrefixMatch(monitorId);
|
||||||
// store these in `monitorSettings` for later checkings
|
|
||||||
|
|
||||||
// 2. check for the settings file in the user's home directory
|
return this.reconcileSettings(matchingSettings, defaultSettings);
|
||||||
// a. if it doesn't exist, create it as an empty json file
|
|
||||||
// 3. search the file, looking for the longest prefix matching the id
|
|
||||||
// a. miss: populate `monitorSettingsValues` with all default settings from `monitorSettings`
|
|
||||||
// b. hit: populate `monitorSettingsValues` with the result for the search
|
|
||||||
// i. purge the `monitorSettingsValues` removing keys that are not defined in `monitorSettings`
|
|
||||||
// and adding those that are missing
|
|
||||||
// ii. save the `monitorSettingsValues` in the file, using the id as the key
|
|
||||||
}
|
}
|
||||||
get(): Promise<PluggableMonitorSettings> {
|
async setSettings(
|
||||||
throw new Error('Method not implemented.');
|
monitorId: string,
|
||||||
}
|
settings: PluggableMonitorSettings
|
||||||
set(settings: PluggableMonitorSettings): Promise<PluggableMonitorSettings> {
|
): Promise<PluggableMonitorSettings> {
|
||||||
throw new Error('Method not implemented.');
|
// wait for the service to complete the init
|
||||||
|
await this.ready.promise;
|
||||||
|
|
||||||
// 1. parse the settings parameter and remove any setting that is not defined in `monitorSettings`
|
const newSettings = this.reconcileSettings(
|
||||||
// 2. update `monitorSettingsValues` accordingly
|
settings,
|
||||||
// 3. save it to the file
|
this.monitorSettings[monitorId]
|
||||||
|
);
|
||||||
|
this.monitorSettings[monitorId] = newSettings;
|
||||||
|
|
||||||
|
await this.writeFile();
|
||||||
|
return newSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private reconcileSettings(
|
||||||
|
newSettings: PluggableMonitorSettings,
|
||||||
|
defaultSettings: PluggableMonitorSettings
|
||||||
|
): PluggableMonitorSettings {
|
||||||
|
// TODO: implement
|
||||||
|
return newSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async readFile(): Promise<void> {
|
||||||
|
const rawJson = await promisify(fs.readFile)(
|
||||||
|
this.pluggableMonitorSettingsPath,
|
||||||
|
{
|
||||||
|
encoding: 'utf-8',
|
||||||
|
flag: 'a+', // a+ = append and read, creating the file if it doesn't exist
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!rawJson) {
|
||||||
|
this.monitorSettings = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.monitorSettings = JSON.parse(rawJson);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
'Could not parse the pluggable monitor settings file. Using empty file.'
|
||||||
|
);
|
||||||
|
this.monitorSettings = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async writeFile() {
|
||||||
|
await promisify(fs.writeFile)(
|
||||||
|
this.pluggableMonitorSettingsPath,
|
||||||
|
JSON.stringify(this.monitorSettings)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private longestPrefixMatch(id: string): {
|
||||||
|
matchingPrefix: string;
|
||||||
|
matchingSettings: PluggableMonitorSettings;
|
||||||
|
} {
|
||||||
|
const separator = '-';
|
||||||
|
const idTokens = id.split(separator);
|
||||||
|
|
||||||
|
let matchingPrefix = '';
|
||||||
|
let matchingSettings: PluggableMonitorSettings = {};
|
||||||
|
|
||||||
|
const monitorSettingsKeys = Object.keys(this.monitorSettings);
|
||||||
|
|
||||||
|
for (let i = 0; i < idTokens.length; i++) {
|
||||||
|
const prefix = idTokens.slice(0, i + 1).join(separator);
|
||||||
|
|
||||||
|
for (let k = 0; k < monitorSettingsKeys.length; k++) {
|
||||||
|
if (monitorSettingsKeys[k].startsWith(prefix)) {
|
||||||
|
matchingPrefix = prefix;
|
||||||
|
matchingSettings = this.monitorSettings[monitorSettingsKeys[k]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchingPrefix.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { matchingPrefix, matchingSettings };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { MonitorModel } from '../../browser/monitor-model';
|
import { MonitorModel } from '../../browser/monitor-model';
|
||||||
import { PluggableMonitorSetting } from '../../common/protocol';
|
import { PluggableMonitorSetting } from '../../common/protocol';
|
||||||
import { CoreClientProvider } from '../core-client-provider';
|
|
||||||
|
|
||||||
export type PluggableMonitorSettings = Record<string, PluggableMonitorSetting>;
|
export type PluggableMonitorSettings = Record<string, PluggableMonitorSetting>;
|
||||||
export interface MonitorSettings {
|
export interface MonitorSettings {
|
||||||
@ -10,10 +9,12 @@ export interface MonitorSettings {
|
|||||||
|
|
||||||
export const MonitorSettingsProvider = Symbol('MonitorSettingsProvider');
|
export const MonitorSettingsProvider = Symbol('MonitorSettingsProvider');
|
||||||
export interface MonitorSettingsProvider {
|
export interface MonitorSettingsProvider {
|
||||||
init(
|
getSettings(
|
||||||
id: string,
|
monitorId: string,
|
||||||
coreClientProvider: CoreClientProvider
|
defaultSettings: PluggableMonitorSettings
|
||||||
|
): Promise<PluggableMonitorSettings>;
|
||||||
|
setSettings(
|
||||||
|
monitorId: string,
|
||||||
|
settings: PluggableMonitorSettings
|
||||||
): Promise<PluggableMonitorSettings>;
|
): Promise<PluggableMonitorSettings>;
|
||||||
get(): Promise<PluggableMonitorSettings>;
|
|
||||||
set(settings: PluggableMonitorSettings): Promise<PluggableMonitorSettings>;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user