blob: 69e2d54a7aa5f2d6d6213fcc45a36e3b89659e3c [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 */
Akron308a6032019-12-05 16:27:34 +010015define(function () {
16
17 "use strict";
18
19 return {
20
21 /**
22 * Constructor
23 */
24 create : function (value) {
25 return Object.create(this)._init(value);
26 },
27
28 // Initialize
Akron237abc42020-10-07 14:14:52 +020029 _init : function (values) {
Akron308a6032019-12-05 16:27:34 +010030 this._assoc = [];
Akron237abc42020-10-07 14:14:52 +020031 if (values == undefined) {
32 this.values = [false,true];
33 }
34 else if (Array.isArray(values)) {
35 this.values = values;
36 }
37 else {
38 this.values = [values];
39 }
40 this.value = this.values[0];
Akron308a6032019-12-05 16:27:34 +010041 return this;
42 },
43
Akron308a6032019-12-05 16:27:34 +010044 /**
45 * Associate the state with some objects.
46 */
47 associate : function (obj) {
48
49 // Check if the object has a setState() method
50 if (obj.hasOwnProperty("setState")) {
51 this._assoc.push(obj);
52 obj.setState(this.value);
53 } else {
54 console.log("Object " + obj + " has no setState() method");
55 }
56 },
57
58 /**
59 * Set the state to a certain value.
60 * This will set the state to all associated objects as well.
61 */
62 set : function (value) {
63 if (value != this.value) {
64 this.value = value;
Akron678c26f2020-10-09 08:52:50 +020065 this._assoc.forEach(i => i.setState(value));
Akron308a6032019-12-05 16:27:34 +010066 };
67 },
68
69 /**
70 * Get the state value
71 */
72 get : function () {
73 return this.value;
Akronb69cbf12020-10-01 13:04:44 +020074 },
75
76
77 /**
78 * Get the number of associated objects
79 */
80 associates : function () {
81 return this._assoc.length;
Akron38ed5dc2020-10-01 17:33:00 +020082 },
83
84 /**
85 * Clear all associated objects
86 */
87 clear : function () {
88 return this._assoc = [];
Akron237abc42020-10-07 14:14:52 +020089 },
90
91 /**
92 * Roll to the next value.
93 * This may be used for toggling.
94 */
95 roll : function () {
96 let next = 0;
97 for (let i = 0; i < this.values.length - 1; i++) {
98 if (this.value == this.values[i]) {
99 next = i+1;
100 break;
101 };
102 };
103 this.set(this.values[next]);
Akron308a6032019-12-05 16:27:34 +0100104 }
105 }
106});