Bridge attachment, population and release
The DAAPI module factory can attach a Flash
bridge with autoPopulate=False. Installing the Python script and populating the
entity are separate steps. The module's creation guard
follows bridge attachment; the bridge's initialized guard
separately prevents normal repeated attachment from automatically rebinding it.
During destruction, the module catches an ordinary Flash-dispose exception and continues
detaching. Superclass or detach errors are outside that local catch and can skip later release
steps. DisposableEntity.destroy can log
an escaping destruction error and still publish the disposed state. Inspect the actual cleanup
path before using that state as proof that bridge and application references were released.
These boundaries were checked against current Python source and recording bridge substitutes. Actual Flash objects, native cleanup and client lifecycle behavior were not tested.
Provider refresh and row delivery
DAAPIDataProvider.refresh sends the
current length to Flash when attached. It does not build, snapshot, sort or wrap the rows.
The current lobby ActionScript provider
invalidates its range cache and announces a change; a later range request can pull the rows.
Python pulls read the current collection and apply the item wrapper then. Sortable variants
obtain their sorted collection on each pull, and range endpoints are inclusive. Setting sort
fields with pySortOn does not itself refresh. Check subclass ordering overrides
rather than assuming refresh fixes the order of later reads.
Partial updates forward the supplied row payload and index directly. They do not update the backing collection, apply its wrapper, resolve sorted positions or use the full-refresh absent-bridge guard. Keep backing rows consistent for future pulls and supply payloads and indices matching the displayed order. The inspected consumer explicitly supplies its own build, update and ordering policy.
Selected Python methods ran with recording bridges and list/wrapper substitutes; the frontend cache branches were source-inspected. Flash rendering, marshalling, runtime timing and installed bytecode parity were not tested.
Page rows, controls and saved queries have different meanings
The client ListPaginator base changes its
offset before requesting a page. Its movement methods do not consult their movement predicates;
the inspected view supplies its button and cooldown gates. Restoring an offset changes that position only,
without restoring the previous result rows.
The concrete ClanFinder provider requests one
more row than its page size. When the parsed row count equals that requested count, it sets
its next-page flag and removes the final sentinel;
the separately reported total does not calculate that flag. Its movement predicates also use
the latest response status. Result rows, total and lookup mapping are replaced before any
failure-driven offset rollback. A truthy envelope containing an empty items list follows a
different rollback branch from a falsy response payload.
In this provider, requestLastSuccess() restores query fields and requests again;
it does not replay cached rows. The saved record belongs to successful recommended-query mode,
so a later successful ordinary search does not replace it. Verify the concrete provider's saved
state rather than treating the method name as a complete success history.
Current-source and synthetic page/context checks establish these Python state boundaries. Real request ordering, server totals, item wrapping and native UI rendering were not tested.
Input and sizing
Overlay windows must publish their real size and avoid capturing input outside their visible panel. Fullscreen browser surfaces cannot provide true click-through to classic HUD elements underneath. See Gameface Modding for the complete resource, window, model, sizing, scaling, and lifecycle patterns.
Single-file UI ownership
_ui = {
'window': None,
'subscriptions': [],
}
def _show_window():
if _ui['window'] is not None:
return
window = _create_verified_window()
_ui['window'] = window
window.load()
def _hide_window():
window = _ui.pop('window', None)
if window is not None:
window.destroy()
_unsubscribe_view_events()
Common mistakes
- Using a Scaleform hook for a Gameface screen or vice versa.
- Keeping generated view-model objects after their view closes.
- Creating duplicate windows on repeated lifecycle events.
- Assuming a loaded window has already published its final browser surface size.
- Binding anonymous or freshly bound handlers that cannot later be removed.
Verification trail
Trace view registration, creation, model generation, resource loading, and destruction. Test navigation away and back, account/battle transitions, resolution changes, and repeated initialization.
Cross-runtime completion and layout
A Python-to-AS3 DAAPI call and the reverse callback form a transaction. Flash can visibly update while a missing reverse callback leaves Python logical state stale. Repeated native input can then keep calculating neighbors from one old index. Observe both directions and reconcile only through the original transaction after its normal completion opportunity.
Native layout can run after a display-coordinate write. If recovery needs a next-frame reapply, preserve it on both real-callback and bounded reconciliation paths. Root display scaling is not an interchangeable native interactive-size operation: previous scoped minimap observations changed hit bounds without cleanly restoring later native sizing.
A plugin parent can be a weak proxy, so Python is-identity is not automatically a valid attachment guard. Prefer the owner lifecycle and verified current attachment semantics. Keep this Scaleform transaction separate from Gameface model publication.