1 /*
2  * hunt-proton: AMQP Protocol library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.proton.engine.Event;
13 
14 import hunt.proton.engine.Reactor;
15 import hunt.proton.engine.Selectable;
16 import hunt.proton.engine.Task;
17 import hunt.proton.engine.Extendable;
18 import hunt.proton.engine.EventType;
19 import hunt.Enum;
20 import hunt.proton.engine.Handler;
21 import hunt.proton.engine.Connection;
22 import hunt.proton.engine.Link;
23 import hunt.proton.engine.Session;
24 import hunt.proton.engine.Sender;
25 import hunt.proton.engine.Receiver;
26 import hunt.proton.engine.Delivery;
27 import hunt.proton.engine.Transport;
28 import std.concurrency : initOnce;
29 
30 /**
31  * Event
32  *
33  */
34 
35 //enum Type{
36 //    REACTOR_INIT,
37 //    REACTOR_QUIESCED,
38 //    REACTOR_FINAL,
39 //
40 //    TIMER_TASK,
41 //
42 //    CONNECTION_INIT,
43 //    CONNECTION_BOUND,
44 //    CONNECTION_UNBOUND,
45 //    CONNECTION_LOCAL_OPEN,
46 //    CONNECTION_REMOTE_OPEN,
47 //    CONNECTION_LOCAL_CLOSE,
48 //    CONNECTION_REMOTE_CLOSE,
49 //    CONNECTION_FINAL,
50 //
51 //    SESSION_INIT,
52 //    SESSION_LOCAL_OPEN,
53 //    SESSION_REMOTE_OPEN,
54 //    SESSION_LOCAL_CLOSE,
55 //    SESSION_REMOTE_CLOSE,
56 //    SESSION_FINAL,
57 //
58 //    LINK_INIT,
59 //    LINK_LOCAL_OPEN,
60 //    LINK_REMOTE_OPEN,
61 //    LINK_LOCAL_DETACH,
62 //    LINK_REMOTE_DETACH,
63 //    LINK_LOCAL_CLOSE,
64 //    LINK_REMOTE_CLOSE,
65 //    LINK_FLOW,
66 //    LINK_FINAL,
67 //
68 //    DELIVERY,
69 //
70 //    TRANSPORT,
71 //    TRANSPORT_ERROR,
72 //    TRANSPORT_HEAD_CLOSED,
73 //    TRANSPORT_TAIL_CLOSED,
74 //    TRANSPORT_CLOSED,
75 //
76 //    SELECTABLE_INIT,
77 //    SELECTABLE_UPDATED,
78 //    SELECTABLE_READABLE,
79 //    SELECTABLE_WRITABLE,
80 //    SELECTABLE_EXPIRED,
81 //    SELECTABLE_ERROR,
82 //    SELECTABLE_FINAL,
83 //
84 //    /**
85 //         * This value must never be used to generate an event, it's only used as
86 //         * a guard when casting custom EventTypes to core {@link Type} via
87 //         * {@link Event#getType()}.
88 //         */
89 //    NON_CORE_EVENT
90 //}
91 
92 struct AmqpEventType {
93     string name;
94 
95     int ordinal;
96 
97     enum AmqpEventType REACTOR_INIT = AmqpEventType("REACTOR_INIT",0);
98     enum AmqpEventType REACTOR_QUIESCED = AmqpEventType("REACTOR_QUIESCED",1);
99     enum AmqpEventType REACTOR_FINAL = AmqpEventType("REACTOR_FINAL",2);
100     enum AmqpEventType TIMER_TASK = AmqpEventType("TIMER_TASK",3);
101     enum AmqpEventType CONNECTION_INIT = AmqpEventType("CONNECTION_INIT",4);
102     enum AmqpEventType CONNECTION_BOUND = AmqpEventType("CONNECTION_BOUND",5);
103     enum AmqpEventType CONNECTION_UNBOUND = AmqpEventType("CONNECTION_UNBOUND",6);
104     enum AmqpEventType CONNECTION_LOCAL_OPEN = AmqpEventType("CONNECTION_LOCAL_OPEN",7);
105     enum AmqpEventType CONNECTION_REMOTE_OPEN = AmqpEventType("CONNECTION_REMOTE_OPEN",8);
106     enum AmqpEventType CONNECTION_LOCAL_CLOSE = AmqpEventType("CONNECTION_LOCAL_CLOSE",9);
107     enum AmqpEventType CONNECTION_REMOTE_CLOSE = AmqpEventType("CONNECTION_REMOTE_CLOSE",10);
108     enum AmqpEventType CONNECTION_FINAL = AmqpEventType("CONNECTION_FINAL",11);
109     enum AmqpEventType SESSION_INIT = AmqpEventType("SESSION_INIT",12);
110     enum AmqpEventType SESSION_LOCAL_OPEN = AmqpEventType("SESSION_LOCAL_OPEN",13);
111     enum AmqpEventType SESSION_REMOTE_OPEN = AmqpEventType("SESSION_REMOTE_OPEN",14);
112     enum AmqpEventType SESSION_LOCAL_CLOSE = AmqpEventType("SESSION_LOCAL_CLOSE",15);
113     enum AmqpEventType SESSION_REMOTE_CLOSE = AmqpEventType("SESSION_REMOTE_CLOSE",16);
114     enum AmqpEventType SESSION_FINAL = AmqpEventType("SESSION_FINAL",17);
115     enum AmqpEventType LINK_INIT = AmqpEventType("LINK_INIT",18);
116     enum AmqpEventType LINK_LOCAL_OPEN = AmqpEventType("LINK_LOCAL_OPEN",19);
117     enum AmqpEventType LINK_REMOTE_OPEN = AmqpEventType("LINK_REMOTE_OPEN",20);
118     enum AmqpEventType LINK_LOCAL_DETACH = AmqpEventType("LINK_LOCAL_DETACH",21);
119     enum AmqpEventType LINK_REMOTE_DETACH = AmqpEventType("LINK_REMOTE_DETACH",22);
120     enum AmqpEventType LINK_LOCAL_CLOSE = AmqpEventType("LINK_LOCAL_CLOSE",23);
121     enum AmqpEventType LINK_REMOTE_CLOSE = AmqpEventType("LINK_REMOTE_CLOSE",24);
122     enum AmqpEventType LINK_FLOW = AmqpEventType("LINK_FLOW",25);
123     enum AmqpEventType LINK_FINAL = AmqpEventType("LINK_FINAL",26);
124     enum AmqpEventType DELIVERY = AmqpEventType("DELIVERY",27);
125     enum AmqpEventType TRANSPORT = AmqpEventType("TRANSPORT",28);
126     enum AmqpEventType TRANSPORT_ERROR = AmqpEventType("TRANSPORT_ERROR",29);
127     enum AmqpEventType TRANSPORT_HEAD_CLOSED = AmqpEventType("TRANSPORT_HEAD_CLOSED",30);
128     enum AmqpEventType TRANSPORT_TAIL_CLOSED = AmqpEventType("TRANSPORT_TAIL_CLOSED",31);
129     enum AmqpEventType TRANSPORT_CLOSED = AmqpEventType("TRANSPORT_CLOSED",32);
130     enum AmqpEventType SELECTABLE_INIT = AmqpEventType("SELECTABLE_INIT",33);
131     enum AmqpEventType SELECTABLE_UPDATED = AmqpEventType("SELECTABLE_UPDATED",34);
132     enum AmqpEventType SELECTABLE_READABLE = AmqpEventType("SELECTABLE_READABLE",35);
133     enum AmqpEventType SELECTABLE_WRITABLE = AmqpEventType("SELECTABLE_WRITABLE",36);
134     enum AmqpEventType SELECTABLE_EXPIRED = AmqpEventType("SELECTABLE_EXPIRED",37);
135     enum AmqpEventType SELECTABLE_ERROR = AmqpEventType("SELECTABLE_ERROR",38);
136     enum AmqpEventType SELECTABLE_FINAL = AmqpEventType("SELECTABLE_FINAL",39);
137     enum AmqpEventType NON_CORE_EVENT = AmqpEventType("NON_CORE_EVENT",40);
138 
139     bool opEquals(const AmqpEventType s) {
140         return ordinal == s.ordinal;
141     }   
142     
143     bool opEquals(ref const AmqpEventType s) {
144         return ordinal == s.ordinal;
145     }
146 
147     bool isValid() {
148        return this == NON_CORE_EVENT? false : true;
149     }
150 }
151 
152 
153 class Type : AbstractEnum!Type , EventType {
154 
155 
156     static Type  REACTOR_INIT() {
157         __gshared Type  inst;
158         return initOnce!inst(new Type("REACTOR_INIT",0));
159     }
160 
161     static Type  REACTOR_QUIESCED() {
162         __gshared Type  inst;
163         return initOnce!inst(new Type("REACTOR_QUIESCED",1));
164     }
165 
166     static Type  REACTOR_FINAL() {
167         __gshared Type  inst;
168         return initOnce!inst(new Type("REACTOR_FINAL",2));
169     }
170 
171     static Type  TIMER_TASK() {
172         __gshared Type  inst;
173         return initOnce!inst(new Type("TIMER_TASK",3));
174     }
175 
176     static Type  CONNECTION_INIT() {
177         __gshared Type  inst;
178         return initOnce!inst(new Type("CONNECTION_INIT",4));
179     }
180 
181     static Type  CONNECTION_BOUND() {
182         __gshared Type  inst;
183         return initOnce!inst(new Type("CONNECTION_BOUND",5));
184     }
185 
186     static Type  CONNECTION_UNBOUND() {
187         __gshared Type  inst;
188         return initOnce!inst(new Type("CONNECTION_UNBOUND",6));
189     }
190 
191     static Type  CONNECTION_LOCAL_OPEN() {
192         __gshared Type  inst;
193         return initOnce!inst(new Type("CONNECTION_LOCAL_OPEN",7));
194     }
195 
196     static Type  CONNECTION_REMOTE_OPEN() {
197         __gshared Type  inst;
198         return initOnce!inst(new Type("CONNECTION_REMOTE_OPEN",8));
199     }
200 
201     static Type  CONNECTION_LOCAL_CLOSE() {
202         __gshared Type  inst;
203         return initOnce!inst(new Type("CONNECTION_LOCAL_CLOSE",9));
204     }
205 
206     static Type  CONNECTION_REMOTE_CLOSE() {
207         __gshared Type  inst;
208         return initOnce!inst(new Type("CONNECTION_REMOTE_CLOSE",10));
209     }
210 
211     static Type  CONNECTION_FINAL() {
212         __gshared Type  inst;
213         return initOnce!inst(new Type("CONNECTION_FINAL",11));
214     }
215 
216     static Type  SESSION_INIT() {
217         __gshared Type  inst;
218         return initOnce!inst(new Type("SESSION_INIT",12));
219     }
220 
221     static Type  SESSION_LOCAL_OPEN() {
222         __gshared Type  inst;
223         return initOnce!inst(new Type("SESSION_LOCAL_OPEN",13));
224     }
225 
226     static Type  SESSION_REMOTE_OPEN() {
227         __gshared Type  inst;
228         return initOnce!inst(new Type("SESSION_REMOTE_OPEN",14));
229     }
230 
231     static Type  SESSION_LOCAL_CLOSE() {
232         __gshared Type  inst;
233         return initOnce!inst(new Type("SESSION_LOCAL_CLOSE",15));
234     }
235 
236     static Type  SESSION_REMOTE_CLOSE() {
237         __gshared Type  inst;
238         return initOnce!inst(new Type("SESSION_REMOTE_CLOSE",16));
239     }
240 
241     static Type  SESSION_FINAL() {
242         __gshared Type  inst;
243         return initOnce!inst(new Type("SESSION_FINAL",17));
244     }
245 
246     static Type  LINK_INIT() {
247         __gshared Type  inst;
248         return initOnce!inst(new Type("LINK_INIT",18));
249     }
250 
251     static Type  LINK_LOCAL_OPEN() {
252         __gshared Type  inst;
253         return initOnce!inst(new Type("LINK_LOCAL_OPEN",19));
254     }
255 
256     static Type  LINK_REMOTE_OPEN() {
257         __gshared Type  inst;
258         return initOnce!inst(new Type("LINK_REMOTE_OPEN",20));
259     }
260 
261     static Type  LINK_LOCAL_DETACH() {
262         __gshared Type  inst;
263         return initOnce!inst(new Type("LINK_LOCAL_DETACH",21));
264     }
265 
266     static Type  LINK_REMOTE_DETACH() {
267         __gshared Type  inst;
268         return initOnce!inst(new Type("LINK_REMOTE_DETACH",22));
269     }
270 
271     static Type  LINK_LOCAL_CLOSE() {
272         __gshared Type  inst;
273         return initOnce!inst(new Type("LINK_LOCAL_CLOSE",23));
274     }
275 
276     static Type  LINK_REMOTE_CLOSE() {
277         __gshared Type  inst;
278         return initOnce!inst(new Type("LINK_REMOTE_CLOSE",24));
279     }
280 
281     static Type  LINK_FLOW() {
282         __gshared Type  inst;
283         return initOnce!inst(new Type("LINK_FLOW",25));
284     }
285 
286     static Type  LINK_FINAL() {
287         __gshared Type  inst;
288         return initOnce!inst(new Type("LINK_FINAL",26));
289     }
290 
291     static Type  DELIVERY() {
292         __gshared Type  inst;
293         return initOnce!inst(new Type("DELIVERY",27));
294     }
295 
296     static Type  TRANSPORT() {
297         __gshared Type  inst;
298         return initOnce!inst(new Type("TRANSPORT",28));
299     }
300 
301     static Type  TRANSPORT_ERROR() {
302         __gshared Type  inst;
303         return initOnce!inst(new Type("TRANSPORT_ERROR",29));
304     }
305 
306     static Type  TRANSPORT_HEAD_CLOSED() {
307         __gshared Type  inst;
308         return initOnce!inst(new Type("TRANSPORT_HEAD_CLOSED",30));
309     }
310 
311     static Type  TRANSPORT_TAIL_CLOSED() {
312         __gshared Type  inst;
313         return initOnce!inst(new Type("TRANSPORT_TAIL_CLOSED",31));
314     }
315 
316     static Type  TRANSPORT_CLOSED() {
317         __gshared Type  inst;
318         return initOnce!inst(new Type("TRANSPORT_CLOSED",32));
319     }
320 
321     static Type  SELECTABLE_INIT() {
322         __gshared Type  inst;
323         return initOnce!inst(new Type("SELECTABLE_INIT",33));
324     }
325 
326     static Type  SELECTABLE_UPDATED() {
327         __gshared Type  inst;
328         return initOnce!inst(new Type("SELECTABLE_UPDATED",34));
329     }
330 
331     static Type  SELECTABLE_READABLE() {
332         __gshared Type  inst;
333         return initOnce!inst(new Type("SELECTABLE_READABLE",35));
334     }
335 
336     static Type  SELECTABLE_WRITABLE() {
337         __gshared Type  inst;
338         return initOnce!inst(new Type("SELECTABLE_WRITABLE",36));
339     }
340 
341     static Type  SELECTABLE_EXPIRED() {
342         __gshared Type  inst;
343         return initOnce!inst(new Type("SELECTABLE_EXPIRED",37));
344     }
345 
346     static Type  SELECTABLE_ERROR() {
347         __gshared Type  inst;
348         return initOnce!inst(new Type("SELECTABLE_ERROR",38));
349     }
350 
351     static Type  SELECTABLE_FINAL() {
352         __gshared Type  inst;
353         return initOnce!inst(new Type("SELECTABLE_FINAL",39));
354     }
355 
356     static Type  NON_CORE_EVENT() {
357         __gshared Type  inst;
358         return initOnce!inst(new Type("NON_CORE_EVENT",40));
359     }
360 
361     this (string name, int i)
362     {
363         super(name,i);
364     }
365 
366     //@Override
367     //          public boolean isValid() { return false; }
368     public bool isValid() {
369        return this == NON_CORE_EVENT? false : true;
370     }
371 }
372 
373 interface Event : Extendable
374 {
375     /**
376      * Event types built into the library.
377      */
378 
379 
380     /**
381      * @return type of the event. The event type can be defined outside of the
382      *         proton library.
383      */
384     EventType getEventType();
385 
386     /**
387      * A concrete event type of core events.
388      *
389      * @return type of the event for core events. For events generated by
390      *         extensions a {@link Type#NON_CORE_EVENT} will be returned
391      */
392     Type getType();
393 
394     Object getContext();
395 
396     /**
397      * The {@link Handler} at the root of the handler tree.
398      * <p>
399      * Set by the {@link Reactor} before dispatching the event.
400      * <p>
401      * @see #redispatch(EventType, Handler)
402      * @return The root handler
403      */
404     Handler getRootHandler();
405 
406     void dispatch(Handler handler) ;
407 
408     /**
409      * Synchronously redispatch the current event as a new {@link EventType} on the provided handler and it's children.
410      * <p>
411      * Note: the <code>redispatch()</code> will complete before children of the current handler have had the current event dispatched, see {@link #delegate()}.
412      *
413      *
414      * @param as_type Type of event to dispatch
415      * @param handler The handler where to start the dispatch. Use {@link #getRootHandler()} to redispatch the new event to all handlers in the tree.
416      * @throws HandlerException A wrapper exception of any unhandled exception thrown by <code>handler</code>
417      */
418     void redispatch(EventType as_type, Handler handler) ;
419 
420     /**
421      * dispatch the event to all children of the handler. A handler can call
422      * this method explicitly to be able to do more processing after all child
423      * handlers have already processed the event. If handler does not invoke
424      * this method it is invoked implicitly by {@link #dispatch(Handler)}
425      *
426      * @throws HandlerException
427      */
428     void Idelegate();
429 
430     Connection getConnection();
431 
432     Session getSession();
433 
434     Link getLink();
435 
436     Sender getSender();
437 
438     Receiver getReceiver();
439 
440     Delivery getDelivery();
441 
442     Transport getTransport();
443 
444     Reactor getReactor();
445 
446     Selectable getSelectable();
447 
448     Task getTask();
449 
450     Event copy();
451 
452 }