-
Notifications
You must be signed in to change notification settings - Fork 514
/
Copy pathduimanager.ts
391 lines (358 loc) · 13.7 KB
/
duimanager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
// Copyright (c) 2011-2012 Turbulenz Limited
/*jshint nomen: false*/
/*global TurbulenzBridge: false*/
/*exported TurbulenzUI*/
// requires jQuery
/**
* The DynamicUI manager sends events to the DynamicUI server to create instances of UI elements on the host website. It
* then manages updates to the UI either responding to requests for the value for a specific UI element, or pushing
* values to elements referenced by id.
*/
class DynamicUIManager
{
_objects : any; // TODO
_setters : any; // TODO
_getters : any; // TODO
_watchGroup : number;
/**
* Generates a new id for use in the dynamicUI system
*
* @return A new unique id to use
*/
_newId: { (): number; };
/**
* Helper function to add a new UI element. Sends an event to the dynamicUI server and sets up listeners to
* handle requests to get and set the value that come form the UI.
*
* @param {String} type The type of the UI element used
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
_addUI(type, title, getValue, setValue, groupId, options)
{
var id = this._newId();
TurbulenzBridge.emit('dynamicui.add-item', JSON.stringify({
id: id,
type: type,
title: title,
groupId: groupId || null,
options: options || {}
}));
this._setters[id] = setValue;
this._getters[id] = getValue;
return id;
}
/**
* Utility function to handle "watch stashed object" events.
*
* @param paramstring The JSONified request
*/
_watchStashedObject(paramstring) {
var params = JSON.parse(paramstring);
var id = params.id;
var property = params.property;
var title = params.title || id;
var ui = params.ui;
var options = params.options || {};
var groupId = params.groupId || this._watchGroup;
this.watchVariable(title, this._objects[id], property, ui, groupId, options);
}
/**
* Adds a slider to the specified group.
*
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
addSlider(title, getValue, setValue, groupId, options)
{
return this._addUI('slider', title, getValue, setValue, groupId, options);
}
/**
* Adds a checkbox to the specified group.
*
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
addCheckbox(title, getValue, setValue, groupId, options)
{
return this._addUI('checkbox', title, getValue, setValue, groupId, options);
}
/**
* Adds a drop-down selector to the specified group.
*
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
addSelect(title, getValue, setValue, groupId, options)
{
return this._addUI('select', title, getValue, setValue, groupId, options);
}
/**
* Adds an updatable label to the specified group.
*
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
addWatch(title, getValue, setValue, groupId, options)
{
return this._addUI('watch', title, getValue, setValue, groupId, options);
}
/**
* Adds a set of radio buttons to the specified group.
*
* @param {String} title The title to use for the UI element
* @param {Function} getValue A callback that gets the value for the UI element
* @param {Function} setValue A callback that is called when the value in the UI is changed
* @param [groupId] The group id of the parent group. If not defined then the default group is used
* @param [options] An object containing UI specific options. The details of this will depend on the implementation
* of the DynamicUI server
* @returns The id of the new element to use to push values to this UI element
*/
addRadioButton(title, getValue, setValue, groupId, options)
{
return this._addUI('radio', title, getValue, setValue, groupId, options);
}
/**
* Destroys the specified UI element.
*
* @param id The Id of the element to destroy. If the element is a group, the group and all its children are
* destroyed
*/
destroy(id)
{
TurbulenzBridge.emit('dynamicui.destroy', JSON.stringify({
id: id
}));
}
/**
* Updates the specified UI element with a new value.
*
* @param id The Id of the element to update
* @param value The value to send to the UI
*/
pushValue(id, value)
{
TurbulenzBridge.emit('dynamicui.pushvalue', JSON.stringify({
id: id,
value: value
}));
}
/**
* Adds a group to the dynamid UI.
*
* @param {String} title The title of the group
* @param groupId The parent group to add this new group to
* @returns The id of the newly created group.
*/
addGroup(title, groupId?)
{
var id = this._newId();
TurbulenzBridge.emit('dynamicui.group-create', JSON.stringify({
id: id,
title: title,
groupId: groupId || null
}));
return id;
}
/**
* Adds a UI element to an existing group. The element is moved, so if it is already a member of a group it
* will be removed from that group and added to the group specified in the function call.
*
* @param id The id of the element to move
* @param groupId The parent group to add this new group to
*/
addToGroup(id, groupId)
{
TurbulenzBridge.emit('dynamicui.group-add', JSON.stringify({
id: id,
groupId: groupId
}));
}
/**
* Removes a UI element from a group. This does not destroy the UI element so it can be used to temporarily hide
* a UI element which can then be re-shown by calling addToGroup
*
* @param id The id of the UI element to remove
* @param groupId The id of the group to remove it from
*/
removeFromGroup(id, groupId)
{
TurbulenzBridge.emit('dynamicui.group-remove', JSON.stringify({
id: id,
groupId: groupId
}));
}
/**
* Helper function to watch the specified property of an object. This automatically sets up the getter and setter
* callbacks on the property to tie it to the state of the UI.
*
* @param {String} title The title of the UI element to create
* @param {Object} object The object whose property will be watched
* @param {String} property The name of the property to watch
* @param {String} [ui = "watch"] The UI to use to show the variable
* @param [group] The group to add this watch element to
* @param [options] The UI creation options to use
* @returns The id of the newly created element
*/
watchVariable(title: string, object, property, ui?: string, group?: number,
options?): number
{
var uiType = ui || 'watch';
var groupId = group || null;
var id = -1;
var getVal = function getValFn()
{
if (property)
{
return object[property];
}
else
{
return object;
}
};
var setVal = function setValFn(value)
{
object[property] = value;
};
switch (uiType)
{
case 'slider' :
id = this.addSlider(title, getVal, setVal, groupId, options);
break;
case 'checkbox' :
id = this.addCheckbox(title, getVal, setVal, groupId, options);
break;
case 'radio' :
id = this.addRadioButton(title, getVal, setVal, groupId, options);
break;
case 'select' :
id = this.addSelect(title, getVal, setVal, groupId, options);
break;
case 'watch' :
id = this.addWatch(title, getVal, setVal, groupId, options);
break;
}
return id;
}
showObject(title, object, editable, group)
{
var objectGroup = this.addGroup(title, group);
var propertyName, property;
for (propertyName in object)
{
if (object.hasOwnProperty(propertyName))
{
property = object[propertyName];
if (typeof property === "object")
{
this.showObject(propertyName, property, editable, objectGroup);
}
else
{
if (editable)
{
// TODO: parse type and provide appropriate UI
this.watchVariable(propertyName, object, propertyName, 'watch', objectGroup);
}
else
{
this.watchVariable(propertyName, object, propertyName, 'watch', objectGroup);
}
}
}
}
return objectGroup;
}
/**
* Registers a named path to an object so that the object can be referenced from another context for the creation of
* watch UI
*
* @param {Object} object The object to stash
* @param {String} path The path to use to access the object in the form "folder/folder/folder/item", for example
* "actors/npcs/enemies/bots/ed209"
* @returns The id of the stashed object - currently for internal use only
*/
stashObject(object, path) {
var id = this._newId();
this._objects[id] = object;
TurbulenzBridge.emit('dynamicui.stash-add', id + ':' + path);
return id;
}
/**
* Creates a DynamicUI manager and initialises it, registering against events.
*
* @param title
* @returns {DynamicUIManager} The UI Manager
*/
static create(/* title */): DynamicUIManager
{
var uiMan = new DynamicUIManager();
uiMan._objects = {};
uiMan._setters = {};
uiMan._getters = {};
uiMan._watchGroup = uiMan.addGroup('watches');
// Watch for calls from the console to watch stashed objects
TurbulenzBridge.setListener('dynamicui.stash-watch', function (paramstring) {
uiMan._watchStashedObject(paramstring);
});
TurbulenzBridge.setListener('dynamicui.changevalue', function (jsonstring) {
var options = JSON.parse(jsonstring);
var setter = uiMan._setters[options.id];
if (setter)
{
setter(options.value);
}
});
TurbulenzBridge.setListener('dynamicui.requestvalue', function (jsonstring) {
var options = JSON.parse(jsonstring);
var getter = uiMan._getters[options.id];
if (getter)
{
TurbulenzBridge.emit('dynamicui.pushvalue', JSON.stringify({
id: options.id,
value: getter()
}));
}
});
return uiMan;
}
}
DynamicUIManager.prototype._newId = (function () {
var id = 0;
return function getId()
{
id += 1;
return id;
};
}());
/**
* The instance of the DynamicUI manager
*/
/* tslint:disable:no-unused-variable */
var TurbulenzUI = DynamicUIManager.create();