diff --git a/src/ig-template/features/settings/BooleanSetting.ts b/src/ig-template/features/settings/BooleanSetting.ts index ef89593..6069dd7 100644 --- a/src/ig-template/features/settings/BooleanSetting.ts +++ b/src/ig-template/features/settings/BooleanSetting.ts @@ -17,6 +17,6 @@ export class BooleanSetting extends Setting { } public toggle(): void { - this.value = !this.value; + this.set(!this.value); } } diff --git a/src/ig-template/features/settings/Setting.ts b/src/ig-template/features/settings/Setting.ts index 05281ac..9f1322c 100644 --- a/src/ig-template/features/settings/Setting.ts +++ b/src/ig-template/features/settings/Setting.ts @@ -3,6 +3,7 @@ import {Requirement} from "@/ig-template/tools/requirements/Requirement"; import {NoRequirement} from "@/ig-template/tools/requirements/NoRequirement"; import {SettingOption} from "@/ig-template/features/settings/SettingOption"; import {SettingsValue} from "@/ig-template/features/settings/SettingsValueType"; +import { ISimpleEvent, SimpleEventDispatcher } from "strongly-typed-events"; export abstract class Setting { @@ -14,6 +15,8 @@ export abstract class Setting { requirement: Requirement; + protected _onChange = new SimpleEventDispatcher<[SettingsValue, SettingsValue]>(); + protected constructor(id: SettingId, displayName: string, options: SettingOption[], defaultValue: SettingsValue, requirement: Requirement = new NoRequirement()) { this.id = id; this.displayName = displayName; @@ -25,12 +28,21 @@ export abstract class Setting { this.requirement = requirement; } + /** + * Emitted whenever the setting is changed. + */ + public get onChange(): ISimpleEvent<[SettingsValue, SettingsValue]> { + return this._onChange.asEvent(); + } + set(value: SettingsValue): void { if (!this.canAccess) { return; } if (this.validValue(value)) { + const prevValue = this.value; this.value = value; + this._onChange.dispatch([prevValue, value]); } else { console.warn(`${value} is not a valid value for setting ${this.id}. It could be that the option is not yet unlocked.`); } diff --git a/tests/unit/ig-template/features/settings/Settings.spec.ts b/tests/unit/ig-template/features/settings/Settings.spec.ts index b1d6324..ee3668d 100644 --- a/tests/unit/ig-template/features/settings/Settings.spec.ts +++ b/tests/unit/ig-template/features/settings/Settings.spec.ts @@ -18,7 +18,7 @@ describe('Settings', () => { new SettingOption("Option 2", 2), new SettingOption("Option 3", 3), ], 2) - ) + ); }); test('adding same setting multiple times', () => { @@ -62,6 +62,21 @@ describe('Settings', () => { }).not.toThrow() }); + test('test change event', () => { + expect.assertions(4); + + const setting = settings.getSetting(id); + setting?.onChange.subscribe(([prevValue, value]) => { + expect(prevValue).toBe(2); + expect(value).toBe(3); + }); + + settings.setSetting(id, 3); + + expect(setting).toBeDefined(); + expect(setting?.value).toBe(3); + }); + test('save empty', () => { // Arrange const expectedSaveData: SettingsSaveData = {