Release 4.0.0-preview1-00267
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / EcoreEvent.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Runtime.InteropServices;
21
22 namespace ElmSharp
23 {
24     /// <summary>
25     /// The EcoreEventType is type of EcoreEvent.
26     /// It includes some predefined instance.
27     /// </summary>
28     public class EcoreEventType
29     {
30         /// <summary>
31         /// Key down Ecore event type.
32         /// </summary>
33         public static readonly EcoreEventType KeyDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_DOWN");
34         /// <summary>
35         /// Key Up Ecore event type.
36         /// </summary>
37         public static readonly EcoreEventType KeyUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_UP");
38         /// <summary>
39         /// Mouse Button Down Ecore event type.
40         /// </summary>
41         public static readonly EcoreEventType MouseButtonDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_DOWN");
42         /// <summary>
43         /// Mouse Button Up Ecore event type.
44         /// </summary>
45         public static readonly EcoreEventType MouseButtonUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_UP");
46         /// <summary>
47         /// Mouse Button Cancel Ecore event type.
48         /// </summary>
49         public static readonly EcoreEventType MouseButtonCancel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_CANCEL");
50         /// <summary>
51         /// Mouse Move Ecore event type.
52         /// </summary>
53         public static readonly EcoreEventType MouseMove = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_MOVE");
54         /// <summary>
55         /// Mouse Wheel Ecore event type.
56         /// </summary>
57         public static readonly EcoreEventType MouseWheel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_WHEEL");
58         /// <summary>
59         /// Mouse In Ecore event type.
60         /// </summary>
61         public static readonly EcoreEventType MouseIn = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_IN");
62         /// <summary>
63         /// Mouse Out Ecore event type.
64         /// </summary>
65         public static readonly EcoreEventType MouseOut = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_OUT");
66
67         private string _lib;
68         private string _name;
69         private int _typeValue;
70
71         private EcoreEventType(string lib, string name)
72         {
73             _lib = lib;
74             _name = name;
75             _typeValue = -1;
76         }
77
78         /// <summary>
79         /// Gets the value associated with the specified type.
80         /// </summary>
81         /// <returns>The value of type.</returns>
82         public int GetValue()
83         {
84             if (_typeValue < 0)
85             {
86                 IntPtr hDll = Interop.Libdl.LoadLibrary(_lib);
87                 if (hDll != IntPtr.Zero)
88                 {
89                     IntPtr pValue = Interop.Libdl.GetProcAddress(hDll, _name);
90                     if (pValue != IntPtr.Zero)
91                     {
92                         _typeValue = Marshal.ReadInt32(pValue);
93                     }
94                     Interop.Libdl.FreeLibrary(hDll);
95                 }
96             }
97             return _typeValue;
98         }
99     }
100
101     /// <summary>
102     /// The EcoreEvent is a class to help to create events are being notified of events.
103     /// </summary>
104     /// <typeparam name="TEventArgs">Kinds of EventArgs</typeparam>
105     public class EcoreEvent<TEventArgs> : IDisposable where TEventArgs : EventArgs
106     {
107         /// <summary>
108         /// EventInfoParser delegate of EcoreEvent class
109         /// </summary>
110         /// <param name="data">IntPtr</param>
111         /// <param name="type">EcoreEventType</param>
112         /// <param name="info">IntPtr</param>
113         /// <returns></returns>
114         public delegate TEventArgs EventInfoParser(IntPtr data, EcoreEventType type, IntPtr info);
115
116         private bool _disposed = false;
117         private EcoreEventType _eventType;
118         private readonly EventInfoParser _parser;
119         private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
120
121         /// <summary>
122         /// Creates and initializes a new instance of the EcoreEvent class.
123         /// </summary>
124         /// <param name="type">EcoreEventType</param>
125         public EcoreEvent(EcoreEventType type) : this(type, null)
126         {
127         }
128
129         /// <summary>
130         /// Creates and initializes a new instance of the EcoreEvent class.
131         /// </summary>
132         /// <param name="type">EcoreEventType</param>
133         /// <param name="parser">EventInfoParser</param>
134         public EcoreEvent(EcoreEventType type, EventInfoParser parser)
135         {
136             _eventType = type;
137             _parser = parser;
138         }
139
140         /// <summary>
141         /// Destructor for EcoreEvent class.
142         /// </summary>
143         ~EcoreEvent()
144         {
145             Dispose(false);
146         }
147
148         private struct NativeCallback
149         {
150             public Interop.Ecore.EcoreEventCallback callback;
151             public IntPtr nativeHandler;
152             public EventHandler<TEventArgs> eventHandler;
153         }
154
155         /// <summary>
156         /// On Event Handler of EcoreEvent.
157         /// </summary>
158         public event EventHandler<TEventArgs> On
159         {
160             add
161             {
162                 EventHandler<TEventArgs> handler = value;
163                 var cb = new Interop.Ecore.EcoreEventCallback((data, type, info) =>
164                 {
165                     TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, _eventType, info);
166                     handler(this, ea);
167                 });
168                 IntPtr hNative = Interop.Ecore.ecore_event_handler_add(_eventType.GetValue(), cb, IntPtr.Zero);
169                 _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler, nativeHandler = hNative });
170             }
171             remove
172             {
173                 EventHandler<TEventArgs> handler = value;
174                 var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
175                 foreach (var cb in callbacks)
176                 {
177                     Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
178                 }
179             }
180         }
181
182         /// <summary>
183         /// Releases all resources currently used by this instance.
184         /// </summary>
185         /// <param name="disposing">
186         /// true if managed resources should be disposed
187         /// otherwise, false.
188         /// </param>
189         protected virtual void Dispose(bool disposing)
190         {
191             if (!_disposed)
192             {
193                 if (disposing)
194                 {
195                     // Place holder to dispose managed state (managed objects).
196                 }
197                 foreach (var cb in _nativeCallbacks)
198                 {
199                     Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
200                 }
201                 _nativeCallbacks.Clear();
202                 _disposed = true;
203             }
204         }
205
206         /// <summary>
207         /// Destroy current object
208         /// </summary>
209         public void Dispose()
210         {
211             Dispose(true);
212             GC.SuppressFinalize(this);
213         }
214     }
215
216     /// <summary>
217     /// Event class for EcoreEvent
218     /// </summary>
219     public class EcoreEvent : EcoreEvent<EventArgs>
220     {
221         /// <summary>
222         /// Creates and initializes a new instance of the EcoreEvent class.
223         /// </summary>
224         /// <param name="type">EcoreEventType</param>
225         public EcoreEvent(EcoreEventType type) : base(type)
226         {
227         }
228     }
229 }
230