@byloth/core 2.0.0-rc.9 → 2.0.0
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/dist/core.js +3371 -608
- package/dist/core.js.map +1 -1
- package/dist/core.umd.cjs +2 -2
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +13 -10
- package/src/core/types.ts +41 -0
- package/src/helpers.ts +11 -2
- package/src/index.ts +12 -9
- package/src/models/aggregators/aggregated-async-iterator.ts +765 -21
- package/src/models/aggregators/aggregated-iterator.ts +698 -22
- package/src/models/aggregators/reduced-iterator.ts +699 -10
- package/src/models/aggregators/types.ts +153 -10
- package/src/models/callbacks/callable-object.ts +42 -6
- package/src/models/callbacks/index.ts +2 -2
- package/src/models/callbacks/publisher.ts +139 -4
- package/src/models/callbacks/switchable-callback.ts +138 -4
- package/src/models/callbacks/types.ts +16 -0
- package/src/models/exceptions/core.ts +112 -3
- package/src/models/exceptions/index.ts +340 -13
- package/src/models/index.ts +4 -8
- package/src/models/iterators/smart-async-iterator.ts +687 -22
- package/src/models/iterators/smart-iterator.ts +631 -21
- package/src/models/iterators/types.ts +268 -9
- package/src/models/json/json-storage.ts +388 -110
- package/src/models/json/types.ts +10 -1
- package/src/models/promises/deferred-promise.ts +75 -5
- package/src/models/promises/index.ts +1 -3
- package/src/models/promises/smart-promise.ts +232 -4
- package/src/models/promises/timed-promise.ts +38 -1
- package/src/models/promises/types.ts +84 -2
- package/src/models/timers/clock.ts +91 -19
- package/src/models/timers/countdown.ts +152 -22
- package/src/models/timers/game-loop.ts +243 -0
- package/src/models/timers/index.ts +2 -1
- package/src/models/types.ts +6 -5
- package/src/utils/async.ts +43 -0
- package/src/utils/curve.ts +75 -0
- package/src/utils/date.ts +204 -10
- package/src/utils/dom.ts +16 -2
- package/src/utils/index.ts +3 -2
- package/src/utils/iterator.ts +200 -17
- package/src/utils/math.ts +55 -3
- package/src/utils/random.ts +109 -2
- package/src/utils/string.ts +11 -0
- package/src/models/game-loop.ts +0 -83
- package/src/models/promises/long-running-task.ts +0 -294
- package/src/models/promises/thenable.ts +0 -97
package/src/utils/iterator.ts
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
|
-
import { SmartIterator } from "../models/index.js";
|
|
1
|
+
import { RangeException, SmartIterator } from "../models/index.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* An utility function that chains multiple iterables into a single one.
|
|
5
|
+
*
|
|
6
|
+
* Since the iterator is lazy, the chaining process will be
|
|
7
|
+
* executed only once the resulting iterator is materialized.
|
|
8
|
+
*
|
|
9
|
+
* A new iterator will be created, holding the reference to the original one.
|
|
10
|
+
* This means that the original iterator won't be consumed until the
|
|
11
|
+
* new one is and that consuming one of them will consume the other as well.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* for (const value of chain([1, 2, 3], [4, 5, 6], [7, 8, 9]))
|
|
15
|
+
* {
|
|
16
|
+
* console.log(value); // 1, 2, 3, 4, 5, 6, 7, 8, 9
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @template T The type of elements in the iterables.
|
|
21
|
+
*
|
|
22
|
+
* @param iterables The list of iterables to chain.
|
|
23
|
+
*
|
|
24
|
+
* @returns A new {@link SmartIterator} object that chains the iterables into a single one.
|
|
25
|
+
*/
|
|
26
|
+
export function chain<T>(...iterables: readonly Iterable<T>[]): SmartIterator<T>
|
|
4
27
|
{
|
|
5
28
|
return new SmartIterator<T>(function* ()
|
|
6
29
|
{
|
|
@@ -11,9 +34,26 @@ export function chain<T>(...iterables: Iterable<T>[]): SmartIterator<T>
|
|
|
11
34
|
});
|
|
12
35
|
}
|
|
13
36
|
|
|
37
|
+
/**
|
|
38
|
+
* An utility function that counts the number of elements in an iterable.
|
|
39
|
+
*
|
|
40
|
+
* Also note that:
|
|
41
|
+
* - If the iterable isn't an `Array`, it will be consumed entirely in the process.
|
|
42
|
+
* - If the iterable is an infinite generator, the function will never return.
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* count([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); // 10
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @template T The type of elements in the iterable.
|
|
49
|
+
*
|
|
50
|
+
* @param elements The iterable to count.
|
|
51
|
+
*
|
|
52
|
+
* @returns The number of elements in the iterable.
|
|
53
|
+
*/
|
|
14
54
|
export function count<T>(elements: Iterable<T>): number
|
|
15
55
|
{
|
|
16
|
-
if (Array
|
|
56
|
+
if (elements instanceof Array) { return elements.length; }
|
|
17
57
|
|
|
18
58
|
let _count = 0;
|
|
19
59
|
for (const _ of elements) { _count += 1; }
|
|
@@ -21,12 +61,35 @@ export function count<T>(elements: Iterable<T>): number
|
|
|
21
61
|
return _count;
|
|
22
62
|
}
|
|
23
63
|
|
|
64
|
+
/**
|
|
65
|
+
* An utility function that enumerates the elements of an iterable.
|
|
66
|
+
* Each element is paired with its index in a new iterator.
|
|
67
|
+
*
|
|
68
|
+
* Since the iterator is lazy, the enumeration process will
|
|
69
|
+
* be executed once the resulting iterator is materialized.
|
|
70
|
+
*
|
|
71
|
+
* A new iterator will be created, holding the reference to the original one.
|
|
72
|
+
* This means that the original iterator won't be consumed until the
|
|
73
|
+
* new one is and that consuming one of them will consume the other as well.
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* for (const [index, value] of enumerate(["A", "M", "N", "Z"]))
|
|
77
|
+
* {
|
|
78
|
+
* console.log(`${index}: ${value}`); // "0: A", "1: M", "2: N", "3: Z"
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @template T The type of elements in the iterable.
|
|
83
|
+
*
|
|
84
|
+
* @param elements The iterable to enumerate.
|
|
85
|
+
*
|
|
86
|
+
* @returns A new {@link SmartIterator} object containing the enumerated elements.
|
|
87
|
+
*/
|
|
24
88
|
export function enumerate<T>(elements: Iterable<T>): SmartIterator<[number, T]>
|
|
25
89
|
{
|
|
26
90
|
return new SmartIterator<[number, T]>(function* ()
|
|
27
91
|
{
|
|
28
92
|
let index = 0;
|
|
29
|
-
|
|
30
93
|
for (const element of elements)
|
|
31
94
|
{
|
|
32
95
|
yield [index, element];
|
|
@@ -36,25 +99,109 @@ export function enumerate<T>(elements: Iterable<T>): SmartIterator<[number, T]>
|
|
|
36
99
|
});
|
|
37
100
|
}
|
|
38
101
|
|
|
102
|
+
/**
|
|
103
|
+
* An utility function that generates an iterator over a range of numbers.
|
|
104
|
+
* The values are included between `0` (included) and `end` (excluded).
|
|
105
|
+
*
|
|
106
|
+
* The default step between the numbers is `1`.
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* for (const number of range(5))
|
|
110
|
+
* {
|
|
111
|
+
* console.log(number); // 0, 1, 2, 3, 4
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @param end
|
|
116
|
+
* The end value (excluded).
|
|
117
|
+
*
|
|
118
|
+
* If the `end` value is negative, the step will be `-1` leading to generate the numbers in reverse order.
|
|
119
|
+
*
|
|
120
|
+
* @returns A {@link SmartIterator} object that generates the numbers in the range.
|
|
121
|
+
*/
|
|
39
122
|
export function range(end: number): SmartIterator<number>;
|
|
40
|
-
|
|
41
|
-
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* An utility function that generates an iterator over a range of numbers.
|
|
126
|
+
* The values are included between `start` (included) and `end` (excluded).
|
|
127
|
+
*
|
|
128
|
+
* The step between the numbers can be specified with a custom value. Default is `1`.
|
|
129
|
+
*
|
|
130
|
+
* ```ts
|
|
131
|
+
* for (const number of range(2, 7))
|
|
132
|
+
* {
|
|
133
|
+
* console.log(number); // 2, 3, 4, 5, 6
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @param start
|
|
138
|
+
* The start value (included).
|
|
139
|
+
*
|
|
140
|
+
* If the `start` value is greater than the `end` value, the iterator will generate the numbers in reverse order.
|
|
141
|
+
*
|
|
142
|
+
* @param end
|
|
143
|
+
* The end value (excluded).
|
|
144
|
+
*
|
|
145
|
+
* If the `end` value is less than the `start` value, the iterator will generate the numbers in reverse order.
|
|
146
|
+
*
|
|
147
|
+
* @param step
|
|
148
|
+
* The step between the numbers. Default is `1`.
|
|
149
|
+
*
|
|
150
|
+
* Must be a positive number. Otherwise, a {@link RangeError} will be thrown.
|
|
151
|
+
*
|
|
152
|
+
* @returns A {@link SmartIterator} object that generates the numbers in the range.
|
|
153
|
+
*/
|
|
154
|
+
export function range(start: number, end: number, step?: number): SmartIterator<number>;
|
|
42
155
|
export function range(start: number, end?: number, step = 1): SmartIterator<number>
|
|
43
156
|
{
|
|
44
|
-
|
|
157
|
+
if (step <= 0)
|
|
45
158
|
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
159
|
+
throw new RangeException(
|
|
160
|
+
"Step must be always a positive number, even when generating numbers in reverse order."
|
|
161
|
+
);
|
|
162
|
+
}
|
|
51
163
|
|
|
52
|
-
|
|
164
|
+
if (end === undefined)
|
|
165
|
+
{
|
|
166
|
+
end = start;
|
|
167
|
+
start = 0;
|
|
168
|
+
}
|
|
53
169
|
|
|
170
|
+
if (start > end)
|
|
171
|
+
{
|
|
172
|
+
return new SmartIterator<number>(function* ()
|
|
173
|
+
{
|
|
174
|
+
for (let index = start; index > end; index -= step) { yield index; }
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return new SmartIterator<number>(function* ()
|
|
179
|
+
{
|
|
54
180
|
for (let index = start; index < end; index += step) { yield index; }
|
|
55
181
|
});
|
|
56
182
|
}
|
|
57
183
|
|
|
184
|
+
/**
|
|
185
|
+
* An utility function shuffles the elements of a given iterable.
|
|
186
|
+
*
|
|
187
|
+
* The function uses the {@link https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle|Fisher-Yates}
|
|
188
|
+
* algorithm to shuffle the elements.
|
|
189
|
+
*
|
|
190
|
+
* Also note that:
|
|
191
|
+
* - If the iterable is an `Array`, it won't be modified since the shuffling isn't done in-place.
|
|
192
|
+
* - If the iterable isn't an `Array`, it will be consumed entirely in the process.
|
|
193
|
+
* - If the iterable is an infinite generator, the function will never return.
|
|
194
|
+
*
|
|
195
|
+
* ```ts
|
|
196
|
+
* shuffle([1, 2, 3, 4, 5]); // [3, 1, 5, 2, 4]
|
|
197
|
+
* ```
|
|
198
|
+
*
|
|
199
|
+
* @template T The type of elements in the iterable.
|
|
200
|
+
*
|
|
201
|
+
* @param iterable The iterable to shuffle.
|
|
202
|
+
*
|
|
203
|
+
* @returns A new `Array` containing the shuffled elements of the given iterable.
|
|
204
|
+
*/
|
|
58
205
|
export function shuffle<T>(iterable: Iterable<T>): T[]
|
|
59
206
|
{
|
|
60
207
|
const array = Array.from(iterable);
|
|
@@ -69,12 +216,27 @@ export function shuffle<T>(iterable: Iterable<T>): T[]
|
|
|
69
216
|
return array;
|
|
70
217
|
}
|
|
71
218
|
|
|
219
|
+
/**
|
|
220
|
+
* An utility function that filters the elements of an iterable ensuring that they are all unique.
|
|
221
|
+
*
|
|
222
|
+
* ```ts
|
|
223
|
+
* for (const value of unique([1, 1, 2, 3, 2, 3, 4, 5, 5, 4]))
|
|
224
|
+
* {
|
|
225
|
+
* console.log(value); // 1, 2, 3, 4, 5
|
|
226
|
+
* }
|
|
227
|
+
* ```
|
|
228
|
+
*
|
|
229
|
+
* @template T The type of elements in the iterable.
|
|
230
|
+
*
|
|
231
|
+
* @param elements The iterable to filter.
|
|
232
|
+
*
|
|
233
|
+
* @returns A {@link SmartIterator} object that iterates over the unique elements of the given iterable.
|
|
234
|
+
*/
|
|
72
235
|
export function unique<T>(elements: Iterable<T>): SmartIterator<T>
|
|
73
236
|
{
|
|
74
237
|
return new SmartIterator<T>(function* ()
|
|
75
238
|
{
|
|
76
239
|
const values = new Set<T>();
|
|
77
|
-
|
|
78
240
|
for (const element of elements)
|
|
79
241
|
{
|
|
80
242
|
if (values.has(element)) { continue; }
|
|
@@ -86,13 +248,34 @@ export function unique<T>(elements: Iterable<T>): SmartIterator<T>
|
|
|
86
248
|
});
|
|
87
249
|
}
|
|
88
250
|
|
|
251
|
+
/**
|
|
252
|
+
* An utility function that zips two iterables into a single one.
|
|
253
|
+
* The resulting iterable will contain the elements of the two iterables paired together.
|
|
254
|
+
*
|
|
255
|
+
* The function will stop when one of the two iterables is exhausted.
|
|
256
|
+
*
|
|
257
|
+
* ```ts
|
|
258
|
+
* for (const [number, char] of zip([1, 2, 3, 4], ["A", "M", "N" "Z"]))
|
|
259
|
+
* {
|
|
260
|
+
* console.log(`${number} - ${char}`); // "1 - A", "2 - M", "3 - N", "4 - Z"
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
263
|
+
*
|
|
264
|
+
* @template T The type of elements in the first iterable.
|
|
265
|
+
* @template U The type of elements in the second iterable.
|
|
266
|
+
*
|
|
267
|
+
* @param first The first iterable to zip.
|
|
268
|
+
* @param second The second iterable to zip.
|
|
269
|
+
*
|
|
270
|
+
* @returns A {@link SmartIterator} object that iterates over the zipped elements of the two given iterables.
|
|
271
|
+
*/
|
|
89
272
|
export function zip<T, U>(first: Iterable<T>, second: Iterable<U>): SmartIterator<[T, U]>
|
|
90
273
|
{
|
|
274
|
+
const firstIterator = first[Symbol.iterator]();
|
|
275
|
+
const secondIterator = second[Symbol.iterator]();
|
|
276
|
+
|
|
91
277
|
return new SmartIterator<[T, U]>(function* ()
|
|
92
278
|
{
|
|
93
|
-
const firstIterator = first[Symbol.iterator]();
|
|
94
|
-
const secondIterator = second[Symbol.iterator]();
|
|
95
|
-
|
|
96
279
|
while (true)
|
|
97
280
|
{
|
|
98
281
|
const firstResult = firstIterator.next();
|
package/src/utils/math.ts
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
import { ValueException } from "../models/exceptions/index.js";
|
|
2
2
|
import { zip } from "./iterator.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Computes the average of a given list of values.
|
|
6
|
+
* The values can be weighted using an additional list of weights.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* average([1, 2, 3, 4, 5]); // 3
|
|
10
|
+
* average([6, 8.5, 4], [3, 2, 1]); // 6.5
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @template T The type of the values in the list. It must be or extend a `number` object.
|
|
14
|
+
*
|
|
15
|
+
* @param values
|
|
16
|
+
* The list of values to compute the average.
|
|
17
|
+
*
|
|
18
|
+
* It must contain at least one element. Otherwise, a {@link ValueException} will be thrown.
|
|
19
|
+
*
|
|
20
|
+
* @param weights
|
|
21
|
+
* The list of weights to apply to the values.
|
|
22
|
+
* It should contain the same number of elements as the values list or
|
|
23
|
+
* the smaller number of elements between the two lists will be considered.
|
|
24
|
+
*
|
|
25
|
+
* The sum of the weights must be greater than zero. Otherwise, a {@link ValueException} will be thrown.
|
|
26
|
+
*
|
|
27
|
+
* @returns The average of the specified values.
|
|
28
|
+
*/
|
|
6
29
|
export function average<T extends number>(values: Iterable<T>, weights?: Iterable<number>): number
|
|
7
30
|
{
|
|
8
31
|
if (weights === undefined)
|
|
@@ -38,11 +61,27 @@ export function average<T extends number>(values: Iterable<T>, weights?: Iterabl
|
|
|
38
61
|
}
|
|
39
62
|
|
|
40
63
|
if (_index === 0) { throw new ValueException("You must provide at least one value and weight."); }
|
|
41
|
-
if (_count
|
|
64
|
+
if (_count <= 0) { throw new ValueException("The sum of weights must be greater than zero."); }
|
|
42
65
|
|
|
43
66
|
return _sum / _count;
|
|
44
67
|
}
|
|
45
68
|
|
|
69
|
+
/**
|
|
70
|
+
* An utility function to compute the hash of a given string.
|
|
71
|
+
*
|
|
72
|
+
* The hash is computed using a simple variation of the
|
|
73
|
+
* {@link http://www.cse.yorku.ca/~oz/hash.html#djb2|djb2} algorithm.
|
|
74
|
+
* However, the hash is garanteed to be a 32-bit signed integer.
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* hash("Hello, world!"); // -1880044555
|
|
78
|
+
* hash("How are you?"); // 1761539132
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @param value The string to hash.
|
|
82
|
+
*
|
|
83
|
+
* @returns The hash of the specified string.
|
|
84
|
+
*/
|
|
46
85
|
export function hash(value: string): number
|
|
47
86
|
{
|
|
48
87
|
let hashedValue = 0;
|
|
@@ -57,6 +96,19 @@ export function hash(value: string): number
|
|
|
57
96
|
return hashedValue;
|
|
58
97
|
}
|
|
59
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Sums all the values of a given list.
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* sum([1, 2, 3, 4, 5]); // 15
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @template T The type of the values in the list. It must be or extend a `number` object.
|
|
107
|
+
*
|
|
108
|
+
* @param values The list of values to sum.
|
|
109
|
+
*
|
|
110
|
+
* @returns The sum of the specified values.
|
|
111
|
+
*/
|
|
60
112
|
export function sum<T extends number>(values: Iterable<T>): number
|
|
61
113
|
{
|
|
62
114
|
let _sum = 0;
|
package/src/utils/random.ts
CHANGED
|
@@ -1,13 +1,61 @@
|
|
|
1
1
|
import { ValueException } from "../models/index.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A wrapper class around the native {@link Math.random} function that
|
|
5
|
+
* provides a set of methods to generate random values more easily.
|
|
6
|
+
* It can be used to generate random numbers, booleans and other different values.
|
|
7
|
+
*
|
|
8
|
+
* It cannot be instantiated directly.
|
|
9
|
+
*/
|
|
3
10
|
export default class Random
|
|
4
11
|
{
|
|
12
|
+
/**
|
|
13
|
+
* Generates a random boolean value.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* if (Random.Boolean())
|
|
17
|
+
* {
|
|
18
|
+
* // Do something...
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param ratio
|
|
23
|
+
* The probability of generating `true`.
|
|
24
|
+
*
|
|
25
|
+
* It must be included between `0` and `1`. Default is `0.5`.
|
|
26
|
+
*
|
|
27
|
+
* @returns A random boolean value.
|
|
28
|
+
*/
|
|
5
29
|
public static Boolean(ratio = 0.5): boolean
|
|
6
30
|
{
|
|
7
31
|
return (Math.random() < ratio);
|
|
8
32
|
}
|
|
9
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Generates a random integer value between `0` (included) and `max` (excluded).
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* Random.Integer(5); // 0, 1, 2, 3, 4
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param max The maximum value (excluded).
|
|
42
|
+
*
|
|
43
|
+
* @returns A random integer value.
|
|
44
|
+
*/
|
|
10
45
|
public static Integer(max: number): number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generates a random integer value between `min` (included) and `max` (excluded).
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* Random.Integer(2, 7); // 2, 3, 4, 5, 6
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @param min The minimum value (included).
|
|
55
|
+
* @param max The maximum value (excluded).
|
|
56
|
+
*
|
|
57
|
+
* @returns A random integer value.
|
|
58
|
+
*/
|
|
11
59
|
public static Integer(min: number, max: number): number;
|
|
12
60
|
public static Integer(min: number, max?: number): number
|
|
13
61
|
{
|
|
@@ -16,8 +64,42 @@ export default class Random
|
|
|
16
64
|
return Math.floor(Math.random() * (max - min) + min);
|
|
17
65
|
}
|
|
18
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Generates a random decimal value between `0` (included) and `1` (excluded).
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* Random.Decimal(); // 0.123456789
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @returns A random decimal value.
|
|
75
|
+
*/
|
|
19
76
|
public static Decimal(): number;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Generates a random decimal value between `0` (included) and `max` (excluded).
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* Random.Decimal(5); // 2.3456789
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @param max The maximum value (excluded).
|
|
86
|
+
*
|
|
87
|
+
* @returns A random decimal value.
|
|
88
|
+
*/
|
|
20
89
|
public static Decimal(max: number): number;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Generates a random decimal value between `min` (included) and `max` (excluded).
|
|
93
|
+
*
|
|
94
|
+
* ```ts
|
|
95
|
+
* Random.Decimal(2, 7); // 4.56789
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @param min The minimum value (included).
|
|
99
|
+
* @param max The maximum value (excluded).
|
|
100
|
+
*
|
|
101
|
+
* @returns A random decimal value
|
|
102
|
+
*/
|
|
21
103
|
public static Decimal(min: number, max: number): number;
|
|
22
104
|
public static Decimal(min?: number, max?: number): number
|
|
23
105
|
{
|
|
@@ -27,13 +109,38 @@ export default class Random
|
|
|
27
109
|
return (Math.random() * (max - min) + min);
|
|
28
110
|
}
|
|
29
111
|
|
|
30
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Picks a random valid index from a given array of elements.
|
|
114
|
+
*
|
|
115
|
+
* @template T The type of the elements in the array.
|
|
116
|
+
*
|
|
117
|
+
* @param elements
|
|
118
|
+
* The array of elements to pick from.
|
|
119
|
+
*
|
|
120
|
+
* It must contain at least one element. Otherwise, a {@link ValueException} will be thrown.
|
|
121
|
+
*
|
|
122
|
+
* @returns A valid random index from the given array.
|
|
123
|
+
*/
|
|
124
|
+
public static Index<T>(elements: readonly T[]): number
|
|
31
125
|
{
|
|
32
126
|
if (elements.length === 0) { throw new ValueException("You must provide at least one element."); }
|
|
33
127
|
|
|
34
128
|
return this.Integer(elements.length);
|
|
35
129
|
}
|
|
36
|
-
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Picks a random element from a given array of elements.
|
|
133
|
+
*
|
|
134
|
+
* @template T The type of the elements in the array.
|
|
135
|
+
*
|
|
136
|
+
* @param elements
|
|
137
|
+
* The array of elements to pick from.
|
|
138
|
+
*
|
|
139
|
+
* It must contain at least one element. Otherwise, a {@link ValueException} will be thrown.
|
|
140
|
+
*
|
|
141
|
+
* @returns A random element from the given array.
|
|
142
|
+
*/
|
|
143
|
+
public static Choice<T>(elements: readonly T[]): T
|
|
37
144
|
{
|
|
38
145
|
return elements[Random.Index(elements)];
|
|
39
146
|
}
|
package/src/utils/string.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capitalize the first letter of a string.
|
|
3
|
+
*
|
|
4
|
+
* ```ts
|
|
5
|
+
* capitalize('hello'); // 'Hello'
|
|
6
|
+
* ```
|
|
7
|
+
*
|
|
8
|
+
* @param value The string to capitalize.
|
|
9
|
+
*
|
|
10
|
+
* @returns The capitalized string.
|
|
11
|
+
*/
|
|
1
12
|
export function capitalize(value: string): string
|
|
2
13
|
{
|
|
3
14
|
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
|
package/src/models/game-loop.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import type { Interval } from "../core/types.js";
|
|
2
|
-
import { isBrowser } from "../helpers.js";
|
|
3
|
-
|
|
4
|
-
import { FatalErrorException, RuntimeException } from "./exceptions/index.js";
|
|
5
|
-
|
|
6
|
-
export default class GameLoop
|
|
7
|
-
{
|
|
8
|
-
protected _handle?: number | Interval;
|
|
9
|
-
|
|
10
|
-
protected _startTime: number;
|
|
11
|
-
public get startTime(): number
|
|
12
|
-
{
|
|
13
|
-
return this._startTime;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
protected _isRunning: boolean;
|
|
17
|
-
public get isRunning(): boolean
|
|
18
|
-
{
|
|
19
|
-
return this._isRunning;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
public get elapsedTime(): number
|
|
23
|
-
{
|
|
24
|
-
return performance.now() - this._startTime;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
protected _start: () => void;
|
|
28
|
-
protected _stop: () => void;
|
|
29
|
-
|
|
30
|
-
public constructor(callback: FrameRequestCallback, msIfNotBrowser = 40)
|
|
31
|
-
{
|
|
32
|
-
this._startTime = 0;
|
|
33
|
-
this._isRunning = false;
|
|
34
|
-
|
|
35
|
-
if (isBrowser)
|
|
36
|
-
{
|
|
37
|
-
this._start = () =>
|
|
38
|
-
{
|
|
39
|
-
callback(this.elapsedTime);
|
|
40
|
-
|
|
41
|
-
this._handle = window.requestAnimationFrame(this._start);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
this._stop = () => window.cancelAnimationFrame(this._handle as number);
|
|
45
|
-
}
|
|
46
|
-
else
|
|
47
|
-
{
|
|
48
|
-
// eslint-disable-next-line no-console
|
|
49
|
-
console.warn(
|
|
50
|
-
"Not a browser environment detected. " +
|
|
51
|
-
`Using setInterval@${msIfNotBrowser}ms instead of requestAnimationFrame...`
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
this._start = () =>
|
|
55
|
-
{
|
|
56
|
-
this._handle = setInterval(() => callback(this.elapsedTime), msIfNotBrowser);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
this._stop = () => clearInterval(this._handle as Interval);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public start(elapsedTime = 0): void
|
|
64
|
-
{
|
|
65
|
-
if (this._isRunning) { throw new RuntimeException("The game loop has already been started."); }
|
|
66
|
-
|
|
67
|
-
this._startTime = performance.now() - elapsedTime;
|
|
68
|
-
this._start();
|
|
69
|
-
this._isRunning = true;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public stop(): void
|
|
73
|
-
{
|
|
74
|
-
if (!(this._isRunning)) { throw new RuntimeException("The game loop hadn't yet started."); }
|
|
75
|
-
if (!(this._handle)) { throw new FatalErrorException(); }
|
|
76
|
-
|
|
77
|
-
this._stop();
|
|
78
|
-
this._handle = undefined;
|
|
79
|
-
this._isRunning = false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public readonly [Symbol.toStringTag]: string = "GameLoop";
|
|
83
|
-
}
|