1 module jin.go.channel;
2 
3 public import jin.go.output;
4 public import jin.go.input;
5 
6 /// Common `Queue` collections implementation.
7 mixin template Channel(Message)
8 {
9 
10     import std.algorithm;
11     import std.container;
12 
13     import jin.go.queue;
14 
15     alias Self = typeof(this);
16 
17     /// Allow transferring between tasks
18     static __isIsolatedType = true;
19 
20     /// All registered Queues.
21     Array!(Queue!Message) queues;
22 
23     /// Index of current Queue.
24     private size_t current;
25 
26     /// Makes new registered `Queue` and returns `Complement` channel.
27     /// Maximum count of messages in a buffer can be provided.
28     Complement!Message pair(Args...)(Args args)
29     {
30         auto queue = new Queue!Message(args);
31         this.queues ~= queue;
32 
33         Complement!Message complement;
34         complement.queues ~= queue;
35 
36         return complement;
37     }
38 
39     /// Moves queues to movable channel of same type.
40     Self move()
41     {
42         auto movable = Self();
43         this.move(movable);
44         return movable;
45     }
46 
47     /// Moves queues to another channel.
48     void move(ref Self target)
49     {
50         target.queues = this.queues.move;
51         target.current = this.current.move;
52     }
53 
54     /// Prevent copy, only move.
55     @disable this(this);
56 }
57 
58 /// Autofinalize and take all.
59 unittest
60 {
61     auto ii = Input!int();
62 
63     {
64         auto oo = ii.pair(5);
65 
66         oo.put(7);
67         oo.put(77);
68     }
69 
70     assert(ii[] == [7, 77]);
71 }
72 
73 /// Movement.
74 unittest
75 {
76     import std.algorithm;
77 
78     auto i1 = Input!int();
79     auto o1 = i1.pair(5);
80 
81     auto i2 = i1.move;
82     auto o2 = o1.move;
83 
84     o2.put(7);
85     o2.put(77);
86     o2.destroy();
87 
88     assert(i1[] == []);
89     assert(i2[] == [7, 77]);
90 }
91 
92 /// Round robin input
93 unittest
94 {
95     auto ii = Input!int();
96 
97     auto o1 = ii.pair(5);
98     auto o2 = ii.pair(5);
99 
100     o1.put(7);
101     o1.put(777);
102     o1.destroy();
103 
104     o2.put(13);
105     o2.put(666);
106     o2.destroy();
107 
108     assert(ii[] == [7, 13, 777, 666]);
109 }
110 
111 /// Round robin output
112 unittest
113 {
114     auto oo = Output!int();
115 
116     auto i1 = oo.pair(5);
117     auto i2 = oo.pair(5);
118 
119     oo.put(7);
120     oo.put(13);
121     oo.put(777);
122     oo.put(666);
123     oo.destroy();
124 
125     assert(i1[] == [7, 777]);
126     assert(i2[] == [13, 666]);
127 }