Chameneos-redux actor example
[nit.git] / lib / actors / examples / chameneos-redux / chameneosredux.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Example implemented from "The computer Language Benchmarks Game" - Chameneos-Redux
16 # http://benchmarksgame.alioth.debian.org/
17 #
18 # Complete description of the chameneos-redux :
19 # https://benchmarksgame.alioth.debian.org/u64q/chameneosredux-description.html#chameneosredux
20 module chameneosredux is no_warning("missing-doc")
21
22 import actors
23
24 class Creature
25 actor
26 var place: MeetingPlace
27 var color: Int
28 var id: Int
29 var count = 0
30 var samecount = 0
31
32 fun run do
33 loop
34 var p = place.meet(id, color)
35 if p == null then break
36 color = p.color
37 if p.sameid then samecount += 1
38 count += 1
39 end
40 end
41
42 fun to_string: String do return count.to_s + " " + numbers[samecount]
43 end
44
45 class Pair
46 var sameid: Bool
47 var color: Int
48 end
49
50 class MeetingPlace
51 var meetings_left: Int
52 var firstcolor: nullable Int
53 var firstid: Int = 0
54 var current: Future[Pair] is noinit
55
56 private var mutex = new Mutex
57
58 fun meet(id, c: Int): nullable Pair do
59 var new_pair = new Future[Pair]
60 mutex.lock
61 if meetings_left == 0 then
62 mutex.unlock
63 return null
64 else
65 if firstcolor == null then
66 firstcolor = c
67 firstid = id
68 current = new Future[Pair]
69 else
70 var color = complement(c, firstcolor.as(not null))
71 current.set_value(new Pair(id == firstid, color))
72 firstcolor = null
73 meetings_left -= 1
74 end
75 new_pair = current
76 end
77 mutex.unlock
78 return new_pair.join
79 end
80 end
81
82 redef class Sys
83 fun blue: Int do return 0
84 fun red: Int do return 1
85 fun yellow: Int do return 2
86 var numbers: Array[String] = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
87 var colors: Array[String] = ["blue", "red", "yellow"]
88 end
89
90 fun complement(c, other: Int): Int do
91 if c == blue then
92 if other == blue then
93 return blue
94 else if other == red then
95 return yellow
96 else if other == yellow then
97 return red
98 end
99 else if c == red then
100 if other == blue then
101 return yellow
102 else if other == red then
103 return red
104 else if other == yellow then
105 return blue
106 end
107 else if c == yellow then
108 if other == blue then
109 return red
110 else if other == red then
111 return blue
112 else if other == yellow then
113 return yellow
114 end
115 end
116 abort
117 end
118
119 fun print_all_colors do
120 print_colors(blue, blue)
121 print_colors(blue, red)
122 print_colors(blue, yellow)
123 print_colors(red, blue)
124 print_colors(red, red)
125 print_colors(red, yellow)
126 print_colors(yellow, blue)
127 print_colors(yellow, red)
128 print_colors(yellow, yellow)
129 end
130
131 fun print_colors(c1, c2: Int) do
132 print colors[c1] + " + " + colors[c2] + " -> " + colors[complement(c1, c2)]
133 end
134
135 fun get_number(n: Int): String do
136 var str = ""
137 var nstr = n.to_s
138 for c in nstr do
139 str += " " + numbers[c.to_i]
140 end
141 return str
142 end
143
144 fun work(n, nb_colors : Int ) do
145 var place = new MeetingPlace(n)
146 var creatures = new Array[Creature]
147 for i in [0..nb_colors[ do
148 printn " " + colors[i % 3]
149 creatures[i] = new Creature(place, i % 3, i)
150 end
151 print ""
152
153 for c in creatures do c.async.run
154
155 active_actors.is_empty
156
157 var total = 0
158 for c in creatures do
159 print c.to_string
160 total += c.count
161 end
162
163 print get_number(total)
164 print ""
165
166 for c in creatures do
167 c.async.terminate
168 c.async.wait_termination
169 end
170 end
171
172 var n = 0
173 if args.is_empty then
174 n = 600
175 else
176 n = args[0].to_i
177 end
178
179 print_all_colors
180 print ""
181
182 work(n, 3)
183 work(n, 10)