1+ // RUN: %target-run-simple-swift(-parse-as-library -Xfrontend -enable-experimental-concurrency %import-libdispatch) | %FileCheck %s
2+
3+ // REQUIRES: executable_test
4+ // REQUIRES: concurrency
5+ // REQUIRES: libdispatch
6+
7+ enum GeneralError : Error {
8+ case UnknownBallKind
9+ case Todo
10+ }
11+
12+ enum BallKind {
13+ case MostLostV1
14+ case Chromehard
15+ case PT5
16+ case KirksandLignature
17+ }
18+
19+ class Specs {
20+ // obtains the number of dimples
21+ subscript( _ bk : BallKind ) -> Int {
22+ get throws {
23+ switch ( bk) {
24+ case . MostLostV1:
25+ return 450
26+ case . Chromehard:
27+ return 125
28+ default :
29+ throw GeneralError . UnknownBallKind
30+ }
31+ }
32+ }
33+ }
34+
35+ actor Database {
36+ var currentData : Specs {
37+ get async {
38+ let handle = Task . runDetached { Specs ( ) }
39+ print ( " obtaining specs... " )
40+ return await handle. get ( )
41+ }
42+ }
43+
44+ var hasNewData : Bool {
45+ get throws { return true }
46+ }
47+ }
48+
49+ protocol SphericalObject {
50+ var name : String { get async throws }
51+ var dimples : Int { get async throws }
52+ var description : String { get async throws }
53+ }
54+
55+ class Ball : SphericalObject {
56+ var name : String { get async throws { throw GeneralError . Todo } }
57+ var dimples : Int { get async throws { throw GeneralError . Todo } }
58+ var description : String { get async throws { throw GeneralError . Todo } }
59+ }
60+
61+ class GolfBall : Ball {
62+ private static let db : Database = Database ( )
63+
64+ private var _model : BallKind
65+ private var _dimples : Int ?
66+
67+ init ( _ bk : BallKind ) {
68+ _model = bk
69+ }
70+
71+ override var name : String {
72+ return " golf ball "
73+ }
74+
75+ override var description : String {
76+ get async throws {
77+ return " this \( name) has \( await dimples) dimples "
78+ }
79+ }
80+
81+ override var dimples : Int {
82+ get async {
83+ let newData = ( try ? await GolfBall . db. hasNewData) ?? false
84+
85+ if newData || _dimples == nil {
86+ let specs = await GolfBall . db. currentData
87+ _dimples = ( try ? specs [ _model] ) ?? 0
88+ }
89+
90+ return _dimples!
91+ }
92+ }
93+ }
94+
95+ // CHECK: obtaining specs...
96+ // CHECK: this golf ball has 450 dimples
97+ // CHECK: obtaining specs...
98+ // CHECK: this golf ball has 125 dimples
99+ // CHECK: obtaining specs...
100+ // CHECK: this golf ball has 0 dimples
101+ // CHECK: obtaining specs...
102+ // CHECK: this golf ball has 0 dimples
103+
104+ func printAsBall( _ b : Ball ) async {
105+ print ( try ! await b. description)
106+ }
107+
108+ func printAsAsSphericalObject( _ b : SphericalObject ) async {
109+ print ( try ! await b. description)
110+ }
111+
112+ @main struct RunIt {
113+ static func main( ) async {
114+ let balls : [ ( Bool , Ball ) ] = [
115+ ( true , GolfBall ( . MostLostV1) ) ,
116+ ( false , GolfBall ( . Chromehard) ) ,
117+ ( true , GolfBall ( . PT5) ) ,
118+ ( false , GolfBall ( . KirksandLignature) )
119+ ]
120+ for (useProtocol, ball) in balls {
121+ if ( useProtocol) {
122+ await printAsAsSphericalObject ( ball)
123+ } else {
124+ await printAsBall ( ball)
125+ }
126+ }
127+ }
128+ }
0 commit comments