diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f00ef23 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +## 1.1 + +Adapting ControlModel to be able to use the full Persistent-Type range and use +observers instead of baked in functions. + +## 1.0 + +initial version diff --git a/Jenkinsfile b/Jenkinsfile index 81d532c..12d359d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { VERSION = VersionNumber([ versionNumberString: '${BUILDS_ALL_TIME}', - versionPrefix: '1.0.', + versionPrefix: '1.1.', worstResultForIncrement: 'SUCCESS' ]) } diff --git a/README.md b/README.md index 407c5f9..51c4da4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @sapphirecode/modelling -version: 1.0.x +version: 1.1.x base classes for controlling data @@ -83,10 +83,13 @@ also extends Persistent. The method define_properties lets you define the data you will store. -verify is meant to check and modify data. +before_change allows you to register observers, that are able to cancel changes. +the registered observers are called with the following parameters: (new_value, +old_value, property_name). By returning false they can cancel the change that +was about to happen. -update should be called when data was modified, by default it just calls verify, -but can also be used to report updates to other components +register_observer does the same thing, but those observers are not able to +cancel the change and they are called after the change already happened. ### Interfaces diff --git a/lib/ControlModel.ts b/lib/ControlModel.ts index 9ced8b9..fedbdae 100644 --- a/lib/ControlModel.ts +++ b/lib/ControlModel.ts @@ -6,43 +6,46 @@ */ import { Persistent } from './Persistent'; +import { PersistentType, ControlObserver, Observer } from './Types'; export abstract class ControlModel extends Persistent { - public constructor (obj?: Record) { + private _before_change: Record = {}; + private _observers: Record = {}; + + public constructor (obj?: Record) { super (); this.define_properties (); - for (const prop of Object.keys (this.properties)) { - if ([ - 'string', - 'number', - 'boolean' - ].indexOf (this.properties[prop]) < 0) { - throw new Error ( - 'property types have to be either string, number or boolean' - ); - } - } - if (typeof obj !== 'undefined') this.assign_object (obj); } - public to_object (): Record { - return super.to_object () as Record; - } + public set (key: string, value: PersistentType): void { + const prev = this.get (key); + if (typeof this._before_change[key] !== 'undefined') { + for (const obs of this._before_change[key]) { + if (!obs (value, prev, key)) + return; + } + } - public get (key: string): string|number|boolean { - return super.get (key) as string|number|boolean; - } - - public set (key: string, value: string|number|boolean): void { super.set (key, value); + if (typeof this._observers[key] !== 'undefined') { + for (const obs of this._observers[key]) + obs (value, prev, key); + } } - public update (): void { - this.verify (); + public before_change (key: string, func: ControlObserver): void { + if (typeof this._before_change[key] === 'undefined') + this._before_change[key] = []; + this._before_change[key].push (func); + } + + public register_observer (key: string, func: Observer): void { + if (typeof this._observers[key] === 'undefined') + this._observers[key] = []; + this._observers[key].push (func); } - public abstract verify(): void; protected abstract define_properties(): void; } diff --git a/lib/Persistent.ts b/lib/Persistent.ts index 89d2531..0dba60c 100644 --- a/lib/Persistent.ts +++ b/lib/Persistent.ts @@ -7,10 +7,7 @@ import { copy_object } from '@sapphirecode/utilities'; import { Assignable, Serializable } from './interfaces'; - -type PersistentTypeString = 'string'|'number'|'boolean'|'array'; -type PersistentPrimitive = string|number|boolean; -type PersistentType = PersistentPrimitive|PersistentPrimitive[]; +import { PersistentTypeString, PersistentType } from './Types'; export abstract class Persistent implements Assignable, Serializable { private _data: Record = {}; diff --git a/lib/Types.ts b/lib/Types.ts new file mode 100644 index 0000000..c726d94 --- /dev/null +++ b/lib/Types.ts @@ -0,0 +1,15 @@ +export type PersistentTypeString = 'string'|'number'|'boolean'|'array'; +export type PersistentPrimitive = string|number|boolean; +export type PersistentType = PersistentPrimitive|PersistentPrimitive[]; + +export type Observer = ( + value: PersistentType, + prev: PersistentType, + key: string +) => void; + +export type ControlObserver = ( + value: PersistentType, + prev: PersistentType, + key: string +) => boolean;