wuira 0.2.3 → 0.2.5
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/CHANGELOG.md +38 -0
- package/README.md +62 -792
- package/data/icons/forever.json +90051 -0
- package/docs/icons.md +28 -0
- package/docs/source-converters.md +34 -0
- package/lib/datasources/DataSource.d.ts +8 -0
- package/lib/datasources/DataSource.lua +7 -0
- package/lib/datasources/GroupMembers.d.ts +6 -0
- package/lib/datasources/GroupMembers.lua +332 -0
- package/lib/datasources/GroupRoster.d.ts +28 -0
- package/lib/datasources/GroupRoster.lua +611 -0
- package/lib/datasources/MathConverter.d.ts +6 -0
- package/lib/datasources/MathConverter.lua +61 -0
- package/lib/datasources/MathExpression.d.ts +16 -0
- package/lib/datasources/MathExpression.lua +281 -0
- package/lib/datasources/Resources.d.ts +3 -2
- package/lib/datasources/Resources.lua +57 -48
- package/lib/datasources/SourceConverter.d.ts +39 -0
- package/lib/datasources/SourceConverter.lua +568 -0
- package/lib/datasources/UnitInfo.d.ts +6 -0
- package/lib/datasources/UnitInfo.lua +347 -15
- package/lib/datasources/UnitSource.d.ts +8 -3
- package/lib/datasources/UnitSource.lua +318 -5
- package/lib/datasources/index.d.ts +7 -1
- package/lib/datasources/index.lua +15 -0
- package/lib/icons/index.d.ts +45634 -0
- package/lib/icons/index.lua +3 -0
- package/lib/index.d.ts +1 -0
- package/lib/store/index.lua +20 -18
- package/lib/ui/Cell.d.ts +2 -0
- package/lib/ui/ForEach.d.ts +18 -4
- package/lib/ui/ForEach.lua +763 -13
- package/lib/ui/index.d.ts +1 -1
- package/package.json +20 -4
- package/tools/build-library.mjs +1 -1
- package/tools/generate-icons.mjs +10 -0
- package/tools/icon-data.mjs +59 -0
- package/tools/update-icons.mjs +36 -0
package/docs/icons.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Forever icon catalog
|
|
2
|
+
|
|
3
|
+
`Icons` contains native texture **FileDataIDs** from the same verified Forever build as the spell enums. Icon identity is independent of spell or item actions.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { UI } from "wuira";
|
|
7
|
+
import { Icons } from "wuira/icons";
|
|
8
|
+
import { Icon } from "wuira/ui";
|
|
9
|
+
|
|
10
|
+
const image = <Icon width={24} height={24} texture={Icons.BlessingOfFreedom_135968} />;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Every icon has an explicit ID-suffixed member. A readable short alias is generated only when that name maps to one icon. Multiple spells or items may share the same texture; they produce one catalog entry with searchable aliases.
|
|
14
|
+
|
|
15
|
+
The snapshot combines SpellMisc spell/active icon fields with Item icon fields and ItemSparse names from the pinned client build. It covers every positive icon ID referenced by these tables, including unused records and entries without a readable name; it does not claim to list every texture or atlas in the game. No other client branch is merged into it. The names describe associated spells or items, rather than guessing asset filenames. Unnamed records receive a `Spell <id>` or `Item <id>` label.
|
|
16
|
+
|
|
17
|
+
The generated enum is erased to numeric literals by TypeScriptToLua. Editor tools can read the packaged `data/icons/forever.json` to create a searchable catalog without constructing every icon in game. A selected texture is saved as a FileDataID, not a spell ID.
|
|
18
|
+
|
|
19
|
+
Game data belongs to Blizzard Entertainment. Source URLs, row counts, build and SHA-256 hashes are recorded in the snapshot.
|
|
20
|
+
|
|
21
|
+
## Update
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm run icons:update -- --build 1.60.1.70374
|
|
25
|
+
npm run icons:generate
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Use `--cached` to regenerate the snapshot from downloaded CSVs. Updating requires the build to match `data/spells/forever.json`. Normal consumers use the committed snapshot and do not download game data during a build.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Source converters
|
|
2
|
+
|
|
3
|
+
`SourceConverter` transforms a readable source value. It consumes the input's change notifications, shares one upstream subscription across its observers, and does not create a timer or dispose the shared input. Sources without notifications remain available as checked one-time reads.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { ClassSource, SourceConverter, CaseConverter, HP, MathConverter, Unit } from "wuira/datasources";
|
|
7
|
+
|
|
8
|
+
const characterClass = new ClassSource(Unit.Player);
|
|
9
|
+
const token = new SourceConverter(characterClass, info => info?.token);
|
|
10
|
+
const color = new CaseConverter(token, [
|
|
11
|
+
{ equals: "PALADIN", value: { r: 1, g: 0.5, b: 0.7, a: 1 } },
|
|
12
|
+
{ equals: "MAGE", value: { r: 0.4, g: 0.8, b: 1, a: 1 } },
|
|
13
|
+
], { r: 0.35, g: 0.4, b: 0.45, a: 1 });
|
|
14
|
+
|
|
15
|
+
const hp = new HP(Unit.Player);
|
|
16
|
+
const doubled = new MathConverter(hp, "2 * input");
|
|
17
|
+
const stop = doubled.BindTo(value => console.log(value));
|
|
18
|
+
// On removal:
|
|
19
|
+
stop();
|
|
20
|
+
doubled.Dispose();
|
|
21
|
+
color.Dispose();
|
|
22
|
+
token.Dispose();
|
|
23
|
+
characterClass.Dispose();
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`Value` and `Compute()` are checked reads. `TryCompute()` performs one checked read and returns `{ readable: false }` for restricted data, without invoking the callback. Converter chains use it to avoid repeated leaf reads. `onChange()` observes future readable output changes; `BindTo()` also applies the current readable value immediately. Scalar outputs with the same value do not emit again. `When()` filters emissions without changing the checked `Value` getter. Call `Dispose()` when the converter is no longer owned by a component.
|
|
27
|
+
|
|
28
|
+
Cases compare strings, finite numbers and booleans with strict equality; `1` and `"1"` are different keys. Duplicate keys are rejected. Unmatched values return the supplied default, or `undefined` when none was provided. Case outputs can be colors, texture IDs, text or other data.
|
|
29
|
+
|
|
30
|
+
Math expressions support `input`, finite numeric literals, parentheses, unary signs, `+`, `-`, `*`, `/`, `%`, and exponentiation (`^` or `**`). Exponents associate to the right; `-input^2` means `-(input^2)`. The bounded parser runs once at construction. It does not evaluate JavaScript or Lua, access globals, or call functions. Invalid syntax, division by zero and non-finite results throw errors. `MathConverter.Validate(expression)` checks syntax without reading the input.
|
|
31
|
+
|
|
32
|
+
Restricted values, including nested secret fields, never reach a conversion callback. Restrictions are checked when values are consumed; combat alone does not mark a value secret. ClassSource subscriptions follow unit identity changes and relevant native events, and release those listeners when the last consumer unsubscribes.
|
|
33
|
+
|
|
34
|
+
Converters produce data. They do not grant permission to change protected buttons or their actions during combat.
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export type ReadResult<T> = {
|
|
2
|
+
readonly readable: true;
|
|
3
|
+
readonly value: T;
|
|
4
|
+
} | {
|
|
5
|
+
readonly readable: false;
|
|
6
|
+
};
|
|
1
7
|
/** A value-producing source. Secrecy describes data, not native frame protection. */
|
|
2
8
|
export declare abstract class DataSource<T> {
|
|
3
9
|
private value;
|
|
@@ -8,6 +14,8 @@ export declare abstract class DataSource<T> {
|
|
|
8
14
|
IsSecret(): boolean;
|
|
9
15
|
get Value(): T;
|
|
10
16
|
Compute<TResult>(compute: (value: T) => TResult): TResult;
|
|
17
|
+
/** One checked read, without exposing a restricted value or invoking its callback. */
|
|
18
|
+
TryCompute<TResult>(compute: (value: T) => TResult): ReadResult<TResult>;
|
|
11
19
|
protected GetValue(): T;
|
|
12
20
|
/** Filters native binding emissions; Value remains a checked, fresh snapshot. */
|
|
13
21
|
When(condition: (value: T) => boolean): this;
|
|
@@ -165,6 +165,13 @@ function DataSource.prototype.Compute(self, compute)
|
|
|
165
165
|
self:AssertReadable(value)
|
|
166
166
|
return compute(nil, value)
|
|
167
167
|
end
|
|
168
|
+
function DataSource.prototype.TryCompute(self, compute)
|
|
169
|
+
local value = self:GetValue()
|
|
170
|
+
return self:IsValueSecret(value) and ({readable = false}) or ({
|
|
171
|
+
readable = true,
|
|
172
|
+
value = compute(nil, value)
|
|
173
|
+
})
|
|
174
|
+
end
|
|
168
175
|
function DataSource.prototype.GetValue(self)
|
|
169
176
|
return self.value
|
|
170
177
|
end
|
|
@@ -4,7 +4,13 @@ export type GroupScope = "auto" | "party" | "raid";
|
|
|
4
4
|
export declare class GroupMembers extends DataSource<readonly string[]> {
|
|
5
5
|
readonly scope: GroupScope;
|
|
6
6
|
private restricted;
|
|
7
|
+
private readonly listeners;
|
|
8
|
+
private frame?;
|
|
7
9
|
constructor(scope?: GroupScope);
|
|
10
|
+
/** Roster/connection events, with one listener frame while observed. No polling. */
|
|
11
|
+
onChange(listener: (units: readonly string[]) => void): () => void;
|
|
12
|
+
private StopListening;
|
|
13
|
+
Dispose(): void;
|
|
8
14
|
protected HasSecretFields(): boolean;
|
|
9
15
|
protected GetValue(): readonly string[];
|
|
10
16
|
}
|
|
@@ -32,6 +32,284 @@ local function __TS__ClassExtends(target, base)
|
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
local __TS__Symbol, Symbol
|
|
36
|
+
do
|
|
37
|
+
local symbolMetatable = {__tostring = function(self)
|
|
38
|
+
return ("Symbol(" .. (self.description or "")) .. ")"
|
|
39
|
+
end}
|
|
40
|
+
function __TS__Symbol(description)
|
|
41
|
+
return setmetatable({description = description}, symbolMetatable)
|
|
42
|
+
end
|
|
43
|
+
Symbol = {
|
|
44
|
+
asyncDispose = __TS__Symbol("Symbol.asyncDispose"),
|
|
45
|
+
dispose = __TS__Symbol("Symbol.dispose"),
|
|
46
|
+
iterator = __TS__Symbol("Symbol.iterator"),
|
|
47
|
+
hasInstance = __TS__Symbol("Symbol.hasInstance"),
|
|
48
|
+
species = __TS__Symbol("Symbol.species"),
|
|
49
|
+
toStringTag = __TS__Symbol("Symbol.toStringTag")
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
local __TS__Iterator
|
|
54
|
+
do
|
|
55
|
+
local function iteratorGeneratorStep(self)
|
|
56
|
+
local co = self.____coroutine
|
|
57
|
+
local status, value = coroutine.resume(co)
|
|
58
|
+
if not status then
|
|
59
|
+
error(value, 0)
|
|
60
|
+
end
|
|
61
|
+
if coroutine.status(co) == "dead" then
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
return true, value
|
|
65
|
+
end
|
|
66
|
+
local function iteratorIteratorStep(self)
|
|
67
|
+
local result = self:next()
|
|
68
|
+
if result.done then
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
return true, result.value
|
|
72
|
+
end
|
|
73
|
+
local function iteratorStringStep(self, index)
|
|
74
|
+
index = index + 1
|
|
75
|
+
if index > #self then
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
return index, string.sub(self, index, index)
|
|
79
|
+
end
|
|
80
|
+
function __TS__Iterator(iterable)
|
|
81
|
+
if type(iterable) == "string" then
|
|
82
|
+
return iteratorStringStep, iterable, 0
|
|
83
|
+
elseif iterable.____coroutine ~= nil then
|
|
84
|
+
return iteratorGeneratorStep, iterable
|
|
85
|
+
elseif iterable[Symbol.iterator] then
|
|
86
|
+
local iterator = iterable[Symbol.iterator](iterable)
|
|
87
|
+
return iteratorIteratorStep, iterator
|
|
88
|
+
else
|
|
89
|
+
return ipairs(iterable)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
local function __TS__New(target, ...)
|
|
95
|
+
local instance = setmetatable({}, target.prototype)
|
|
96
|
+
instance:____constructor(...)
|
|
97
|
+
return instance
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
local Set
|
|
101
|
+
do
|
|
102
|
+
Set = __TS__Class()
|
|
103
|
+
Set.name = "Set"
|
|
104
|
+
function Set.prototype.____constructor(self, values)
|
|
105
|
+
self[Symbol.toStringTag] = "Set"
|
|
106
|
+
self.size = 0
|
|
107
|
+
self.nextKey = {}
|
|
108
|
+
self.previousKey = {}
|
|
109
|
+
if values == nil then
|
|
110
|
+
return
|
|
111
|
+
end
|
|
112
|
+
local iterable = values
|
|
113
|
+
if iterable[Symbol.iterator] then
|
|
114
|
+
local iterator = iterable[Symbol.iterator](iterable)
|
|
115
|
+
while true do
|
|
116
|
+
local result = iterator:next()
|
|
117
|
+
if result.done then
|
|
118
|
+
break
|
|
119
|
+
end
|
|
120
|
+
self:add(result.value)
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
local array = values
|
|
124
|
+
for ____, value in ipairs(array) do
|
|
125
|
+
self:add(value)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
function Set.prototype.add(self, value)
|
|
130
|
+
local isNewValue = not self:has(value)
|
|
131
|
+
if isNewValue then
|
|
132
|
+
self.size = self.size + 1
|
|
133
|
+
end
|
|
134
|
+
if self.firstKey == nil then
|
|
135
|
+
self.firstKey = value
|
|
136
|
+
self.lastKey = value
|
|
137
|
+
elseif isNewValue then
|
|
138
|
+
self.nextKey[self.lastKey] = value
|
|
139
|
+
self.previousKey[value] = self.lastKey
|
|
140
|
+
self.lastKey = value
|
|
141
|
+
end
|
|
142
|
+
return self
|
|
143
|
+
end
|
|
144
|
+
function Set.prototype.clear(self)
|
|
145
|
+
self.nextKey = {}
|
|
146
|
+
self.previousKey = {}
|
|
147
|
+
self.firstKey = nil
|
|
148
|
+
self.lastKey = nil
|
|
149
|
+
self.size = 0
|
|
150
|
+
end
|
|
151
|
+
function Set.prototype.delete(self, value)
|
|
152
|
+
local contains = self:has(value)
|
|
153
|
+
if contains then
|
|
154
|
+
self.size = self.size - 1
|
|
155
|
+
local next = self.nextKey[value]
|
|
156
|
+
local previous = self.previousKey[value]
|
|
157
|
+
if next ~= nil and previous ~= nil then
|
|
158
|
+
self.nextKey[previous] = next
|
|
159
|
+
self.previousKey[next] = previous
|
|
160
|
+
elseif next ~= nil then
|
|
161
|
+
self.firstKey = next
|
|
162
|
+
self.previousKey[next] = nil
|
|
163
|
+
elseif previous ~= nil then
|
|
164
|
+
self.lastKey = previous
|
|
165
|
+
self.nextKey[previous] = nil
|
|
166
|
+
else
|
|
167
|
+
self.firstKey = nil
|
|
168
|
+
self.lastKey = nil
|
|
169
|
+
end
|
|
170
|
+
self.nextKey[value] = nil
|
|
171
|
+
self.previousKey[value] = nil
|
|
172
|
+
end
|
|
173
|
+
return contains
|
|
174
|
+
end
|
|
175
|
+
function Set.prototype.forEach(self, callback)
|
|
176
|
+
for ____, key in __TS__Iterator(self:keys()) do
|
|
177
|
+
callback(nil, key, key, self)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
function Set.prototype.has(self, value)
|
|
181
|
+
return self.nextKey[value] ~= nil or self.lastKey == value
|
|
182
|
+
end
|
|
183
|
+
Set.prototype[Symbol.iterator] = function(self)
|
|
184
|
+
return self:values()
|
|
185
|
+
end
|
|
186
|
+
function Set.prototype.entries(self)
|
|
187
|
+
local function getFirstKey()
|
|
188
|
+
return self.firstKey
|
|
189
|
+
end
|
|
190
|
+
local nextKey = self.nextKey
|
|
191
|
+
local key
|
|
192
|
+
local started = false
|
|
193
|
+
return {
|
|
194
|
+
[Symbol.iterator] = function(self)
|
|
195
|
+
return self
|
|
196
|
+
end,
|
|
197
|
+
next = function(self)
|
|
198
|
+
if not started then
|
|
199
|
+
started = true
|
|
200
|
+
key = getFirstKey(nil)
|
|
201
|
+
else
|
|
202
|
+
key = nextKey[key]
|
|
203
|
+
end
|
|
204
|
+
return {done = not key, value = {key, key}}
|
|
205
|
+
end
|
|
206
|
+
}
|
|
207
|
+
end
|
|
208
|
+
function Set.prototype.keys(self)
|
|
209
|
+
local function getFirstKey()
|
|
210
|
+
return self.firstKey
|
|
211
|
+
end
|
|
212
|
+
local nextKey = self.nextKey
|
|
213
|
+
local key
|
|
214
|
+
local started = false
|
|
215
|
+
return {
|
|
216
|
+
[Symbol.iterator] = function(self)
|
|
217
|
+
return self
|
|
218
|
+
end,
|
|
219
|
+
next = function(self)
|
|
220
|
+
if not started then
|
|
221
|
+
started = true
|
|
222
|
+
key = getFirstKey(nil)
|
|
223
|
+
else
|
|
224
|
+
key = nextKey[key]
|
|
225
|
+
end
|
|
226
|
+
return {done = not key, value = key}
|
|
227
|
+
end
|
|
228
|
+
}
|
|
229
|
+
end
|
|
230
|
+
function Set.prototype.values(self)
|
|
231
|
+
local function getFirstKey()
|
|
232
|
+
return self.firstKey
|
|
233
|
+
end
|
|
234
|
+
local nextKey = self.nextKey
|
|
235
|
+
local key
|
|
236
|
+
local started = false
|
|
237
|
+
return {
|
|
238
|
+
[Symbol.iterator] = function(self)
|
|
239
|
+
return self
|
|
240
|
+
end,
|
|
241
|
+
next = function(self)
|
|
242
|
+
if not started then
|
|
243
|
+
started = true
|
|
244
|
+
key = getFirstKey(nil)
|
|
245
|
+
else
|
|
246
|
+
key = nextKey[key]
|
|
247
|
+
end
|
|
248
|
+
return {done = not key, value = key}
|
|
249
|
+
end
|
|
250
|
+
}
|
|
251
|
+
end
|
|
252
|
+
function Set.prototype.union(self, other)
|
|
253
|
+
local result = __TS__New(Set, self)
|
|
254
|
+
for ____, item in __TS__Iterator(other) do
|
|
255
|
+
result:add(item)
|
|
256
|
+
end
|
|
257
|
+
return result
|
|
258
|
+
end
|
|
259
|
+
function Set.prototype.intersection(self, other)
|
|
260
|
+
local result = __TS__New(Set)
|
|
261
|
+
for ____, item in __TS__Iterator(self) do
|
|
262
|
+
if other:has(item) then
|
|
263
|
+
result:add(item)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
return result
|
|
267
|
+
end
|
|
268
|
+
function Set.prototype.difference(self, other)
|
|
269
|
+
local result = __TS__New(Set, self)
|
|
270
|
+
for ____, item in __TS__Iterator(other) do
|
|
271
|
+
result:delete(item)
|
|
272
|
+
end
|
|
273
|
+
return result
|
|
274
|
+
end
|
|
275
|
+
function Set.prototype.symmetricDifference(self, other)
|
|
276
|
+
local result = __TS__New(Set, self)
|
|
277
|
+
for ____, item in __TS__Iterator(other) do
|
|
278
|
+
if self:has(item) then
|
|
279
|
+
result:delete(item)
|
|
280
|
+
else
|
|
281
|
+
result:add(item)
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
return result
|
|
285
|
+
end
|
|
286
|
+
function Set.prototype.isSubsetOf(self, other)
|
|
287
|
+
for ____, item in __TS__Iterator(self) do
|
|
288
|
+
if not other:has(item) then
|
|
289
|
+
return false
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
return true
|
|
293
|
+
end
|
|
294
|
+
function Set.prototype.isSupersetOf(self, other)
|
|
295
|
+
for ____, item in __TS__Iterator(other) do
|
|
296
|
+
if not self:has(item) then
|
|
297
|
+
return false
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
return true
|
|
301
|
+
end
|
|
302
|
+
function Set.prototype.isDisjointFrom(self, other)
|
|
303
|
+
for ____, item in __TS__Iterator(self) do
|
|
304
|
+
if other:has(item) then
|
|
305
|
+
return false
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
return true
|
|
309
|
+
end
|
|
310
|
+
Set[Symbol.species] = Set
|
|
311
|
+
end
|
|
312
|
+
|
|
35
313
|
local function __TS__NumberIsFinite(value)
|
|
36
314
|
return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge
|
|
37
315
|
end
|
|
@@ -55,6 +333,60 @@ function GroupMembers.prototype.____constructor(self, scope)
|
|
|
55
333
|
DataSource.prototype.____constructor(self, {})
|
|
56
334
|
self.scope = scope
|
|
57
335
|
self.restricted = false
|
|
336
|
+
self.listeners = __TS__New(Set)
|
|
337
|
+
end
|
|
338
|
+
function GroupMembers.prototype.onChange(self, listener)
|
|
339
|
+
self.listeners:add(listener)
|
|
340
|
+
if self.listeners.size == 1 then
|
|
341
|
+
if self.frame == nil then
|
|
342
|
+
self.frame = CreateFrame("Frame", nil, UIParent)
|
|
343
|
+
end
|
|
344
|
+
for ____, event in ipairs({
|
|
345
|
+
"GROUP_ROSTER_UPDATE",
|
|
346
|
+
"UNIT_PET",
|
|
347
|
+
"UNIT_CONNECTION",
|
|
348
|
+
"UNIT_NAME_UPDATE",
|
|
349
|
+
"PLAYER_ENTERING_WORLD"
|
|
350
|
+
}) do
|
|
351
|
+
self.frame:RegisterEvent(event)
|
|
352
|
+
end
|
|
353
|
+
self.frame:SetScript(
|
|
354
|
+
"OnEvent",
|
|
355
|
+
function()
|
|
356
|
+
local units = self:GetValue()
|
|
357
|
+
if self.restricted then
|
|
358
|
+
return
|
|
359
|
+
end
|
|
360
|
+
for ____, callback in __TS__Iterator(self.listeners) do
|
|
361
|
+
callback(nil, units)
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
)
|
|
365
|
+
end
|
|
366
|
+
return function()
|
|
367
|
+
self.listeners:delete(listener)
|
|
368
|
+
if self.listeners.size == 0 then
|
|
369
|
+
self:StopListening()
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
function GroupMembers.prototype.StopListening(self)
|
|
374
|
+
local ____opt_0 = self.frame
|
|
375
|
+
if ____opt_0 ~= nil then
|
|
376
|
+
____opt_0:UnregisterAllEvents()
|
|
377
|
+
end
|
|
378
|
+
local ____opt_2 = self.frame
|
|
379
|
+
if ____opt_2 ~= nil then
|
|
380
|
+
____opt_2:SetScript("OnEvent", nil)
|
|
381
|
+
end
|
|
382
|
+
local ____opt_4 = self.frame
|
|
383
|
+
if ____opt_4 ~= nil then
|
|
384
|
+
____opt_4:Hide()
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
function GroupMembers.prototype.Dispose(self)
|
|
388
|
+
self.listeners:clear()
|
|
389
|
+
self:StopListening()
|
|
58
390
|
end
|
|
59
391
|
function GroupMembers.prototype.HasSecretFields(self)
|
|
60
392
|
return self.restricted
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DataSource } from "./DataSource";
|
|
2
|
+
import type { GroupScope } from "./GroupMembers";
|
|
3
|
+
export interface GroupRosterMember {
|
|
4
|
+
readonly key: string;
|
|
5
|
+
readonly guid?: string;
|
|
6
|
+
readonly unit: string;
|
|
7
|
+
readonly pet: boolean;
|
|
8
|
+
readonly group: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getPetUnitToken(unit: string): string;
|
|
11
|
+
/** Small snapshots describe identity/order only; keyed rendering owns widgets and unit sources. */
|
|
12
|
+
export declare class GroupRoster extends DataSource<readonly GroupRosterMember[]> {
|
|
13
|
+
private readonly scope;
|
|
14
|
+
private readonly options;
|
|
15
|
+
private readonly roster;
|
|
16
|
+
private readonly knownNames;
|
|
17
|
+
private snapshot;
|
|
18
|
+
private restricted;
|
|
19
|
+
get Status(): "ready" | "restricted";
|
|
20
|
+
constructor(scope?: GroupScope, options?: {
|
|
21
|
+
pets?: boolean;
|
|
22
|
+
includeSelfWhenSolo?: boolean;
|
|
23
|
+
});
|
|
24
|
+
protected GetValue(): readonly GroupRosterMember[];
|
|
25
|
+
private Read;
|
|
26
|
+
onChange(listener: (members: readonly GroupRosterMember[]) => void): () => void;
|
|
27
|
+
Dispose(): void;
|
|
28
|
+
}
|