RevFramework – Sample Scene: 08_Currency_Awaiters¶
Goal¶
Teach event-driven waiting for currency changes:
Owner + Currency + ICurrencyService.OnWalletChanged → await condition → complete, timeout, or cancel.
What This Scene Demonstrates¶
This scene shows how to wait for wallet changes without polling.
The flow is:
Owner → ICurrencyService → selected CurrencyId → awaiter subscribes to OnWalletChanged → matching change event → condition check → completion
- Awaiters observe public service events
- Awaiters do not mutate balances
- Awaiters do not poll every frame
- Awaiters complete only when the selected condition is met
- Awaiters can timeout or be cancelled
- Existing waits are cancelled if the service instance changes
Awaiters are event-driven helpers.
The service event is the trigger.
What To Look For¶
Use the CurrencyAwaitersPanel to compare Task-based and Coroutine-based wait flows.
-
Setup tab
-
Owner is the wallet being observed
- Service shows the resolved
ICurrencyServicestack - Currency selection provides the
CurrencyIdbeing matched -
Live balance shows the current state before starting waits
-
Tasks tab
-
WaitForBalanceAtLeastAsynccompletes when balance is at least the target WaitForAnyChangeAsynccompletes on the first matching owner/currency changeWaitForDeltaAsynccaptures the starting balance and waits for an absolute delta thresholdWaitForPredicateAsynccompletes when the supplied predicate returns true-
Each task has timeout and cancellation controls
-
Coroutine tab
-
Coroutine
WaitForBalanceAtLeastteaches the same pattern without async/await -
The coroutine completes, times out, cancels, or exits if owner/service context becomes invalid
-
External mutation source
-
Use another panel or gameplay to change the observed balance
- The awaiter panel waits; it does not create the wallet change itself
Sample Scope¶
This scene covers:
- Event-driven currency waiting through
OnWalletChanged - Task-based awaiters
- Coroutine-based awaiters
- Balance-at-least waits
- Any-change waits
- Delta-threshold waits
- Predicate waits
- Timeout and cancellation behaviour
- Service swap cancellation
This scene does NOT cover:
- Mutating balances directly from the awaiter panel
- Polling loops
- Internal service inspection
- Custom production quest systems
- Full reactive UI architecture
- Multiplayer replication or networking
Those are project-level integration concerns.
Authority Note¶
This scene may include a permissive sample authority setup so it runs without additional configuration.
Networking Reminder¶
RevFramework does not include networking.
For multiplayer projects, wallet changes should come from server/host-approved mutations. Awaiters can react to local service events, but they are not a networking or authority layer.
How To Use¶
- Enter Play Mode.
- Toggle the
CurrencyAwaitersPanelwithF8. -
In Setup:
-
Confirm Owner is assigned
- Confirm
ICurrencyServiceis resolved - Select a valid currency
- Check the live balance
-
In Tasks:
-
Configure the target, delta, predicate value, or timeout
- Start one of the task awaiters
- Use another panel or gameplay to mutate the selected owner/currency
- Watch the status update when the condition completes, times out, or is cancelled
-
In Coroutine:
-
Enter a target and timeout
- Start the coroutine awaiter
- Mutate the selected owner/currency externally
- Watch the coroutine status complete or cancel
- Cancel running waits when you no longer need them.
Failure Behaviour¶
Failures or exits are shown through dependency messages, awaiter statuses, or result messages.
Common causes:
-
Play Mode required
-
Awaiters listen to live runtime service events
-
Fix: enter Play Mode
-
Service missing
-
No
ICurrencyServicewas resolved -
Fix: add a scene currency service, add
CurrencyServiceBootstrap, or publish a composed service -
Owner missing
-
No wallet owner is selected
-
Fix: assign an owner or tag the player GameObject as
Player -
No currencies bound
-
No
CurrencyDefinitionassets are available -
Fix: assign currencies in the Inspector or provide a
CurrencySet -
Invalid CurrencyId
-
The selected
CurrencyDefinitionhas an invalid Id -
Fix: correct the CurrencyDefinition asset
-
Bad input
-
Target, delta, predicate, or timeout values are invalid
-
Fix: enter values within the panel’s accepted ranges
-
Timeout
-
No matching event satisfied the condition before timeout
-
Fix: increase the timeout or trigger a matching owner/currency mutation
-
Cancelled
-
The user cancelled the awaiter, the panel disabled, or context changed
-
Fix: start the awaiter again when ready
-
Service changed
-
Existing waits are tied to the previous service instance
-
Fix: restart awaiters against the new service
-
No completion despite balance changes
-
The awaited owner/currency did not match the emitted change
- Fix: check owner binding, selected currency, service reference, and whether
OnWalletChangedfires for that mutation
Behind The Scenes¶
The panel uses real Currency awaiter APIs:
-
CurrencyResolve.ServiceFrom -
resolves the active
ICurrencyService -
ICurrencyService -
GetBalance -
OnWalletChanged -
CurrencyAwaiters -
WaitForBalanceAtLeastAsync WaitForAnyChangeAsyncWaitForDeltaAsyncWaitForPredicateAsync-
WaitForBalanceAtLeastcoroutine variant -
CancellationTokenSource -
cancels Task-based waits
-
Unity coroutine host
-
runs the coroutine awaiter
The panel observes service events only.
It does not inspect internals.
It does not mutate balances directly.
Key Takeaway¶
Awaiters wait for real wallet events.
They complete when the selected condition becomes true.
Use them when you want reactive currency logic without manual polling.