Fix settingsset.findSetting and arraysetting.items not being populated

- Changed plugin/theme event emitters to AsyncEventEmitter
This commit is contained in:
Samuel Elliott 2018-03-04 21:49:35 +00:00
parent d32959b8b9
commit 47637eca75
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
6 changed files with 36 additions and 107 deletions

View File

@ -8,27 +8,9 @@
* LICENSE file in the root directory of this source tree.
*/
import { AsyncEventEmitter } from 'common';
import { EventEmitter } from 'events';
class ExtModuleEvents {
constructor(extmodule) {
this.extmodule = extmodule;
this.emitter = new EventEmitter();
}
on(eventname, callback) {
this.emitter.on(eventname, callback);
}
off(eventname, callback) {
this.emitter.removeListener(eventname, callback);
}
emit(...args) {
this.emitter.emit(...args);
}
}
export default class ExtModule {
constructor(pluginInternals) {
@ -57,6 +39,6 @@ export default class ExtModule {
get enabled() { return true }
get config() { return this.userConfig.config || [] }
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new ExtModuleEvents(this)) }
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
}

View File

@ -8,36 +8,17 @@
* LICENSE file in the root directory of this source tree.
*/
import { Utils, FileUtils } from 'common';
import { Utils, FileUtils, AsyncEventEmitter } from 'common';
import { Modals } from 'ui';
import { EventEmitter } from 'events';
import PluginManager from './pluginmanager';
import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs';
class PluginEvents {
constructor(plugin) {
this.plugin = plugin;
this.emitter = new EventEmitter();
}
on(eventname, callback) {
this.emitter.on(eventname, callback);
}
off(eventname, callback) {
this.emitter.removeListener(eventname, callback);
}
emit(...args) {
this.emitter.emit(...args);
}
}
export default class Plugin {
constructor(pluginInternals) {
this.__pluginInternals = pluginInternals;
this.saveSettings = this.saveSettings.bind(this);
this.saveConfiguration = this.saveConfiguration.bind(this);
this.hasSettings = this.config && this.config.length > 0;
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
@ -70,29 +51,12 @@ export default class Plugin {
get pluginConfig() { return this.config }
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
get exports() { return this._exports ? this._exports : (this._exports = this.getExports()) }
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new PluginEvents(this)) }
getSetting(setting_id, category_id) {
for (let category of this.config) {
if (category_id && category.category !== category_id) continue;
for (let setting of category.settings) {
if (setting.id !== setting_id) continue;
return setting.value;
}
}
}
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
showSettingsModal() {
return Modals.contentSettings(this);
}
async saveSettings(newSettings) {
const updatedSettings = this.settings.merge(newSettings);
await this.saveConfiguration();
return updatedSettings;
}
async saveConfiguration() {
try {
await FileUtils.writeFile(`${this.pluginPath}/user.config.json`, JSON.stringify({

View File

@ -13,34 +13,15 @@ import ThemeManager from './thememanager';
import { EventEmitter } from 'events';
import { SettingUpdatedEvent, SettingsUpdatedEvent } from 'structs';
import { DOM, Modals } from 'ui';
import { Utils, FileUtils, ClientIPC, ClientLogger as Logger } from 'common';
import { Utils, FileUtils, ClientIPC, ClientLogger as Logger, AsyncEventEmitter } from 'common';
import filewatcher from 'filewatcher';
class ThemeEvents {
constructor(theme) {
this.theme = theme;
this.emitter = new EventEmitter();
}
on(eventname, callback) {
this.emitter.on(eventname, callback);
}
off(eventname, callback) {
this.emitter.removeListener(eventname, callback);
}
emit(...args) {
this.emitter.emit(...args);
}
}
export default class Theme {
constructor(themeInternals) {
this.__themeInternals = themeInternals;
this.hasSettings = this.config && this.config.length > 0;
this.saveSettings = this.saveSettings.bind(this);
this.saveConfiguration = this.saveConfiguration.bind(this);
this.enable = this.enable.bind(this);
this.disable = this.disable.bind(this);
@ -79,22 +60,12 @@ export default class Theme {
get themeConfig() { return this.config }
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
get css() { return this.data.css }
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new ThemeEvents(this)) }
get events() { return this.EventEmitter ? this.EventEmitter : (this.EventEmitter = new AsyncEventEmitter()) }
showSettingsModal() {
return Modals.contentSettings(this);
}
async saveSettings(newSettings) {
const updatedSettings = this.settings.merge(newSettings);
// As the theme's configuration has changed it needs recompiling
// When the compiled CSS has been saved it will also save the configuration
await this.recompile();
return this.settingsUpdated(updatedSettings);
}
async saveConfiguration() {
try {
await FileUtils.writeFile(`${this.themePath}/user.config.json`, JSON.stringify({

View File

@ -101,17 +101,6 @@ export default class SettingsSet {
return false;
}
/**
* Return the first setting that matches the id in any category
*/
findFirst(settingId) {
for (let cat of this.categories) {
const found = cat.settings.find(s => s.id === settingId);
if (found) return found;
}
return null;
}
/**
* Returns the first category where calling {function} returns true.
* @param {Function} function A function to call to filter categories
@ -146,7 +135,7 @@ export default class SettingsSet {
*/
findSetting(f) {
for (let category of this.categories) {
const setting = category.findSetting(f);
const setting = category.find(f);
if (setting) return setting;
}
}

View File

@ -24,7 +24,12 @@ export default class ArraySetting extends Setting {
this.args.schemes = this.schemes.map(scheme => new SettingsScheme(scheme));
this.args.items = this.value ? this.value.map(item => this.createItem(item.args || item)) : [];
this.updateValue(false, false);
this.args.value = this.items.map(item => {
if (!item) return;
item.setSaved();
return item.strip();
});
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
}
/**
@ -142,6 +147,24 @@ export default class ArraySetting extends Setting {
return set;
}
/**
* Merges a setting into this setting without emitting events (and therefore synchronously).
* This only exists for use by the constructor and SettingsCategory.
*/
_merge(newSetting) {
const value = newSetting.args ? newSetting.args.value : newSetting.value;
const old_value = this.args.value;
if (Utils.compare(value, old_value)) return [];
this.args.value = value;
this.args.items = this.value ? this.value.map(item => this.createItem(item.args || item)) : [];
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
return [{
setting: this, setting_id: this.id,
value, old_value
}];
}
/**
* Sets the value of this setting.
* This is only intended for use by settings.

View File

@ -156,7 +156,7 @@ export default class Setting {
* @param {Boolean} emit Whether to emit a SettingUpdatedEvent
* @return {Promise}
*/
setValue(value, emit_multi = true, emit = true) {
async setValue(value, emit_multi = true, emit = true) {
const old_value = this.args.value;
if (Utils.compare(value, old_value)) return [];
this.args.value = value;
@ -168,10 +168,10 @@ export default class Setting {
};
if (emit)
this.emit('setting-updated', new SettingUpdatedEvent(updatedSetting));
await this.emit('setting-updated', new SettingUpdatedEvent(updatedSetting));
if (emit_multi)
this.emit('settings-updated', new SettingsUpdatedEvent({
await this.emit('settings-updated', new SettingsUpdatedEvent({
updatedSettings: [updatedSetting]
}));