blob: f68408ff4e795f15fd4d30d0289c9e9dc68ca35a [file] [log] [blame]
Akron308a6032019-12-05 16:27:34 +01001/**
2 * Create a state object, that can have a single value
3 * (mostly boolean) and multiple objects associated to it.
4 * Whenever the state changes, all objects are informed
5 * by their setState() method of the value change.
6 *
7 * @author Nils Diewald
8 */
Akronb69cbf12020-10-01 13:04:44 +02009/*
10 * TODO:
Akron237abc42020-10-07 14:14:52 +020011 * Require names for states, that should be quite short, so they
12 * can easily be serialized and kept between page turns (via cookie
13 * and/or query param)
Akronb69cbf12020-10-01 13:04:44 +020014 */
Akrondf90c592020-10-20 08:42:50 +020015"use strict";
16
Akron308a6032019-12-05 16:27:34 +010017define(function () {
Akron308a6032019-12-05 16:27:34 +010018 return {
19
20 /**
21 * Constructor
22 */
Akron72c1c9d2021-11-05 10:46:34 +010023 create : function (values) {
24 return Object.create(this)._init(values);
Akron308a6032019-12-05 16:27:34 +010025 },
26
Akrondf90c592020-10-20 08:42:50 +020027
Akron308a6032019-12-05 16:27:34 +010028 // Initialize
Akron237abc42020-10-07 14:14:52 +020029 _init : function (values) {
Akrondf90c592020-10-20 08:42:50 +020030 const t = this;
31 t._assoc = [];
Akron237abc42020-10-07 14:14:52 +020032 if (values == undefined) {
Akrondf90c592020-10-20 08:42:50 +020033 t.values = [false,true];
Akron237abc42020-10-07 14:14:52 +020034 }
35 else if (Array.isArray(values)) {
Akrondf90c592020-10-20 08:42:50 +020036 t.values = values;
Akron237abc42020-10-07 14:14:52 +020037 }
38 else {
Akrondf90c592020-10-20 08:42:50 +020039 t.values = [values];
Akron237abc42020-10-07 14:14:52 +020040 }
Akrondf90c592020-10-20 08:42:50 +020041 return t;
Akron308a6032019-12-05 16:27:34 +010042 },
43
Akrondf90c592020-10-20 08:42:50 +020044
Akron308a6032019-12-05 16:27:34 +010045 /**
46 * Associate the state with some objects.
47 */
48 associate : function (obj) {
49
50 // Check if the object has a setState() method
51 if (obj.hasOwnProperty("setState")) {
52 this._assoc.push(obj);
53 obj.setState(this.value);
54 } else {
55 console.log("Object " + obj + " has no setState() method");
56 }
57 },
58
Akrondf90c592020-10-20 08:42:50 +020059
Akron308a6032019-12-05 16:27:34 +010060 /**
61 * Set the state to a certain value.
62 * This will set the state to all associated objects as well.
63 */
64 set : function (value) {
65 if (value != this.value) {
66 this.value = value;
Akron678c26f2020-10-09 08:52:50 +020067 this._assoc.forEach(i => i.setState(value));
Akron308a6032019-12-05 16:27:34 +010068 };
69 },
70
Akrondf90c592020-10-20 08:42:50 +020071
Akron308a6032019-12-05 16:27:34 +010072 /**
Akron72c1c9d2021-11-05 10:46:34 +010073 * Set the state to a default value.
74 * This will only be set, if no other value is set yet.
75 */
76 setIfNotYet : function (value) {
77 if (this.value == undefined) {
78 this.set(value);
79 };
80 },
81
82
83 /**
Akron308a6032019-12-05 16:27:34 +010084 * Get the state value
85 */
86 get : function () {
Akron72c1c9d2021-11-05 10:46:34 +010087 if (this.value == undefined) {
88 this.value = this.values[0];
89 };
90
Akron308a6032019-12-05 16:27:34 +010091 return this.value;
Akronb69cbf12020-10-01 13:04:44 +020092 },
93
94
95 /**
96 * Get the number of associated objects
97 */
98 associates : function () {
99 return this._assoc.length;
Akron38ed5dc2020-10-01 17:33:00 +0200100 },
101
Akrondf90c592020-10-20 08:42:50 +0200102
Akron38ed5dc2020-10-01 17:33:00 +0200103 /**
104 * Clear all associated objects
105 */
106 clear : function () {
107 return this._assoc = [];
Akron237abc42020-10-07 14:14:52 +0200108 },
109
Akrondf90c592020-10-20 08:42:50 +0200110
Akron237abc42020-10-07 14:14:52 +0200111 /**
112 * Roll to the next value.
113 * This may be used for toggling.
114 */
115 roll : function () {
116 let next = 0;
117 for (let i = 0; i < this.values.length - 1; i++) {
Akron72c1c9d2021-11-05 10:46:34 +0100118 if (this.get() == this.values[i]) {
Akron237abc42020-10-07 14:14:52 +0200119 next = i+1;
120 break;
121 };
122 };
123 this.set(this.values[next]);
Akron308a6032019-12-05 16:27:34 +0100124 }
125 }
126});