@woosh/meep-engine 2.46.29 → 2.46.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/editor/Editor.js +793 -0
  2. package/editor/SelectionVisualizer.js +148 -0
  3. package/editor/actions/concrete/ActionUpdateTexture.js +21 -0
  4. package/editor/actions/concrete/ArrayCopyAction.js +39 -0
  5. package/editor/actions/concrete/ComponentAddAction.js +47 -0
  6. package/editor/actions/concrete/ComponentRemoveAction.js +38 -0
  7. package/editor/actions/concrete/EntityCreateAction.js +47 -0
  8. package/editor/actions/concrete/EntityRemoveAction.js +51 -0
  9. package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
  10. package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
  11. package/editor/actions/concrete/ModifyPatchTextureArray2DAction.js +182 -0
  12. package/editor/actions/concrete/PaintTerrainOverlayAction.js +45 -0
  13. package/editor/actions/concrete/PatchTerrainHeightAction.js +67 -0
  14. package/editor/actions/concrete/PatchTerrainTextureAction.js +152 -0
  15. package/editor/actions/concrete/SelectionAddAction.js +36 -0
  16. package/editor/actions/concrete/SelectionClearAction.js +22 -0
  17. package/editor/actions/concrete/SelectionRemoveAction.js +30 -0
  18. package/editor/actions/concrete/TransformModifyAction.js +46 -0
  19. package/editor/actions/concrete/WriteGridValueAction.js +46 -0
  20. package/editor/ecs/EditorEntity.js +12 -0
  21. package/editor/ecs/EditorEntitySystem.js +14 -0
  22. package/editor/ecs/component/FieldDescriptor.js +34 -0
  23. package/editor/ecs/component/FieldValueAdapter.js +20 -0
  24. package/editor/ecs/component/TypeEditor.js +33 -0
  25. package/editor/ecs/component/TypeSchema.d.ts +38 -0
  26. package/editor/ecs/component/createFieldEditor.js +92 -0
  27. package/editor/ecs/component/createObjectEditor.js +361 -0
  28. package/editor/ecs/component/editors/ColorEditor.js +39 -0
  29. package/editor/ecs/component/editors/HTMLElementEditor.js +17 -0
  30. package/editor/ecs/component/editors/ImagePathEditor.js +82 -0
  31. package/editor/ecs/component/editors/LargeStrongEditor.js +107 -0
  32. package/editor/ecs/component/editors/NumericIntervalEditor.js +86 -0
  33. package/editor/ecs/component/editors/ObservedBooleanEditor.js +13 -0
  34. package/editor/ecs/component/editors/ObservedEnumEditor.js +32 -0
  35. package/editor/ecs/component/editors/ObservedIntegerEditor.js +43 -0
  36. package/editor/ecs/component/editors/ObservedStringEditor.js +51 -0
  37. package/editor/ecs/component/editors/Sampler2DEditor.js +221 -0
  38. package/editor/ecs/component/editors/collection/ListEditor.js +83 -0
  39. package/editor/ecs/component/editors/common/BitFlagsEditor.js +80 -0
  40. package/editor/ecs/component/editors/common/EnumEditor.js +41 -0
  41. package/editor/ecs/component/editors/common/makeV3_editor.js +85 -0
  42. package/editor/ecs/component/editors/common/noEditor.js +9 -0
  43. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +17 -0
  44. package/editor/ecs/component/editors/ecs/MinimapMarkerEditor.js +16 -0
  45. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +225 -0
  46. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -0
  47. package/editor/ecs/component/editors/ecs/ParameterTrackSetEditor.js +18 -0
  48. package/editor/ecs/component/editors/ecs/ParticleEmitterEditor.js +58 -0
  49. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +58 -0
  50. package/editor/ecs/component/editors/ecs/SimulationStepDefinitionEditor.js +21 -0
  51. package/editor/ecs/component/editors/ecs/Trail2DEditor.js +33 -0
  52. package/editor/ecs/component/editors/ecs/TransformEditor.js +23 -0
  53. package/editor/ecs/component/editors/ecs/terrain/SplatMappingEditor.js +21 -0
  54. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +95 -0
  55. package/editor/ecs/component/editors/ecs/terrain/TerrainLayerEditor.js +18 -0
  56. package/editor/ecs/component/editors/ecs/terrain/TerrainLayersEditor.js +22 -0
  57. package/editor/ecs/component/editors/ecs/terrain/TerrainOverlayEditor.js +20 -0
  58. package/editor/ecs/component/editors/geom/QuaternionEditor.js +63 -0
  59. package/editor/ecs/component/editors/geom/Vector1Editor.js +57 -0
  60. package/editor/ecs/component/editors/geom/Vector2Editor.js +11 -0
  61. package/editor/ecs/component/editors/geom/Vector3Editor.js +13 -0
  62. package/editor/ecs/component/editors/geom/Vector4Editor.js +12 -0
  63. package/editor/ecs/component/editors/primitive/ArrayEditor.js +46 -0
  64. package/editor/ecs/component/editors/primitive/BooleanEditor.js +27 -0
  65. package/editor/ecs/component/editors/primitive/FunctionEditor.js +29 -0
  66. package/editor/ecs/component/editors/primitive/NumberEditor.js +60 -0
  67. package/editor/ecs/component/editors/primitive/ObjectEditor.js +12 -0
  68. package/editor/ecs/component/editors/primitive/StringEditor.js +31 -0
  69. package/editor/ecs/component/editors/three/BufferGeometryEditor.js +28 -0
  70. package/editor/ecs/component/editors/three/MaterialEditor.js +27 -0
  71. package/editor/ecs/component/editors/three/MeshEditor.js +35 -0
  72. package/editor/ecs/component/editors/three/TextureEditor.js +112 -0
  73. package/editor/ecs/component/findNearestRegisteredType.js +59 -0
  74. package/editor/ecs/component/prototypeObjectEditor.js +379 -0
  75. package/editor/enableEditor.js +85 -0
  76. package/editor/library/MeshLibrary.js +33 -0
  77. package/editor/process/DisableGameUIProcess.js +43 -0
  78. package/editor/process/EditorProcess.js +35 -0
  79. package/editor/process/ObstacleGridDisplayProcess.js +120 -0
  80. package/editor/process/ProcessEngine.js +123 -0
  81. package/editor/process/SymbolicDisplayProcess.js +132 -0
  82. package/editor/process/symbolic/ComponentSymbolicDisplay.js +34 -0
  83. package/editor/process/symbolic/SymbolicDisplayInternalAPI.js +159 -0
  84. package/editor/process/symbolic/buildThreeJSHelperEntity.js +36 -0
  85. package/editor/process/symbolic/make3DSymbolicDisplay.js +91 -0
  86. package/editor/process/symbolic/makeCameraSymbolicDisplay.js +32 -0
  87. package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +176 -0
  88. package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
  89. package/editor/process/symbolic/makeHelperSphereGeometry.js +73 -0
  90. package/editor/process/symbolic/makeLightSymbolicDisplay.js +77 -0
  91. package/editor/process/symbolic/makeParticleEmitterSymbolicDisplay.js +146 -0
  92. package/editor/process/symbolic/makePathSymbolicDisplay.js +105 -0
  93. package/editor/process/symbolic/makePositionedIconDisplaySymbol.js +74 -0
  94. package/editor/process/symbolic/makeSocketsSymbolicDisplay.js +153 -0
  95. package/editor/process/symbolic/makeSolidArrowGeometry.js +391 -0
  96. package/editor/process/symbolic/makeSoundEmitterSymbolicDisplay.js +89 -0
  97. package/editor/process/symbolic/makeStoryTriggerSetAreaDisplay.js +114 -0
  98. package/editor/process/symbolic/synchronizeTransform.js +50 -0
  99. package/editor/tools/FoliagePaintTool.js +168 -0
  100. package/editor/tools/GridPaintTool.js +247 -0
  101. package/editor/tools/SelectionTool.js +407 -0
  102. package/editor/tools/TopDownCameraControlTool.js +59 -0
  103. package/editor/tools/TransformTool.js +370 -0
  104. package/editor/tools/engine/Tool.js +121 -0
  105. package/editor/tools/engine/ToolEngine.js +193 -0
  106. package/editor/tools/engine/ToolState.js +9 -0
  107. package/editor/tools/engine/ToolStateMachine.js +53 -0
  108. package/editor/tools/paint/TerrainHeightPaintTool.js +297 -0
  109. package/editor/tools/paint/TerrainPaintTool.js +211 -0
  110. package/editor/tools/paint/TerrainTexturePaintTool.js +193 -0
  111. package/editor/tools/paint/prototypeTerrainEditor.js +135 -0
  112. package/editor/tools/v2/BlenderCameraOrientationGizmo.d.ts +50 -0
  113. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +500 -0
  114. package/editor/tools/v2/TransformControls.d.ts +20 -0
  115. package/editor/tools/v2/TransformControls.js +1782 -0
  116. package/editor/tools/v2/prototypeTransformControls.js +92 -0
  117. package/editor/view/EditorView.js +462 -0
  118. package/editor/view/GridPickCoordinateView.js +88 -0
  119. package/editor/view/ecs/ComponentControlFactory.js +48 -0
  120. package/editor/view/ecs/ComponentControlView.js +214 -0
  121. package/editor/view/ecs/EntityEditor.js +258 -0
  122. package/editor/view/ecs/EntityList.js +258 -0
  123. package/editor/view/ecs/components/BlackboardController.js +50 -0
  124. package/editor/view/ecs/components/DatGuiController.js +216 -0
  125. package/editor/view/ecs/components/FogOfWarController.js +78 -0
  126. package/editor/view/ecs/components/FogOfWarRevealerController.js +44 -0
  127. package/editor/view/ecs/components/GeneratedArmyController.js +42 -0
  128. package/editor/view/ecs/components/GridObstacleController.js +72 -0
  129. package/editor/view/ecs/components/GridPositionController.js +40 -0
  130. package/editor/view/ecs/components/HeadsUpDisplayController.js +30 -0
  131. package/editor/view/ecs/components/HighlightController.js +47 -0
  132. package/editor/view/ecs/components/MeshController.js +125 -0
  133. package/editor/view/ecs/components/PathFollowerController.js +87 -0
  134. package/editor/view/ecs/components/TagController.js +80 -0
  135. package/editor/view/ecs/components/TerrainController.js +225 -0
  136. package/editor/view/ecs/components/TransformController.js +103 -0
  137. package/editor/view/ecs/components/UnitShopController.js +112 -0
  138. package/editor/view/ecs/components/army/ArmyController.js +130 -0
  139. package/editor/view/ecs/components/color/GaugeView.js +107 -0
  140. package/editor/view/ecs/components/common/AutoCanvasView.js +53 -0
  141. package/editor/view/ecs/components/common/LineView.js +17 -0
  142. package/editor/view/ecs/components/common/NumberController.js +112 -0
  143. package/editor/view/ecs/components/common/NumericIntervalController.js +64 -0
  144. package/editor/view/ecs/components/gui/GUIElementController.js +117 -0
  145. package/editor/view/ecs/components/items/ItemContainerController.js +132 -0
  146. package/editor/view/ecs/components/items/ItemContainerController.stories.js +50 -0
  147. package/editor/view/ecs/components/items/ItemController.js +52 -0
  148. package/editor/view/ecs/components/particles/ColorParameterLUTController.js +444 -0
  149. package/editor/view/ecs/components/particles/ParameterTrackController.js +51 -0
  150. package/editor/view/ecs/components/particles/ParticleEmitterController.js +213 -0
  151. package/editor/view/ecs/components/particles/ParticleLayerController.js +213 -0
  152. package/editor/view/ecs/components/particles/ScalarParameterLUTController.js +401 -0
  153. package/editor/view/ecs/components/sockets/AttachmentSocketsController.js +51 -0
  154. package/editor/view/ecs/components/sound/SoundEmitterController.js +137 -0
  155. package/editor/view/ecs/components/story/StoryTriggerSetController.js +214 -0
  156. package/editor/view/ecs/components/unit/AuraController.js +45 -0
  157. package/editor/view/library/MeshLibraryView.js +164 -0
  158. package/editor/view/node-graph/NodeGraphEditorView.js +170 -0
  159. package/editor/view/node-graph/NodeGraphView.js +453 -0
  160. package/editor/view/node-graph/NodeView.js +135 -0
  161. package/editor/view/node-graph/PortView.js +69 -0
  162. package/editor/view/process/ProcessView.js +63 -0
  163. package/editor/view/tools/ToolSettingsView.js +143 -0
  164. package/editor/view/tools/ToolView.js +58 -0
  165. package/package.json +2 -1
  166. package/src/engine/intelligence/behavior/composite/CompositeBehavior.js +18 -2
  167. package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +21 -9
  168. package/src/engine/intelligence/behavior/composite/SequenceBehavior.js +5 -1
  169. package/src/engine/intelligence/behavior/util/DelayBehavior.js +8 -3
