Pitch #2: Protocol-based Actor Isolation

Let's say I'm making a fist person shooter, where players are divided randomly into six teams, and every team keeps track of their kills and deaths.

struct TeamRef: CustomStringConvertible {
    static let numberOfTeams = 6
    private static var kills: [Int] = .init(repeating: 0, count: numberOfTeams)
    private static var deaths: [Int] = .init(repeating: 0, count: numberOfTeams)

    private var teamIdx: Array<Int>.Index = Int.random(in: 0..<numberOfTeams)

    var kills: Int {
        get {
            Self.kills[teamIdx]
        }
        nonmutating set {
            Self.kills[teamIdx] = newValue
        }
    }

    var deaths: Int {
        get {
            Self.deaths[teamIdx]
        }
        nonmutating set {
            Self.deaths[teamIdx] = newValue
        }
    }

    var description: String {
        "kd: \(kills)/\(deaths)"
    }
}

let team = TeamRef()
team.kills += 1
let teamCopy = team
teamCopy.deaths += 10
print(team) // kd: 1/10

This type has reference semantics, all the properties (stored and computed) are Int, which is specifically mentioned in the pitch as a type that would be ValueSemantic.

Why didn't I use a class for the Team?

  • Why not? It's correct swift today.
  • If I want to do something with all the kills, it's better for cache for them to be in the same place in memory
  • I can change the stored property type to something like UInt8 and get 8 times smaller size compared to a class
  • it eliminates ARC overhead