1
+ // Examples from Eric's internship final presentation.
2
+ //
3
+ // Code is easier to write in emacs, and it's good to be sure all the
4
+ // code samples compile (or not) as they should.
5
+
6
+ import double_buffer:: client:: * ;
7
+ import double_buffer:: give_buffer;
8
+
9
+ macro_rules! select_if {
10
+ {
11
+ $index: expr,
12
+ $count: expr,
13
+ $port: path => [
14
+ $( $message: path$( ( $( $x: ident) ,+) ) dont_type_this*
15
+ -> $next: ident $e: expr) ,+
16
+ ] ,
17
+ $( $ports: path => [
18
+ $( $messages: path$( ( $( $xs: ident) ,+) ) dont_type_this*
19
+ -> $nexts: ident $es: expr) ,+
20
+ ] , ) *
21
+ } => {
22
+ log_syntax!{ select_if1} ;
23
+ if $index == $count {
24
+ match move pipes:: try_recv( $port) {
25
+ $( some( $message( $( $( copy $x, ) +) * next) ) => {
26
+ // FIXME (#2329) we really want move out of enum here.
27
+ let $next = unsafe { let x <- * ptr:: addr_of( next) ; x } ;
28
+ $e
29
+ } ) +
30
+ _ => fail
31
+ }
32
+ } else {
33
+ select_if!{
34
+ $index,
35
+ $count + 1 ,
36
+ $( $ports => [
37
+ $( $messages$( ( $( $xs) ,+) ) dont_type_this*
38
+ -> $nexts $es) ,+
39
+ ] , ) *
40
+ }
41
+ }
42
+ } ;
43
+
44
+ {
45
+ $index: expr,
46
+ $count: expr,
47
+ } => {
48
+ log_syntax!{ select_if2} ;
49
+ fail
50
+ }
51
+ }
52
+
53
+ macro_rules! select {
54
+ {
55
+ $( $port: path => {
56
+ $( $message: path$( ( $( $x: ident) ,+) ) dont_type_this*
57
+ -> $next: ident $e: expr) ,+
58
+ } ) +
59
+ } => {
60
+ let index = pipes:: selecti( [ $( ( $port) . header( ) ) ,+] /_) ;
61
+ log_syntax!{ select} ;
62
+ log_syntax!{
63
+ select_if!{ index, 0 , $( $port => [
64
+ $( $message$( ( $( $x) ,+) ) dont_type_this* -> $next $e) ,+
65
+ ] , ) +}
66
+ } ;
67
+ select_if!{ index, 0 , $( $port => [
68
+ $( $message$( ( $( $x) ,+) ) dont_type_this* -> $next $e) ,+
69
+ ] , ) +}
70
+ }
71
+ }
72
+
73
+ // Types and protocols
74
+ struct Buffer {
75
+ foo : ( ) ;
76
+
77
+ drop { }
78
+ }
79
+
80
+ proto! double_buffer {
81
+ acquire : send {
82
+ request -> wait_buffer
83
+ }
84
+
85
+ wait_buffer: recv {
86
+ give_buffer( Buffer ) -> release
87
+ }
88
+
89
+ release: send {
90
+ release( Buffer ) -> acquire
91
+ }
92
+ }
93
+
94
+ // Code examples
95
+ fn render ( _buffer : & Buffer ) {
96
+ // A dummy function.
97
+ }
98
+
99
+ fn draw_frame ( +channel : double_buffer:: client:: acquire ) {
100
+ let channel = request ( channel) ;
101
+ select ! {
102
+ channel => {
103
+ give_buffer( buffer) -> channel {
104
+ render( & buffer) ;
105
+ release( channel, move buffer)
106
+ }
107
+ }
108
+ } ;
109
+ }
110
+
111
+ fn draw_two_frames ( +channel : double_buffer:: client:: acquire ) {
112
+ let channel = request ( channel) ;
113
+ let channel = select ! {
114
+ channel => {
115
+ give_buffer( buffer) -> channel {
116
+ render( & buffer) ;
117
+ release( channel, move buffer)
118
+ }
119
+ }
120
+ } ;
121
+ let channel = request ( channel) ;
122
+ select ! {
123
+ channel => {
124
+ give_buffer( buffer) -> channel {
125
+ render( & buffer) ;
126
+ release( channel, move buffer)
127
+ }
128
+ }
129
+ } ;
130
+ }
131
+
132
+ #[ cfg( bad1) ]
133
+ fn draw_two_frames_bad1 ( +channel : double_buffer:: client:: acquire ) {
134
+ let channel = request ( channel) ;
135
+ let channel = select ! {
136
+ channel => {
137
+ give_buffer( buffer) -> channel {
138
+ render( & buffer) ;
139
+ channel
140
+ }
141
+ }
142
+ } ;
143
+ let channel = request ( channel) ;
144
+ select ! {
145
+ channel => {
146
+ give_buffer( buffer) -> channel {
147
+ render( & buffer) ;
148
+ release( channel, move buffer)
149
+ }
150
+ }
151
+ } ;
152
+ }
153
+
154
+ #[ cfg( bad2) ]
155
+ fn draw_two_frames_bad2 ( +channel : double_buffer:: client:: acquire ) {
156
+ let channel = request ( channel) ;
157
+ select ! {
158
+ channel => {
159
+ give_buffer( buffer) -> channel {
160
+ render( & buffer) ;
161
+ release( channel, move buffer) ;
162
+ render( & buffer) ;
163
+ release( channel, move buffer) ;
164
+ }
165
+ }
166
+ } ;
167
+ }
168
+
169
+ fn main ( ) { }
0 commit comments