1 import { debounceInIntervals
} from '../util.js';
3 export const controllerEvents
= {
5 SIM_RESET
: 'SIMULATION_RESET',
6 VALUE_SET
: 'VALUE_SET',
7 SLIDING_VALUE
: 'SLIDING_VALUE',
11 /** Class that enables data binding. Allows for callback functions to subscribe to the Controller which will
12 * then be called whenever the value in the controller is updated. */
13 export class Controller
{
14 constructor(value
=null) {
17 this.debouncedSetValue
= debounceInIntervals((setArgs
) => {
18 this.setValueCallback(setArgs
);
22 subscribe(callback
, eventName
=controllerEvents
.VALUE_SET
) {
23 // this.listeners.push(callback);
24 if (!(eventName
in this.listeners
)) {
25 this.listeners
[eventName
] = [];
27 this.listeners
[eventName
].push(callback
);
30 setValue(value
, eventName
=controllerEvents
.VALUE_SET
) {
31 this.setValueCallback([value
, eventName
]);
34 setValueCallback([value
, eventName
=controllerEvents
.VALUE_SET
]) {
36 if (eventName
!= controllerEvents
.QUIET
) {
37 this.notifyListeners(this.listeners
[eventName
]);
38 if (eventName
!= controllerEvents
.ALL
) {
39 this.notifyListeners(this.listeners
[controllerEvents
.ALL
]);
48 notifyListeners(listeners
, args
=null) {
49 if (listeners
== null) {
52 listeners
.map(listener
=> listener(args
));
55 broadcastEvent(event
, args
=null) {
56 this.notifyListeners(this.listeners
[event
], args
);
60 /** Class to synchronise a function call at the end of two asynchronous events.
61 * Useful for executing a function after both a layer and its colorbar have loaded. */
62 export class SyncController
extends Controller
{
64 super([false, false]);
69 if (this.value
[0] && this.value
[1]) {
70 this.setValue([false, false]);
76 export const controllers
= {
77 currentTimestamp
: (function createCurrentTimestamp() {
78 var currentTimestamp
= new Controller();
79 currentTimestamp
.setValue
= (value
, eventName
=controllerEvents
.VALUE_SET
) => {
80 currentTimestamp
.debouncedSetValue([value
, eventName
]);
82 return currentTimestamp
;
84 domainInstance
: new Controller(),
85 currentDomain
: new Controller(),
86 loadingProgress
: (function createLoadProg() {
87 const loadingProgress
= new Controller(0);
88 loadingProgress
.nFrames
= 0;
89 loadingProgress
.loadedFrames
= 0;
91 loadingProgress
.setFrames
= (nFrames
) => {
92 loadingProgress
.nFrames
= nFrames
;
93 loadingProgress
.loadedFrames
= 0;
94 loadingProgress
.setValue(0);
97 loadingProgress
.frameLoaded
= (frames
= 1) => {
98 loadingProgress
.loadedFrames
+= frames
;
99 var progress
= loadingProgress
.loadedFrames
/ loadingProgress
.nFrames
;
100 loadingProgress
.setValue(progress
);
103 return loadingProgress
;
105 timeSeriesMarkers
: (function createTimeSeriesMarkers() {
106 var timeSeriesMarkers
= new Controller([]);
107 timeSeriesMarkers
.removeEvent
= 'REMOVE_EVENT';
108 timeSeriesMarkers
.add
= (newMarker
) => {
109 timeSeriesMarkers
.value
.push(newMarker
);
111 timeSeriesMarkers
.remove
= (removeMarker
) => {
112 var index
= timeSeriesMarkers
.value
.indexOf(removeMarker
);
113 timeSeriesMarkers
.value
.splice(index
, 1);
114 timeSeriesMarkers
.broadcastEvent(timeSeriesMarkers
.removeEvent
, index
);
116 return timeSeriesMarkers
;
118 opacity
: new Controller(0.5),
119 syncImageLoad
: new SyncController(),
120 startDate
: (function createStartDate() {
121 var startDateController
= new Controller();
123 const subscriptionFunction
= () => {
124 var newStartDate
= startDateController
.getValue();
125 var currentTimestamp
= controllers
.currentTimestamp
.getValue();
127 if (newStartDate
> currentTimestamp
) {
128 controllers
.currentTimestamp
.setValue(newStartDate
);
131 startDateController
.subscribe(subscriptionFunction
, controllerEvents
.ALL
);
132 startDateController
.setValue
= (value
, eventName
=controllerEvents
.VALUE_SET
) => {
133 startDateController
.debouncedSetValue([value
, eventName
]);
136 return startDateController
;
138 endDate
: (function createEndDate() {
139 var endDateController
= new Controller();
141 const subscriptionFunction
= ()=> {
142 var newEndDate
= endDateController
.getValue();
143 var currentTimestamp
= controllers
.currentTimestamp
.getValue();
145 if (newEndDate
< currentTimestamp
) {
146 controllers
.currentTimestamp
.setValue(newEndDate
);
149 endDateController
.subscribe(subscriptionFunction
, controllerEvents
.ALL
);
150 endDateController
.setValue
= (value
, eventName
=controllerEvents
.VALUE_SET
) => {
151 endDateController
.debouncedSetValue([value
, eventName
]);
154 return endDateController
;