wuira 0.2.6 → 0.2.8
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 +26 -0
- package/README.md +24 -1
- package/docs/nameplates.md +89 -0
- package/lib/WuiraApp.lua +42 -6
- package/lib/datasources/UnitSource.d.ts +5 -0
- package/lib/datasources/UnitSource.lua +47 -3
- package/lib/index.d.ts +2 -0
- package/lib/index.lua +6 -0
- package/lib/platform/forever.d.ts +3 -0
- package/lib/skins/Nameplates.d.ts +56 -0
- package/lib/skins/Nameplates.lua +1119 -0
- package/lib/skins/index.d.ts +2 -0
- package/lib/skins/index.lua +6 -0
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ with the release date and highlight breaking changes explicitly.
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.2.8 — 2026-10-17
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `UnitSource("target").onChange` invalidates on `PLAYER_TARGET_CHANGED`, including
|
|
15
|
+
combat and target removal, without reading secret identities or notifying other
|
|
16
|
+
unit sources. Event subscriptions stop with the last consumer.
|
|
17
|
+
- Add `onTokenChange` for secure consumers that should only rewrite bindings after
|
|
18
|
+
an explicit `Retarget`, not when a stable target address points to another unit.
|
|
19
|
+
|
|
20
|
+
## 0.2.7 — 2026-10-16
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Generic `Nameplates.Apply` / `Replace` registration groups, with global first-match
|
|
25
|
+
precedence, fresh per-unit JSX factories, reversible native visual helpers,
|
|
26
|
+
event-driven pooled-frame lifecycle, explicit refresh, and independent disposal.
|
|
27
|
+
Forbidden/protected frames and secret identities are skipped; secure JSX is rejected.
|
|
28
|
+
- Lua integration coverage for nameplate reuse, rule conflicts, rollback, native
|
|
29
|
+
restoration and HP subscription cleanup. These are mock tests, not in-game validation.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Continue unmount cleanup after a binding or decoration disposer throws, so remaining
|
|
34
|
+
subscriptions and frames are released before the first error is reported.
|
|
35
|
+
|
|
10
36
|
## 0.2.6 — 2026-10-16
|
|
11
37
|
|
|
12
38
|
### Changed
|
package/README.md
CHANGED
|
@@ -76,6 +76,29 @@ Other sources include `AuraTimer`, `GlobalCooldown`, `CastTimer`, `SpellCooldown
|
|
|
76
76
|
|
|
77
77
|
Supported action types: `spell`, `item`, `macro`, `action`, and `target`. Actions and units are static mount-time attributes. Protected trees cannot be mounted during combat.
|
|
78
78
|
|
|
79
|
+
## Nameplates
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { Nameplates, UI } from "wuira";
|
|
83
|
+
import { HP } from "wuira/datasources";
|
|
84
|
+
|
|
85
|
+
const plates = Nameplates
|
|
86
|
+
.Apply(p => p.GUID === configuredGUID, p => {
|
|
87
|
+
if (p.Native.healthBar) p.Size(p.Native.healthBar, 140, 12);
|
|
88
|
+
})
|
|
89
|
+
.Replace(() => true, p => (
|
|
90
|
+
<progress width={140} height={12} source={new HP(p.Unit)} />
|
|
91
|
+
));
|
|
92
|
+
|
|
93
|
+
// plates.Dispose();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The first matching rule wins across Apply and Replace; they do not stack.
|
|
97
|
+
Each factory creates fresh JSX for its unit. Use `Nameplates.Create()` with
|
|
98
|
+
`collection.forEach(...)` to register presets, and `Refresh()` after preset changes.
|
|
99
|
+
See [nameplate lifecycle and cleanup](docs/nameplates.md). Secure nameplate controls
|
|
100
|
+
require a separate lifecycle and are not supported by this visual API.
|
|
101
|
+
|
|
79
102
|
## Stores
|
|
80
103
|
|
|
81
104
|
```ts
|
|
@@ -118,7 +141,7 @@ For global installation, use `npm install -g wuira`. To test unpublished changes
|
|
|
118
141
|
|
|
119
142
|
wuira is an early framework. It is not a complete UI replacement, an in-game visual editor, or a WeakAuras replacement. JSX describes widgets; there is no React runtime or automatic reactive rendering layer. Combat restrictions and secret-value rules still apply and cannot be bypassed by the framework.
|
|
120
143
|
|
|
121
|
-
Current core includes Cells,
|
|
144
|
+
Current core includes Cells, layouts, progress bars, decorations, unit sources, native nameplate adapters, and project tooling. Not yet implemented: a complete WoW API surface, nameplate click-cast abstractions, and preset management. Nameplate lifecycle tests use a mock Lua runtime; real-client validation is still required.
|
|
122
145
|
|
|
123
146
|
The target client is WoW Forever. Compatibility with Retail or other Classic clients is not promised without verification.
|
|
124
147
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Nameplates
|
|
2
|
+
|
|
3
|
+
Import `Nameplates` from `wuira` or `wuira/skins`. Wuira owns native access,
|
|
4
|
+
events, unit bindings and visual cleanup. Preset selection, NPC rules, editor
|
|
5
|
+
data and component collections belong to the consuming addon (for example LumaUI).
|
|
6
|
+
No class or mob presets are built into Wuira.
|
|
7
|
+
|
|
8
|
+
`NativeSkin` remains the adapter for fixed named frames. Nameplates use a separate
|
|
9
|
+
event-driven manager because both carriers and unit visuals are dynamically pooled.
|
|
10
|
+
|
|
11
|
+
## Rules and ownership
|
|
12
|
+
|
|
13
|
+
`Nameplates.Apply(selector, customize)` and `Nameplates.Replace(selector, render)`
|
|
14
|
+
start independent groups. Chained calls append to that same group. `Nameplates.Create()`
|
|
15
|
+
starts an empty group, useful for collections:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
const plates = Nameplates.Create();
|
|
19
|
+
collection.forEach(component => {
|
|
20
|
+
plates.Replace(p => component.matches(p.Unit, p.GUID), p => component.render(p));
|
|
21
|
+
});
|
|
22
|
+
// When preset data changes:
|
|
23
|
+
plates.Refresh();
|
|
24
|
+
// On addon feature shutdown:
|
|
25
|
+
plates.Dispose();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Rules are ordered by registration time across all groups. **The first matching
|
|
29
|
+
rule wins, regardless of whether it is Apply or Replace.** Apply rules do not
|
|
30
|
+
accumulate before/after a replacement. Put specific rules before fallbacks.
|
|
31
|
+
Disposing a losing group leaves the winning binding intact. Disposing a winning
|
|
32
|
+
group restores its changes and then activates the next matching rule, if any.
|
|
33
|
+
Dispose is idempotent; adding rules to a disposed group is an error.
|
|
34
|
+
|
|
35
|
+
Selectors receive `Unit`, public `GUID`, engine-owned `Frame`, and native visual
|
|
36
|
+
`Native` (with optional `healthBar` / `castBar`). Restricted identities/frames
|
|
37
|
+
never reach selectors. A selector error or secret result leaves the plate native;
|
|
38
|
+
it does not activate a less specific fallback. Callback errors go to WoW's error
|
|
39
|
+
handler. A failing winner is retried on refresh or the next relevant native event.
|
|
40
|
+
Callbacks must not add/dispose/refresh groups while reconciliation is running.
|
|
41
|
+
|
|
42
|
+
## Apply
|
|
43
|
+
|
|
44
|
+
Apply reuses Blizzard's visuals and bars. The context exposes reversible
|
|
45
|
+
`Alpha(frame, value)`, `Scale(frame, value)`, `Size(frame, width, height)`, and
|
|
46
|
+
`BarColor(bar, r, g, b, a?)`. These accept the native visual or its accessible,
|
|
47
|
+
unprotected descendants; the engine-owned carrier is excluded.
|
|
48
|
+
|
|
49
|
+
Cleanup restores a property only if it still equals the value this binding wrote,
|
|
50
|
+
so a later external write is preserved. Blizzard or another addon can overwrite
|
|
51
|
+
Apply styling; it is reapplied on relevant identity/faction/target/world events or
|
|
52
|
+
explicit refresh, rather than continuously polled. Direct native writes through
|
|
53
|
+
`Frame`/`Native` are outside rollback ownership and should be avoided.
|
|
54
|
+
|
|
55
|
+
Register each owned subscription immediately with `p.OnDispose(stop)` before
|
|
56
|
+
doing more work that could throw. Disposers run in reverse order, and a failing
|
|
57
|
+
disposer cannot prevent the remaining cleanup operations.
|
|
58
|
+
|
|
59
|
+
## Replace
|
|
60
|
+
|
|
61
|
+
Replace mounts the factory's fresh visual JSX under the native carrier, centered
|
|
62
|
+
on it, and suppresses native UnitFrame alpha only after mounting succeeds. It
|
|
63
|
+
keeps native scripts and events registered. A dormant hook per pooled UnitFrame
|
|
64
|
+
maintains suppression and remembers subsequent public native alpha writes for
|
|
65
|
+
restoration. This does not arbitrate competing nameplate addons that also hide,
|
|
66
|
+
reparent or replace native visuals.
|
|
67
|
+
|
|
68
|
+
Factories run per unit binding. Do not return one cached JSX instance for several
|
|
69
|
+
plates: mounting rejects simultaneous reuse. Bind sources inside the factory,
|
|
70
|
+
for example `new HP(p.Unit)`; mounting owns their widget subscriptions. Register
|
|
71
|
+
additional manual subscriptions through `OnDispose`.
|
|
72
|
+
|
|
73
|
+
Nameplate add/remove events, GUID changes and reuse of either carrier or UnitFrame
|
|
74
|
+
dispose the previous binding before a fresh factory runs. Already visible plates
|
|
75
|
+
are discovered on registration and world entry. Name/faction/target events and
|
|
76
|
+
`Refresh()` reevaluate selection and visuals. Health events are handled by data
|
|
77
|
+
sources, without polling selectors. Refresh also rebuilds matching views so edited
|
|
78
|
+
preset values take effect. Protected/forbidden frames and secret GUIDs are skipped.
|
|
79
|
+
|
|
80
|
+
Native positioning, movement, click bounds and ordinary targeting stay with the
|
|
81
|
+
engine. This API does not resize the carrier or alter native click areas. Ordinary
|
|
82
|
+
unprotected visuals can mount/unmount during combat. Secure JSX is rejected,
|
|
83
|
+
including outside combat: secure nameplate buttons need a separate design for
|
|
84
|
+
combat-time creation, positioning and correct targeting. Fixed arena secure cells
|
|
85
|
+
do not establish that dynamic nameplate buttons are safe.
|
|
86
|
+
|
|
87
|
+
The Lua integration tests exercise the compiled framework with mock WoW APIs,
|
|
88
|
+
including actual HP source subscription cleanup and mounting failures. They do
|
|
89
|
+
not establish real-client behavior or compatibility with other nameplate addons.
|
package/lib/WuiraApp.lua
CHANGED
|
@@ -372,22 +372,58 @@ function WuiraApp.prototype.Unmount(self, frame)
|
|
|
372
372
|
tree.pendingUnmount = true
|
|
373
373
|
return
|
|
374
374
|
end
|
|
375
|
+
local failed = false
|
|
376
|
+
local failure
|
|
377
|
+
local function attempt(____, action)
|
|
378
|
+
do
|
|
379
|
+
local function ____catch(caught)
|
|
380
|
+
if not failed then
|
|
381
|
+
failed = true
|
|
382
|
+
failure = caught
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
local ____try, ____hasReturned = pcall(function()
|
|
386
|
+
action(nil)
|
|
387
|
+
end)
|
|
388
|
+
if not ____try then
|
|
389
|
+
____catch(____hasReturned)
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
375
393
|
for ____, dispose in ipairs(tree.bindings) do
|
|
376
|
-
|
|
394
|
+
attempt(nil, dispose)
|
|
377
395
|
end
|
|
378
396
|
for ____, decoration in ipairs(tree.decorations) do
|
|
379
|
-
|
|
397
|
+
attempt(
|
|
398
|
+
nil,
|
|
399
|
+
function() return decoration:dispose() end
|
|
400
|
+
)
|
|
380
401
|
end
|
|
381
402
|
for ____, child in ipairs(tree.frames) do
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
403
|
+
attempt(
|
|
404
|
+
nil,
|
|
405
|
+
function() return child:UnregisterAllEvents() end
|
|
406
|
+
)
|
|
407
|
+
attempt(
|
|
408
|
+
nil,
|
|
409
|
+
function() return child:SetScript("OnEvent", nil) end
|
|
410
|
+
)
|
|
411
|
+
attempt(
|
|
412
|
+
nil,
|
|
413
|
+
function() return child:SetScript("OnUpdate", nil) end
|
|
414
|
+
)
|
|
415
|
+
attempt(
|
|
416
|
+
nil,
|
|
417
|
+
function() return child:Hide() end
|
|
418
|
+
)
|
|
386
419
|
end
|
|
387
420
|
for ____, cell in ipairs(tree.cells) do
|
|
388
421
|
self.mountedFrames:delete(cell.props)
|
|
389
422
|
end
|
|
390
423
|
self.mountedTrees:delete(frame)
|
|
424
|
+
if failed then
|
|
425
|
+
error(failure, 0)
|
|
426
|
+
end
|
|
391
427
|
end
|
|
392
428
|
function WuiraApp.prototype.Protect(self, root, tree)
|
|
393
429
|
local ____temp_8 = not tree.protected
|
|
@@ -20,11 +20,16 @@ export declare class UnitSource extends DataSource<UnitIdentity | undefined> {
|
|
|
20
20
|
readonly Is: UnitPredicates;
|
|
21
21
|
private restricted;
|
|
22
22
|
private readonly listeners;
|
|
23
|
+
private readonly tokenListeners;
|
|
24
|
+
private events?;
|
|
23
25
|
constructor(token: string);
|
|
24
26
|
get Token(): string;
|
|
25
27
|
/** Keep source objects/subscriptions while a stable identity moves to another unit slot. */
|
|
26
28
|
Retarget(token: string): void;
|
|
29
|
+
/** Secure consumers only need notification when the actual unit address changes. */
|
|
30
|
+
onTokenChange(listener: () => void): () => void;
|
|
27
31
|
onChange(listener: () => void): () => void;
|
|
32
|
+
private UpdateEvents;
|
|
28
33
|
protected HasSecretFields(): boolean;
|
|
29
34
|
protected GetValue(): UnitIdentity | undefined;
|
|
30
35
|
}
|
|
@@ -506,32 +506,76 @@ function UnitSource.prototype.____constructor(self, token)
|
|
|
506
506
|
self.token = token
|
|
507
507
|
self.restricted = false
|
|
508
508
|
self.listeners = __TS__New(Set)
|
|
509
|
+
self.tokenListeners = __TS__New(Set)
|
|
509
510
|
self.Is = __TS__New(
|
|
510
511
|
____exports.UnitPredicates,
|
|
511
512
|
function() return self.Token end
|
|
512
513
|
)
|
|
513
514
|
end
|
|
514
515
|
function UnitSource.prototype.Retarget(self, token)
|
|
516
|
+
if issecretvalue(token) or type(token) ~= "string" or __TS__StringTrim(token) == "" then
|
|
517
|
+
error("UnitSource: expected a public unit token")
|
|
518
|
+
end
|
|
515
519
|
if token == self.token then
|
|
516
520
|
return
|
|
517
521
|
end
|
|
518
522
|
if InCombatLockdown() then
|
|
519
523
|
error("UnitSource: retarget after combat so secure actions and displayed data stay aligned")
|
|
520
524
|
end
|
|
521
|
-
if issecretvalue(token) or type(token) ~= "string" or __TS__StringTrim(token) == "" then
|
|
522
|
-
error("UnitSource: expected a public unit token")
|
|
523
|
-
end
|
|
524
525
|
self.token = token
|
|
526
|
+
self:UpdateEvents()
|
|
527
|
+
for ____, listener in __TS__Iterator(self.tokenListeners) do
|
|
528
|
+
listener(nil)
|
|
529
|
+
end
|
|
525
530
|
for ____, listener in __TS__Iterator(self.listeners) do
|
|
526
531
|
listener(nil)
|
|
527
532
|
end
|
|
528
533
|
end
|
|
534
|
+
function UnitSource.prototype.onTokenChange(self, listener)
|
|
535
|
+
self.tokenListeners:add(listener)
|
|
536
|
+
return function()
|
|
537
|
+
self.tokenListeners:delete(listener)
|
|
538
|
+
end
|
|
539
|
+
end
|
|
529
540
|
function UnitSource.prototype.onChange(self, listener)
|
|
530
541
|
self.listeners:add(listener)
|
|
542
|
+
self:UpdateEvents()
|
|
531
543
|
return function()
|
|
532
544
|
self.listeners:delete(listener)
|
|
545
|
+
self:UpdateEvents()
|
|
533
546
|
end
|
|
534
547
|
end
|
|
548
|
+
function UnitSource.prototype.UpdateEvents(self)
|
|
549
|
+
local ____opt_2 = self.events
|
|
550
|
+
if ____opt_2 ~= nil then
|
|
551
|
+
____opt_2:UnregisterAllEvents()
|
|
552
|
+
end
|
|
553
|
+
if self.listeners.size == 0 or self.token ~= "target" then
|
|
554
|
+
local ____opt_4 = self.events
|
|
555
|
+
if ____opt_4 ~= nil then
|
|
556
|
+
____opt_4:SetScript("OnEvent", nil)
|
|
557
|
+
end
|
|
558
|
+
local ____opt_6 = self.events
|
|
559
|
+
if ____opt_6 ~= nil then
|
|
560
|
+
____opt_6:Hide()
|
|
561
|
+
end
|
|
562
|
+
self.events = nil
|
|
563
|
+
return
|
|
564
|
+
end
|
|
565
|
+
if self.events == nil then
|
|
566
|
+
self.events = CreateFrame("Frame", nil, UIParent)
|
|
567
|
+
end
|
|
568
|
+
local frame = self.events
|
|
569
|
+
frame:RegisterEvent("PLAYER_TARGET_CHANGED")
|
|
570
|
+
frame:SetScript(
|
|
571
|
+
"OnEvent",
|
|
572
|
+
function()
|
|
573
|
+
for ____, listener in __TS__Iterator(self.listeners) do
|
|
574
|
+
listener(nil)
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
)
|
|
578
|
+
end
|
|
535
579
|
function UnitSource.prototype.HasSecretFields(self)
|
|
536
580
|
return self.restricted
|
|
537
581
|
end
|
package/lib/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export { UI } from "./ui/primitives/jsx";
|
|
|
16
16
|
export { HoverTracker } from "./ui/HoverTracker";
|
|
17
17
|
export type { HoverTrackerOptions, HoverFrame } from "./ui/HoverTracker";
|
|
18
18
|
export { MicroBar } from "./skins/MicroBar";
|
|
19
|
+
export { Nameplates, NameplateRules, NameplateContext } from "./skins/Nameplates";
|
|
20
|
+
export type { NameplateInfo, NameplateSelector, NameplateCustomize, NameplateRender, NativeNameplate, NativeNameplateVisual } from "./skins/Nameplates";
|
|
19
21
|
export type { Element, Component } from "./ui/primitives/jsx";
|
|
20
22
|
export type { Cell } from "./ui/Cell";
|
|
21
23
|
export { Store, StoreRegistry } from "./store/index";
|
package/lib/index.lua
CHANGED
|
@@ -38,6 +38,12 @@ do
|
|
|
38
38
|
local ____MicroBar = require("skins.MicroBar")
|
|
39
39
|
____exports.MicroBar = ____MicroBar.MicroBar
|
|
40
40
|
end
|
|
41
|
+
do
|
|
42
|
+
local ____Nameplates = require("skins.Nameplates")
|
|
43
|
+
____exports.Nameplates = ____Nameplates.Nameplates
|
|
44
|
+
____exports.NameplateRules = ____Nameplates.NameplateRules
|
|
45
|
+
____exports.NameplateContext = ____Nameplates.NameplateContext
|
|
46
|
+
end
|
|
41
47
|
do
|
|
42
48
|
local ____index = require("store.index")
|
|
43
49
|
____exports.Store = ____index.Store
|
|
@@ -35,6 +35,8 @@ interface wuiraNativeFrame {
|
|
|
35
35
|
SetScript(script: "OnMouseWheel", handler: ((this: void, frame: wuiraNativeFrame, delta: number) => void) | undefined): void;
|
|
36
36
|
GetName(): string | undefined;
|
|
37
37
|
IsProtected?(): boolean;
|
|
38
|
+
IsForbidden?(): boolean;
|
|
39
|
+
GetAlpha(): number;
|
|
38
40
|
GetParent(): wuiraNativeFrame;
|
|
39
41
|
GetNumPoints(): number;
|
|
40
42
|
GetPoint(index: number): wuiraNativeReturns<[wuiraAnchor, wuiraNativeFrame, wuiraAnchor, number, number]>;
|
|
@@ -95,6 +97,7 @@ declare const UIParent: wuiraNativeFrame;
|
|
|
95
97
|
declare const _G: Record<string, unknown>;
|
|
96
98
|
declare const SlashCmdList: Record<string, (this: void, message: string) => void>;
|
|
97
99
|
interface wuiraNativeStatusBar extends wuiraNativeFrame {
|
|
100
|
+
GetStatusBarColor(): wuiraNativeReturns<[number, number, number, number]>;
|
|
98
101
|
GetStatusBarTexture(): wuiraNativeTexture;
|
|
99
102
|
SetMinMaxValues(min: number, max: number): void;
|
|
100
103
|
SetValue(value: number): void;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Cell } from "../ui/Cell";
|
|
2
|
+
export interface NativeNameplate extends wuiraNativeFrame {
|
|
3
|
+
readonly UnitFrame?: NativeNameplateVisual;
|
|
4
|
+
readonly namePlateUnitToken?: string;
|
|
5
|
+
GetUnit?(): string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface NativeNameplateVisual extends wuiraNativeFrame {
|
|
8
|
+
readonly healthBar?: wuiraNativeStatusBar;
|
|
9
|
+
readonly castBar?: wuiraNativeStatusBar;
|
|
10
|
+
}
|
|
11
|
+
export interface NameplateInfo {
|
|
12
|
+
readonly Unit: string;
|
|
13
|
+
readonly GUID: string;
|
|
14
|
+
/** Engine-owned carrier. Do not mutate it or attach secure controls through this API. */
|
|
15
|
+
readonly Frame: NativeNameplate;
|
|
16
|
+
readonly Native: NativeNameplateVisual;
|
|
17
|
+
}
|
|
18
|
+
export type NameplateSelector = (this: void, plate: NameplateInfo) => boolean;
|
|
19
|
+
export type NameplateCustomize = (this: void, plate: NameplateContext) => void;
|
|
20
|
+
export type NameplateRender = (this: void, plate: NameplateContext) => Cell;
|
|
21
|
+
/** One unit binding. Use the reversible methods; direct native writes are not tracked. */
|
|
22
|
+
export declare class NameplateContext implements NameplateInfo {
|
|
23
|
+
readonly Unit: string;
|
|
24
|
+
readonly GUID: string;
|
|
25
|
+
readonly Frame: NativeNameplate;
|
|
26
|
+
readonly Native: NativeNameplateVisual;
|
|
27
|
+
private active;
|
|
28
|
+
private readonly cleanup;
|
|
29
|
+
constructor(Unit: string, GUID: string, Frame: NativeNameplate, Native: NativeNameplateVisual);
|
|
30
|
+
/** Register owned subscriptions/sources immediately, before subsequent work can throw. */
|
|
31
|
+
OnDispose(cleanup: () => void): void;
|
|
32
|
+
private check;
|
|
33
|
+
Alpha(frame: wuiraNativeFrame, value: number): void;
|
|
34
|
+
Scale(frame: wuiraNativeFrame, value: number): void;
|
|
35
|
+
Size(frame: wuiraNativeFrame, width: number, height: number): void;
|
|
36
|
+
BarColor(bar: wuiraNativeStatusBar, r: number, g: number, b: number, a?: number): void;
|
|
37
|
+
/** Internal lifecycle endpoint; cleanup failures cannot prevent other restorations. */
|
|
38
|
+
Dispose(): void;
|
|
39
|
+
}
|
|
40
|
+
/** An independently disposable ordered registration group. First matching rule wins globally. */
|
|
41
|
+
export declare class NameplateRules {
|
|
42
|
+
private disposed;
|
|
43
|
+
private add;
|
|
44
|
+
Apply(selector: NameplateSelector, customize: NameplateCustomize): this;
|
|
45
|
+
Replace(selector: NameplateSelector, render: NameplateRender): this;
|
|
46
|
+
/** Re-evaluate after external preset/selector data changes; native events handle unit changes. */
|
|
47
|
+
Refresh(): void;
|
|
48
|
+
Dispose(): void;
|
|
49
|
+
}
|
|
50
|
+
/** Each entry call creates a new group; chained calls append to that group. */
|
|
51
|
+
export declare class Nameplates {
|
|
52
|
+
private constructor();
|
|
53
|
+
static Apply(selector: NameplateSelector, customize: NameplateCustomize): NameplateRules;
|
|
54
|
+
static Replace(selector: NameplateSelector, render: NameplateRender): NameplateRules;
|
|
55
|
+
static Create(): NameplateRules;
|
|
56
|
+
}
|