/*:#localized(key: "CrossingOntoMainActor")
 # Crossing onto the main actor: the `await`

 On the last page every call to `deposit` needed an `await`. Here is why. A
 `@MainActor` type protects its state the same way any actor does: the state lives
 on the main actor, and code running somewhere else cannot touch it directly.
 Reaching in from outside is a **crossing**, and a crossing is a point where your
 task may suspend while it waits its turn on the main actor. `await` marks that
 point. It is the same `await` you already use with any actor.

 The crossing applies to *reading* state too, not just calling methods:
 */
//#-hidden-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

// Read the thread through a synchronous helper, so it is safe to call from a task.
func runningOnMainThread() -> Bool {
    Thread.isMainThread
}

@MainActor
final class BalanceDisplay {
    private(set) var balance = 0

    func deposit(_ amount: Int) {
        balance += amount
        print("Deposited \(amount), balance now \(balance). On main thread? \(runningOnMainThread())")
    }
}

let display = BalanceDisplay()
//#-end-hidden-code
//#-editable-code
Task.detached {
    await display.deposit(100)          // calling across: await
    await display.deposit(50)

    let shown = await display.balance   // reading across: await too
    print("Read the balance back from off the main actor: \(shown)")

    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "CrossingOntoMainActorNotice")
 Every single touch of `display` from out here carries an `await`, because each
 one hops onto the main actor and back. This is not boilerplate the compiler makes
 you type for no reason. It is the compiler proving, *before the app ever runs*,
 that main-actor state is never touched off the main thread.

 * callout(Try it): Delete the `await` in front of `display.balance` and run. The
 compiler stops you: main-actor state cannot be read from off the main actor
 without crossing. That refusal, caught at compile time, is exactly the data-race
 safety `@MainActor` buys you. You would see the same error in Xcode.

 [Previous](@previous)  |  page 3 of 11  |  [Next: A One-Off Hop](@next)
 */
