1 /*
2                                     __
3                                    / _|
4   __ _ _   _ _ __ ___  _ __ __ _  | |_ ___  ___ ___
5  / _` | | | | '__/ _ \| '__/ _` | |  _/ _ \/ __/ __|
6 | (_| | |_| | | | (_) | | | (_| | | || (_) \__ \__ \
7  \__,_|\__,_|_|  \___/|_|  \__,_| |_| \___/|___/___/
8 
9 Copyright (C) 2020 Aurora Free Open Source Software.
10 Copyright (C) 2020 João Lourenço <com (dot) gmail (at) jlourenco5691, backward>
11 
12 This file is part of the Aurora Free Open Source Software. This
13 organization promote free and open source software that you can
14 redistribute and/or modify under the terms of the GNU Lesser General
15 Public License Version 3 as published by the Free Software Foundation or
16 (at your option) any later version approved by the Aurora Free Open Source
17 Software Organization. The license is available in the package root path
18 as 'LICENSE' file. Please review the following information to ensure the
19 GNU Lesser General Public License version 3 requirements will be met:
20 https://www.gnu.org/licenses/lgpl.html .
21 
22 Alternatively, this file may be used under the terms of the GNU General
23 Public License version 3 or later as published by the Free Software
24 Foundation. Please review the following information to ensure the GNU
25 General Public License requirements will be met:
26 https://www.gnu.org/licenses/gpl-3.0.html.
27 
28 NOTE: All products, services or anything associated to trademarks and
29 service marks used or referenced on this file are the property of their
30 respective companies/owners or its subsidiaries. Other names and brands
31 may be claimed as the property of others.
32 
33 For more info about intellectual property visit: aurorafoss.org or
34 directly send an email to: contact (at) aurorafoss.org .
35 */
36 
37 module aurorafw.event.eventsystem.eventdispatcher;
38 
39 import aurorafw.event.eventsystem.event : Event;
40 
41 /** Dispatch an Event to a function
42  *
43  * Use this class whenever you want to redirect a specific event to a function. \
44  */
45 @safe
46 public class EventDispatcher
47 {
48 public:
49 	this(Event event)
50 	{
51 		this.event = event;
52 	}
53 
54 	/** Dispatch an event
55 	 *
56 	 * If the `event` variable in EventDispatcher is the same type as T calls func.
57 	 *
58 	 * Params:
59 	 *     T = *Event* to compare to **event**
60 	 *     func = callback function
61 	 *
62 	 * Examples:
63 	 * --------------------
64 	 * void onEvent(in Event e)
65 	 * {
66 	 *     Eventdispatcher ed = new EventDispatcher(e);
67 	 *     ed.dispatch!MyEvent(delegate void(MyEvent event) { event.toString().writeln; });
68 	 * }
69 	 * --------------------
70 	 * --------------------
71 	 * void onEvent(in Event e)
72 	 * {
73 	 *     Eventdispatcher ed = new EventDispatcher(e);
74 	 *     ed.dispatch!MyEvent((MyEvent event) { event.toString().writeln; });
75 	 * }
76 	 * --------------------
77 	 * --------------------
78 	 * auto func = (MyEvent event) { event.toString.writeln; };
79 	 * void onEvent(in Event e)
80 	 * {
81 	 *     Eventdispatcher ed = new EventDispatcher(e);
82 	 *     ed.dispatch!MyEvent(func);
83 	 * }
84 	 * --------------------
85 	 * --------------------
86 	 * void onMyEvent(MyEvent event) { event.toString.writeln; }
87 	 * void onEvent(in Event e)
88 	 * {
89 	 *     import std.functional : toDelegate;
90 	 *     Eventdispatcher ed = new EventDispatcher(e);
91 	 *     ed.dispatch!MyEvent(toDelegate(&onMyEvent));
92 	 * }
93 	 * --------------------
94 	 */
95 	@system
96 	void dispatch(T : Event)(in void delegate(T) func)
97 	in (func.ptr !is null || func.funcptr !is null)
98 	{
99 		if (event.isEventTypeOf(T.staticEventType))
100 			func(cast(T) event);
101 	}
102 
103 private:
104 	Event event;
105 }
106 
107 private version (unittest)
108 {
109 	import aurorafw.unit;
110 	import aurorafw.event.eventsystem.event : EventType, basicEventType;
111 
112 	@EventType("FooEvent")
113 	class FooEvent : Event
114 	{
115 		mixin basicEventType!FooEvent;
116 	}
117 }
118 
119 @safe
120 @("EventDispatcher: ctor")
121 unittest
122 {
123 	FooEvent event = new FooEvent();
124 	EventDispatcher ed = new EventDispatcher(event);
125 	assertSame(ed.event, event);
126 }
127 
128 @system
129 @("EventDispatcher: dispatch")
130 unittest
131 {
132 	FooEvent event = new FooEvent();
133 	FooEvent event2 = new FooEvent();
134 	EventDispatcher ed = new EventDispatcher(event);
135 
136 	ed.dispatch!FooEvent(delegate void(in FooEvent _event) { assertSame(_event, event); assertNotSame(_event, event2); });
137 
138 	ed.dispatch!FooEvent((in FooEvent _event) { assertSame(_event, event); assertNotSame(_event, event2); });
139 
140 	auto func = (in FooEvent _event) { assertSame(_event, event); assertNotSame(_event, event2); };
141 
142 	ed.dispatch!FooEvent(func);
143 }