@@ -0,0 +1,20 @@
1
+ import { assert } from "../../../src/core/assert.js";
2
+
3
+ export class FieldValueAdapter {
4
+ constructor() {
5
+ this.writable = true;
6
+ this.readable = true;
7
+
8
+ }
9
+
10
+ read(object, field_name) {
11
+ assert.isString(field_name, 'field_name');
12
+
13
+
14
+ return object[field_name];
15
+ }
16
+
17
+ write(object, field_name, value) {
18
+ object[field_name] = value;
19
+ }
20
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @class
3
+ * @template T
4
+ */
5
+ export class TypeEditor {
6
+ inline = true;
7
+
8
+ /**
9
+ * Class is hidden and editor should not be displayed
10
+ * @returns {boolean}
11
+ */
12
+ get hidden() {
13
+ return false;
14
+ }
15
+
16
+ /**
17
+ *
18
+ * @returns {TypeSchema|undefined}
19
+ */
20
+ get schema() {
21
+ return undefined;
22
+ }
23
+
24
+ /**
25
+ * @param {*} parent
26
+ * @param {FieldDescriptor} field
27
+ * @param {Map<*, TypeEditor>} registry
28
+ * @returns {View|void}
29
+ */
30
+ build(parent, field, registry) {
31
+ throw new Error('Not Implemented');
32
+ }
33
+ }
@@ -0,0 +1,38 @@
1
+ import {DataType} from "../../../src/core/parser/simple/DataType";
2
+
3
+ interface Type<T> extends Function {
4
+ new(...args: any[]): T;
5
+ }
6
+
7
+ interface PropertiesSchema {
8
+ [key: string]: FieldSchema<any>;
9
+ }
10
+
11
+ export interface TypeSchema {
12
+ additionalProperties?: boolean
13
+ properties: PropertiesSchema
14
+ }
15
+
16
+ interface TypeEditor {
17
+
18
+ }
19
+
20
+ export interface FieldSchema<T> {
21
+ type: Type<T>
22
+ type_parameters?: any[]
23
+ transient?: boolean
24
+ description?: string,
25
+ editor?: TypeEditor
26
+ deprecated?: boolean,
27
+ enum?: T[],
28
+ numeric_type: DataType,
29
+ /**
30
+ * Small image to be displayed next to field name
31
+ */
32
+ thumbnail: string,
33
+ /**
34
+ * @see https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00#section-6.2.2
35
+ */
36
+ maximum?: number,
37
+ minimum?: number
38
+ }
@@ -0,0 +1,92 @@
1
+ import EmptyView from "../../../src/view/elements/EmptyView.js";
2
+ import LabelView from "../../../src/view/common/LabelView.js";
3
+
4
+ function format_field_name(name) {
5
+ return name
6
+ .replace(/([a-z])([A-Z])/g, '$1 $2') // break up camel case
7
+ .replace(/([^.])_([^.])/g, '$1 $2') // break up underscore case
8
+ .replace(/(^\w{1})|(\s+\w{1})/g, letter => letter.toUpperCase()); // capitalize every word
9
+ }
10
+
11
+ /**
12
+ * @template CTX
13
+ * @param {Object} object
14
+ * @param {FieldDescriptor} field
15
+ * @param {Map<*, TypeEditor>} registry
16
+ */
17
+ export function createFieldEditor(object, field, registry) {
18
+
19
+ const field_schema = field.schema;
20
+
21
+ let vValue;
22
+
23
+ /**
24
+ * @type {TypeEditor}
25
+ */
26
+ let factory;
27
+ if (field_schema !== undefined) {
28
+ const specific_field_editor = field_schema.editor;
29
+
30
+ if (specific_field_editor !== undefined) {
31
+ // field has a dedicated editor
32
+ factory = specific_field_editor;
33
+ }
34
+ }
35
+
36
+ if (factory === undefined) {
37
+ factory = registry.get(field.type);
38
+ }
39
+
40
+ let orientation_inline = true;
41
+
42
+ if (factory !== undefined) {
43
+ if (factory.hidden) {
44
+ // hidden class
45
+ return null;
46
+ }
47
+
48
+ vValue = factory.build(object, field, registry);
49
+
50
+ if (vValue) {
51
+ orientation_inline = factory.inline;
52
+ }
53
+ }
54
+
55
+ if (vValue === null || vValue === undefined) {
56
+ // no view
57
+ return null;
58
+ }
59
+
60
+ vValue.addClass('field-value');
61
+
62
+ const vResult = new EmptyView({
63
+ classList: ['auto-field-editor']
64
+ });
65
+
66
+ if (orientation_inline) {
67
+ vResult.addClass('orientation-inline');
68
+ }
69
+
70
+ const field_formatted_name = format_field_name(field.name);
71
+
72
+ const vLabel = new LabelView(field_formatted_name, { classList: ['field-name'] });
73
+
74
+ vResult.addChild(vLabel);
75
+ vResult.addChild(vValue);
76
+
77
+
78
+ if (field_schema !== undefined) {
79
+ if (field_schema.description !== undefined && field_schema.description.length > 0) {
80
+ // add tooltip
81
+ vLabel.attr({
82
+ title: field_schema.description
83
+ });
84
+ }
85
+
86
+ if (field_schema.deprecated) {
87
+ vResult.addClass('field-deprecated');
88
+ }
89
+ }
90
+
91
+ return vResult;
92
+ }
@@ -0,0 +1,361 @@
1
+ import EmptyView from "../../../src/view/elements/EmptyView.js";
2
+ import { FieldDescriptor } from "./FieldDescriptor.js";
3
+ import { FieldValueAdapter } from "./FieldValueAdapter.js";
4
+ import { createFieldEditor } from "./createFieldEditor.js";
5
+ import { findNearestRegisteredType } from "./findNearestRegisteredType.js";
6
+ import LabelView from "../../../src/view/common/LabelView.js";
7
+
8
+ /**
9
+ * @template T
10
+ * @param {T|undefined} value
11
+ */
12
+ function objectToClass(value) {
13
+ if (value === null || value === undefined) {
14
+ return;
15
+ }
16
+
17
+ const type = typeof value;
18
+
19
+ switch (type) {
20
+ case "object":
21
+ const proto = Object.getPrototypeOf(value);
22
+
23
+ if (proto === null) {
24
+ return;
25
+ }
26
+
27
+ return proto.constructor;
28
+ case "boolean":
29
+ return Boolean;
30
+ case "function":
31
+ return Function;
32
+ case "string":
33
+ return String;
34
+ case "number":
35
+ return Number;
36
+ default:
37
+ throw new Error(`Unsupported type '${type}'`);
38
+ }
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param {Object} object
44
+ * @param {string} field_name
45
+ * @returns {boolean}
46
+ */
47
+ function isPublicField(object, field_name) {
48
+ if (field_name.startsWith('_')) {
49
+ // private
50
+ return false;
51
+ }
52
+
53
+ return true;
54
+ }
55
+
56
+ /**
57
+ *
58
+ * @param {Object} object
59
+ * @param {string} field_name
60
+ * @returns {boolean}
61
+ */
62
+ function isReservedField(object, field_name) {
63
+ if (field_name.startsWith('@')) {
64
+ return true;
65
+ }
66
+
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ *
72
+ * @type {string[]}
73
+ */
74
+ const reserved_prototype_names = [
75
+ "constructor"
76
+ ];
77
+
78
+ const reserved_prototypes = [
79
+ Object,
80
+ Object.prototype
81
+ ];
82
+
83
+ /**
84
+ *
85
+ * @param {Object} object
86
+ * @param {FieldDescriptor[]} result
87
+ * @param {*} object_proto
88
+ */
89
+ function extract_object_fields_reflection(object, result, object_proto) {
90
+ const keys = Object.keys(object);
91
+
92
+ for (let i = 0; i < keys.length; i++) {
93
+ const key = keys[i];
94
+
95
+ if (!isPublicField(object, key)) {
96
+ continue;
97
+ }
98
+
99
+ if (isReservedField(object, key)) {
100
+ continue;
101
+ }
102
+
103
+ const field_type = objectToClass(object[key]);
104
+
105
+ if (field_type === undefined) {
106
+ continue;
107
+ }
108
+
109
+ const descriptor = new FieldDescriptor();
110
+ descriptor.name = key;
111
+ descriptor.type = field_type;
112
+ descriptor.adapter = new FieldValueAdapter();
113
+
114
+ result.push(descriptor);
115
+ }
116
+
117
+ if (!reserved_prototypes.includes(object_proto)) {
118
+
119
+ const descriptors = Object.getOwnPropertyDescriptors(object_proto);
120
+
121
+ for (let d_name in descriptors) {
122
+
123
+ if (reserved_prototype_names.includes(d_name)) {
124
+ // reserved name, skip
125
+ continue;
126
+ }
127
+
128
+ const d = descriptors[d_name];
129
+
130
+ const adapter = new FieldValueAdapter();
131
+
132
+ if (d.get === undefined && d.value === undefined) {
133
+ adapter.readable = false;
134
+ }
135
+
136
+ if (d.get !== undefined && d.set === undefined) {
137
+ adapter.writable = false;
138
+ }
139
+
140
+ if (!adapter.readable) {
141
+ continue;
142
+ }
143
+
144
+
145
+ let field_value;
146
+
147
+ try {
148
+ field_value = adapter.read(object, d_name);
149
+ } catch (e) {
150
+ console.warn(e);
151
+ continue;
152
+ }
153
+
154
+ const field_type = objectToClass(field_value);
155
+
156
+ if (field_type === undefined) {
157
+ continue;
158
+ }
159
+
160
+ const descriptor = new FieldDescriptor();
161
+
162
+ descriptor.name = d_name;
163
+ descriptor.type = field_type;
164
+ descriptor.adapter = adapter;
165
+
166
+ result.push(descriptor);
167
+ }
168
+
169
+ }
170
+ }
171
+
172
+ /**
173
+ *
174
+ * @param {Object} object
175
+ * @param {Map<*, TypeEditor>} registry
176
+ * @returns {FieldDescriptor[]}
177
+ */
178
+ function extractObjectFields(object, registry) {
179
+
180
+ const result = [];
181
+
182
+ const object_proto = Object.getPrototypeOf(object);
183
+ const Klass = object_proto.constructor;
184
+
185
+ const editor = registry.get(Klass);
186
+
187
+ if (!(editor?.schema?.additionalProperties === false)) {
188
+
189
+ extract_object_fields_reflection(object, result, object_proto);
190
+
191
+ }
192
+
193
+
194
+ if (editor !== undefined) {
195
+
196
+ const schema = editor.schema;
197
+
198
+ if (schema !== undefined) {
199
+ // has schema, apply
200
+ const prop_keys = Object.keys(schema.properties);
201
+
202
+ for (let i = 0; i < prop_keys.length; i++) {
203
+ const key = prop_keys[i];
204
+
205
+ const property = schema.properties[key];
206
+
207
+ const field_index = result.findIndex(a => a.name === key);
208
+
209
+ let field;
210
+
211
+ if (field_index === -1) {
212
+ // not in schema yet, build
213
+ field = new FieldDescriptor();
214
+ field.name = key;
215
+ field.adapter = new FieldValueAdapter();
216
+
217
+ result.push(field);
218
+ } else {
219
+ field = result[field_index];
220
+ }
221
+
222
+ let actual_type = field.type;
223
+
224
+ if (actual_type === undefined || actual_type === null) {
225
+ let actual_value;
226
+
227
+ try {
228
+ actual_value = field.adapter.read(object, key);
229
+ } catch (e) {
230
+ // silent failure
231
+ }
232
+
233
+ if (actual_value !== undefined && actual_value !== null) {
234
+ actual_type = objectToClass(actual_value);
235
+ }
236
+ }
237
+
238
+ if (property.type) {
239
+ // validate type
240
+ if (actual_type !== undefined && actual_type !== null) {
241
+ if (actual_type !== property.type) {
242
+ console.error(`Schema violation at field '${key}', schema type is different from actual type`, schema, actual_type);
243
+ }
244
+ }
245
+
246
+ field.type = property.type;
247
+ } else if (actual_type !== undefined && field.type !== actual_type) {
248
+ field.type = actual_type;
249
+ }
250
+
251
+
252
+ field.schema = property;
253
+
254
+ if (property.transient === true) {
255
+ // no point in editing transient
256
+ result.splice(field_index, 1);
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ return result;
263
+ }
264
+
265
+ const build_path = [];
266
+ let build_path_offset = 0;
267
+
268
+
269
+ /**
270
+ * @param {Object} object
271
+ * @param {Map<*, TypeEditor>} registry
272
+ * @param {FieldDescriptor} [field_descriptor]
273
+ */
274
+ export function buildObjectEditorFromRegistry(object, registry, field_descriptor) {
275
+
276
+ const editor = findNearestRegisteredType(registry, object);
277
+
278
+ let fd;
279
+
280
+ if (field_descriptor === undefined) {
281
+
282
+ fd = new FieldDescriptor();
283
+ fd.adapter = new FieldValueAdapter();
284
+
285
+ fd.adapter.read = () => object;
286
+ fd.adapter.writable = false;
287
+
288
+ if (editor.schema) {
289
+ fd.schema = editor.schema;
290
+ }
291
+
292
+ } else {
293
+ fd = field_descriptor;
294
+ }
295
+
296
+ return editor.build(null, fd, registry);
297
+ }
298
+
299
+ const MAX_DEPTH = 7;
300
+
301
+ /**
302
+ * @param {Object} object
303
+ * @param {Map<*, TypeEditor>} registry
304
+ */
305
+ export function createObjectEditor(object, registry) {
306
+
307
+ if (build_path_offset > MAX_DEPTH) {
308
+ // too deep
309
+ return undefined;
310
+ }
311
+
312
+ const seen_index = build_path.indexOf(object);
313
+ if (seen_index >= 0 && seen_index < build_path_offset) {
314
+ // recursion
315
+ return undefined;
316
+ }
317
+
318
+
319
+ build_path[build_path_offset++] = object;
320
+
321
+
322
+ const vResult = new EmptyView({
323
+ classList: ['auto-object-editor'],
324
+ css: {}
325
+ });
326
+
327
+
328
+ const fields = extractObjectFields(object, registry);
329
+
330
+ const field_views = [];
331
+
332
+ for (let i = 0; i < fields.length; i++) {
333
+ const field = fields[i];
334
+
335
+ let vField;
336
+
337
+ try {
338
+ vField = createFieldEditor(object, field, registry);
339
+ } catch (e) {
340
+ vField = new LabelView('ERROR');
341
+ console.warn(e);
342
+ }
343
+
344
+ if (vField === null) {
345
+ continue;
346
+ }
347
+
348
+ field_views.push(vField);
349
+ }
350
+
351
+ build_path_offset--;
352
+
353
+ if (field_views.length === 0) {
354
+ // skip containers with no data
355
+ return null;
356
+ }
357
+
358
+ vResult.addChildren(field_views);
359
+
360
+ return vResult;
361
+ }
@@ -0,0 +1,39 @@
1
+ import { TypeEditor } from "../TypeEditor.js";
2
+ import EmptyView from "../../../../src/view/elements/EmptyView.js";
3
+ import { rgb2hex } from "../../../../src/core/color/rgb2hex.js";
4
+
5
+ export class ColorEditor extends TypeEditor {
6
+ build(parent, field) {
7
+
8
+ /**
9
+ * @type {Color}
10
+ */
11
+ const color = field.adapter.read(parent, field.name);
12
+
13
+ const view = new EmptyView({
14
+ tag: 'input'
15
+ });
16
+
17
+ view.attr({
18
+ type: "color"
19
+ });
20
+
21
+ function sync_up() {
22
+ view.attr({
23
+ value: `#${rgb2hex(color.r * 255, color.g * 255, color.b * 255)}`
24
+ })
25
+ }
26
+
27
+ function sync_down(e) {
28
+ const color_value = e.target.value;
29
+
30
+ color.parse(color_value);
31
+ }
32
+
33
+ view.on.linked.add(sync_up);
34
+ view.el.addEventListener('input', sync_down, false);
35
+ view.el.addEventListener('change', sync_down, false);
36
+
37
+ return view;
38
+ }
39
+ }
@@ -0,0 +1,17 @@
1
+ import { TypeEditor } from "../TypeEditor.js";
2
+ import View from "../../../../src/view/View.js";
3
+
4
+ export class HTMLElementEditor extends TypeEditor {
5
+ build(parent, field, registry) {
6
+ const el = field.adapter?.read(parent, field.name);
7
+
8
+ const view = new View();
9
+
10
+ view.el = el;
11
+
12
+ // make the size small
13
+ view.size.setScalar(32);
14
+
15
+ return view;
16
+ }
17
+ }
@@ -0,0 +1,82 @@
1
+ import { TypeEditor } from "../TypeEditor.js";
2
+ import EmptyView from "../../../../src/view/elements/EmptyView.js";
3
+ import ImageView from "../../../../src/view/elements/image/ImageView.js";
4
+ import ButtonView from "../../../../src/view/elements/button/ButtonView.js";
5
+ import { url_to_data_url } from "../../../../src/core/binary/url_to_data_url.js";
6
+ import { is_data_url } from "../../../../src/core/binary/is_data_url.js";
7
+ import { LargeStrongEditor } from "./LargeStrongEditor.js";
8
+
9
+ export class ImagePathEditor extends TypeEditor {
10
+ inline = true;
11
+
12
+ build(parent, field, registry) {
13
+ const url_editor = new LargeStrongEditor();
14
+
15
+ const editor = url_editor.build(parent, field, registry);
16
+
17
+ const r = new EmptyView({
18
+ css: {
19
+ display: "flex",
20
+ flexDirection: "row"
21
+ }
22
+ });
23
+
24
+ const vPreview = new ImageView(field.adapter.read(parent, field.name));
25
+
26
+ vPreview.size.set(32, 32);
27
+
28
+ const b_toDataURL = new ButtonView({
29
+ classList: ['convert-to-data-url', 'embed'],
30
+ async action() {
31
+ const url = await url_to_data_url(field.adapter.read(parent, field.name));
32
+
33
+ field.adapter.write(parent, field.name, url);
34
+
35
+ // update editor value
36
+ editor.methods.set_value(url);
37
+
38
+ input_changed();
39
+ }
40
+ });
41
+
42
+ b_toDataURL.attr({
43
+ title: 'Convert URL into DATA_URL, embedding the data. This allows to bypass CORRS restrictions if the URL points to a different origin from the one where the texture resides'
44
+ });
45
+
46
+ function update_data_url_status() {
47
+ const url = field.adapter.read(parent, field.name);
48
+
49
+ const can_convert = typeof url === "string"
50
+ && field.adapter.writable
51
+ && !is_data_url(url)
52
+ ;
53
+
54
+ if (can_convert) {
55
+ // offer encoding option
56
+ r.addChild(b_toDataURL);
57
+ } else {
58
+ // nothing
59
+ if (r.hasChild(b_toDataURL)) {
60
+ r.removeChild(b_toDataURL);
61
+ }
62
+ }
63
+ }
64
+
65
+ function input_changed() {
66
+ const url = field.adapter.read(parent, field.name);
67
+
68
+ vPreview.__setSource(url);
69
+
70
+ update_data_url_status();
71
+ }
72
+
73
+ r.addChild(vPreview);
74
+ r.addChild(editor.view);
75
+
76
+ editor.signals.input_changed.add(input_changed);
77
+
78
+ r.on.linked.add(update_data_url_status);
79
+
80
+ return r;
81
+ }
82
+ }