@woosh/meep-engine 2.46.18 → 2.46.20

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.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "productName": "Meep",
5
5
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
6
6
  "author": "Alexander Goldring",
7
- "version": "2.46.18",
7
+ "version": "2.46.20",
8
8
  "main": "build/meep.module.js",
9
9
  "module": "build/meep.module.js",
10
10
  "scripts": {
@@ -7,11 +7,11 @@ import { assert } from "../assert.js";
7
7
  */
8
8
  export class LocaleDataset {
9
9
  /**
10
- * Localized strings, identified by localization key
11
- * @type {Object<string>}
10
+ * Localized objects, identified by localization key
11
+ * @type {Object<Object|string>}
12
12
  * @private
13
13
  */
14
- __strings = {}
14
+ #map = {}
15
15
 
16
16
  /**
17
17
  *
@@ -19,19 +19,19 @@ export class LocaleDataset {
19
19
  * @param {string} key
20
20
  * @return {boolean}
21
21
  */
22
- hasString(key) {
22
+ hasKey(key) {
23
23
  assert.isString(key, 'key');
24
24
 
25
- return this.__strings[key] !== undefined;
25
+ return this.#map[key] !== undefined;
26
26
  }
27
27
 
28
28
  /**
29
29
  *
30
30
  * @param {string} key
31
- * @returns {string|undefined}
31
+ * @returns {string|Object|undefined}
32
32
  */
33
- getString(key) {
34
- return this.__strings[key];
33
+ get(key) {
34
+ return this.#map[key];
35
35
  }
36
36
 
37
37
  }
@@ -0,0 +1,98 @@
1
+ import { array_get_index_in_range } from "../collection/array/array_get_index_in_range.js";
2
+ import { assert } from "../assert.js";
3
+
4
+ const resolve_chain = [];
5
+
6
+ export class LocalizationEngine {
7
+ /**
8
+ *
9
+ * @type {Object<LocaleDataset>}
10
+ */
11
+ #locales = {};
12
+ /**
13
+ *
14
+ * @type {Object<LanguageMetadata>}
15
+ */
16
+ #languages = {};
17
+
18
+
19
+ /**
20
+ *
21
+ * @param {string} key
22
+ * @param {LocaleDataset} dataset
23
+ */
24
+ setLocaleDataset(key, dataset) {
25
+ assert.isString(key, 'key');
26
+ assert.defined(dataset, 'dataset');
27
+
28
+ this.#locales[key] = dataset;
29
+ }
30
+
31
+ /**
32
+ *
33
+ * @param {LanguageMetadata} metadata
34
+ */
35
+ addLanguageMetadata(metadata) {
36
+ assert.defined(metadata, 'metadata');
37
+
38
+ this.#languages[metadata.locale] = metadata;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * Resolves language and fragment key to a localized value, follows fallback links of known languages when no value found in requested language
44
+ *
45
+ * @param {string} language_key Locale key
46
+ * @param {string} fragment_key Object key
47
+ * @returns {Object|string|undefined}
48
+ */
49
+ resolve(language_key, fragment_key) {
50
+
51
+
52
+ resolve_chain[0] = language_key;
53
+ let resolve_cursor = 0;
54
+ let resolve_chain_end = 1;
55
+
56
+ while (resolve_cursor < resolve_chain_end) {
57
+ const lang = resolve_chain[resolve_cursor++];
58
+
59
+ const locale = this.#locales[lang];
60
+
61
+ if (locale !== undefined && locale[fragment_key] !== undefined) {
62
+
63
+ // found a hit
64
+ return locale[fragment_key];
65
+
66
+ } else {
67
+
68
+ // see if there's a fallback locale
69
+ const metadata = this.#languages[lang];
70
+
71
+ if (metadata !== undefined) {
72
+
73
+ const fallbacks = metadata.fallback_languages;
74
+ const fallback_count = fallbacks.length;
75
+
76
+ for (let i = 0; i < fallback_count; i++) {
77
+
78
+ const fallback = fallbacks[i];
79
+
80
+ if (array_get_index_in_range(resolve_chain, fallback, 0, resolve_chain_end) !== -1) {
81
+ // circular dependency, that language was already attempted
82
+ continue;
83
+ }
84
+
85
+ resolve_chain[resolve_chain_end++] = fallback;
86
+
87
+ }
88
+
89
+ }
90
+
91
+ }
92
+ }
93
+
94
+ // chain exhausted, no result found
95
+ return undefined;
96
+ }
97
+
98
+ }
@@ -65,6 +65,22 @@ export class NodeDescription {
65
65
  this.parameters = [];
66
66
  }
67
67
 
68
+ /**
69
+ * Output ports
70
+ * @returns {Port[]}
71
+ */
72
+ get outPorts() {
73
+ return this.ports.filter(p => p.direction === PortDirection.Out);
74
+ }
75
+
76
+ /**
77
+ * Input ports
78
+ * @returns {Port[]}
79
+ */
80
+ get inPorts() {
81
+ return this.ports.filter(p => p.direction === PortDirection.In);
82
+ }
83
+
68
84
  /**
69
85
  *
70
86
  * @param {string} name
@@ -80,6 +80,23 @@ export class NodeInstance {
80
80
  return count;
81
81
  }
82
82
 
83
+ /**
84
+ * Output port references
85
+ * @returns {NodeInstancePortReference[]}
86
+ */
87
+ get outEndpoints() {
88
+ return this.endpoints.filter(ref => ref.port.direction === PortDirection.Out);
89
+ }
90
+
91
+ /**
92
+ * Input port references
93
+ * @returns {NodeInstancePortReference[]}
94
+ */
95
+ get inEndpoints() {
96
+ return this.endpoints.filter(ref => ref.port.direction === PortDirection.In);
97
+ }
98
+
99
+
83
100
  /**
84
101
  * Outgoing connections from this node
85
102
  * @return {Connection[]}
@@ -151,9 +168,10 @@ export class NodeInstance {
151
168
  this.description = node;
152
169
 
153
170
  //generate endpoints
154
- this.endpoints = node.getPorts().map(port => {
171
+ this.endpoints = node.getPorts().map((port, port_index) => {
155
172
  const endpoint = new NodeInstancePortReference();
156
173
 
174
+ endpoint.id = port_index;
157
175
  endpoint.port = port;
158
176
  endpoint.instance = this;
159
177
 
@@ -24,6 +24,8 @@ import { MetricsCategory } from "../metrics/MetricsCategory.js";
24
24
  import { ClockChannelType } from "../intelligence/behavior/ecs/ClockChannelType.js";
25
25
  import { EnginePlugin } from "../plugin/EnginePlugin.js";
26
26
  import { makeCubicCurve } from "../../core/math/makeCubicCurve.js";
27
+ import { logger } from "../logging/GlobalLogger.js";
28
+ import { assert } from "../../core/assert.js";
27
29
 
28
30
 
29
31
  const SLOW_CUBIC = makeCubicCurve(0.04, 0.4, 0.9, 0.99);
@@ -134,6 +136,8 @@ export class AchievementManager extends EnginePlugin {
134
136
  * @param {String} id
135
137
  */
136
138
  unlock(id) {
139
+ assert.isString(id, 'id');
140
+
137
141
  const key = computeAchievementBlackboardFlag(id);
138
142
  const value = this.blackboard.acquireBoolean(key, false);
139
143
 
@@ -146,6 +150,10 @@ export class AchievementManager extends EnginePlugin {
146
150
 
147
151
  const achievement = this.getAchievementById(id);
148
152
 
153
+ if (achievement === undefined) {
154
+ logger.warn(`Attempting to unlock achievement ${id}. Achievement not found`);
155
+ }
156
+
149
157
  if (achievement !== undefined && this.isGatewayInitialized.getValue()) {
150
158
  this.deactivateEntry(achievement);
151
159
 
@@ -23,6 +23,19 @@ export class SelectorBehavior extends CompositeBehavior {
23
23
  this.__currentBehaviourIndex = -1;
24
24
  }
25
25
 
26
+ /**
27
+ *
28
+ * @param {Behavior[]} children
29
+ * @returns {SelectorBehavior}
30
+ */
31
+ static from(children) {
32
+ const r = new SelectorBehavior();
33
+
34
+ children.forEach(this.addChild, this);
35
+
36
+ return r;
37
+ }
38
+
26
39
  tick(timeDelta) {
27
40
  if (this.__children.length < 1) {
28
41
  // no options, nothing chosen