60361a87f67a0c172856f2a3a951a566dc391fe6
[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 = complements[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 # Matrix for complementing colors
89 var complements: Array[Array[Int]] = [[0, 2, 1],
90 [2, 1, 0],
91 [1, 0, 2]]
92
93 end
94
95 fun print_all_colors do
96 print_colors(blue, blue)
97 print_colors(blue, red)
98 print_colors(blue, yellow)
99 print_colors(red, blue)
100 print_colors(red, red)
101 print_colors(red, yellow)
102 print_colors(yellow, blue)
103 print_colors(yellow, red)
104 print_colors(yellow, yellow)
105 end
106
107 fun print_colors(c1, c2: Int) do
108 print colors[c1] + " + " + colors[c2] + " -> " + colors[complements[c1][c2]]
109 end
110
111 fun get_number(n: Int): String do
112 var str = ""
113 var nstr = n.to_s
114 for c in nstr do
115 str += " " + numbers[c.to_i]
116 end
117 return str
118 end
119
120 fun work(n, nb_colors : Int ) do
121 var place = new MeetingPlace(n)
122 var creatures = new Array[Creature]
123 for i in [0..nb_colors[ do
124 printn " " + colors[i % 3]
125 creatures[i] = new Creature(place, i % 3, i)
126 end
127 print ""
128
129 for c in creatures do c.async.run
130
131 active_actors.wait
132
133 var total = 0
134 for c in creatures do
135 print c.to_string
136 total += c.count
137 end
138
139 print get_number(total)
140 print ""
141
142 for c in creatures do
143 c.async.terminate
144 c.async.wait_termination
145 end
146 end
147
148 var n = if args.is_empty then 600 else args[0].to_i
149
150 print_all_colors
151 print ""
152
153 work(n, 3)
154 work(n, 10)