Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit d6c7b5a

Browse files
elektronikworkshopadiazulay
authored andcommitted
New classes which will improve the device settings management and event handling. To be integrated with one of the next commits.
1 parent d712a94 commit d6c7b5a

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

src/deviceSettings.ts

+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import * as vscode from "vscode";
4+
5+
import * as constants from "./common/constants";
6+
import * as util from "./common/util";
7+
import * as logger from "./logger/logger";
8+
9+
/**
10+
* Generic class which provides monitoring of a specific settings value.
11+
* If the value is modified a flag is set and an event is emitted.
12+
*
13+
* Usually you want to specialize the setter for any given value type
14+
* to prevent invalid or badly formatted values to enter your settings.
15+
*/
16+
class Setting<T> {
17+
/** The setting's default value. */
18+
public readonly default: T;
19+
/** The actual value of the setting. */
20+
private _value: T | undefined;
21+
/** Indicates if the value was changed since the last call to this.commit(). */
22+
private _modified: boolean;
23+
/** Event emitter which fires when the value is changed. */
24+
private _emitter: vscode.EventEmitter<T> = new vscode.EventEmitter<T>();
25+
26+
constructor(defaultValue?: T) {
27+
this.default = defaultValue;
28+
this._value = this.default;
29+
}
30+
/**
31+
* Value-setter - sets the value.
32+
* If modified, the modified flag is set and the modified event is
33+
* fired.
34+
*/
35+
public set value(value: T | undefined) {
36+
if (value !== this._value) {
37+
this._value = value;
38+
this._modified = true;
39+
this._emitter.fire(this._value);
40+
}
41+
}
42+
/** Value-getter - returns the internal value. */
43+
public get value() {
44+
return this._value;
45+
}
46+
/**
47+
* Returns true, if the internal value has been modified.
48+
* To clear the modified flag call commit().
49+
*/
50+
public get modified() {
51+
return this._modified;
52+
}
53+
/** Returns the modified-event emitter. */
54+
public get emitter() {
55+
return this._emitter;
56+
}
57+
/**
58+
* Returns the internal value to its default value.
59+
* If the default value is different from the previous value,
60+
* it triggers the modified event and the modified flag is set.
61+
*/
62+
public reset() {
63+
this.value = this.default;
64+
}
65+
/** Reset the modified flag (if you know what you're doing) */
66+
public commit() {
67+
this._modified = false;
68+
}
69+
}
70+
71+
/**
72+
* String specialization of the Setting class.
73+
*/
74+
class StrSetting extends Setting<string> {
75+
/**
76+
* When we override setter (below) we have to override getter as well
77+
* (see JS language specs).
78+
*/
79+
public get value() {
80+
return super.value;
81+
}
82+
/**
83+
* Set string value. Anything else than a string will set the value to
84+
* its default value (undefined). White spaces at the front and back are
85+
* trimmed before setting the value.
86+
* If the setting's value is changed during this operation, the base
87+
* class' event emitter will fire and the modified flag will be set.
88+
*/
89+
public set value(value: string) {
90+
if (typeof value !== "string") {
91+
value = this.default;
92+
} else {
93+
value = value.trim();
94+
}
95+
super.value = value;
96+
}
97+
}
98+
99+
/**
100+
* This class encapsulates all device/project specific settings and
101+
* provides common operations on them.
102+
*/
103+
export class DeviceSettings {
104+
public port = new StrSetting();
105+
public board = new StrSetting();
106+
public sketch = new StrSetting();
107+
public output = new StrSetting();
108+
public debugger = new StrSetting();
109+
public disableIntelliSenseAutoGen = new StrSetting();
110+
public configuration = new StrSetting();
111+
public prebuild = new StrSetting();
112+
public programmer = new StrSetting();
113+
114+
/**
115+
* @returns true if any of the settings values has its modified flag
116+
* set.
117+
*/
118+
public get modified() {
119+
return this.port.modified ||
120+
this.board.modified ||
121+
this.sketch.modified ||
122+
this.output.modified ||
123+
this.debugger.modified ||
124+
this.disableIntelliSenseAutoGen.modified ||
125+
this.configuration.modified ||
126+
this.prebuild.modified ||
127+
this.programmer.modified;
128+
}
129+
/**
130+
* Clear modified flags of all settings values.
131+
*/
132+
public commit() {
133+
this.port.commit();
134+
this.board.commit();
135+
this.sketch.commit();
136+
this.output.commit();
137+
this.debugger.commit();
138+
this.disableIntelliSenseAutoGen.commit();
139+
this.configuration.commit();
140+
this.prebuild.commit();
141+
this.programmer.commit();
142+
}
143+
/**
144+
* Resets all settings values to their default values.
145+
* @param commit If true clear the modified flags after all values are
146+
* reset.
147+
*/
148+
public reset(commit: boolean = true) {
149+
this.port.reset();
150+
this.board.reset();
151+
this.sketch.reset();
152+
this.output.reset();
153+
this.debugger.reset();
154+
this.disableIntelliSenseAutoGen.reset();
155+
this.configuration.reset();
156+
this.prebuild.reset();
157+
this.programmer.reset();
158+
if (commit) {
159+
this.commit();
160+
}
161+
}
162+
/**
163+
* Load settings values from the given file.
164+
* If a value is changed through this operation, its event emitter will
165+
* fire.
166+
* @param file Path to the file the settings should be loaded from.
167+
* @param commit If true reset the modified flags after all values are read.
168+
* @returns true if the settings are loaded successfully.
169+
*/
170+
public load(file: string, commit: boolean = true) {
171+
const settings = util.tryParseJSON(fs.readFileSync(file, "utf8"));
172+
if (settings) {
173+
this.port.value = settings.port;
174+
this.board.value = settings.board;
175+
this.sketch.value = settings.sketch;
176+
this.configuration.value = settings.configuration;
177+
this.output.value = settings.output;
178+
this.debugger.value = settings.debugger;
179+
this.disableIntelliSenseAutoGen.value = settings.disableIntelliSenseAutoGen;
180+
this.prebuild.value = settings.prebuild;
181+
this.programmer.value = settings.programmer;
182+
if (commit) {
183+
this.commit();
184+
}
185+
return true;
186+
} else {
187+
logger.notifyUserError("arduinoFileError",
188+
new Error(constants.messages.ARDUINO_FILE_ERROR));
189+
return false;
190+
}
191+
}
192+
/**
193+
* Writes the settings to the given file if there are modified
194+
* values. The modification flags are reset (commit()) on successful write.
195+
* On write failure the modification flags are left unmodified.
196+
* @param file Path to file the JSON representation of the settings should
197+
* written to. If either the folder or the file does not exist they are
198+
* created.
199+
* @returns true on succes, false on write failure.
200+
*/
201+
public save(file: string) {
202+
203+
if (!this.modified) {
204+
return true;
205+
}
206+
207+
let settings: any = {};
208+
if (util.fileExistsSync(file)) {
209+
settings = util.tryParseJSON(fs.readFileSync(file, "utf8"));
210+
}
211+
if (!settings) {
212+
logger.notifyUserError(
213+
"arduinoFileError",
214+
new Error(constants.messages.ARDUINO_FILE_ERROR));
215+
return false;
216+
}
217+
218+
settings.sketch = this.sketch.value;
219+
settings.port = this.port.value;
220+
settings.board = this.board.value;
221+
settings.output = this.output.value;
222+
settings.debugger = this.debugger.value;
223+
settings.disableIntelliSenseAutoGen = this.disableIntelliSenseAutoGen.value;
224+
settings.configuration = this.configuration.value;
225+
settings.programmer = this.programmer.value;
226+
227+
util.mkdirRecursivelySync(path.dirname(file));
228+
fs.writeFileSync(file, JSON.stringify(settings, undefined, 4));
229+
230+
this.commit();
231+
232+
return true;
233+
}
234+
}

0 commit comments

Comments
 (0)