Release 4.0.0-preview1-00051
[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         public delegate TEventArgs EventInfoParser(IntPtr data, EcoreEventType type, IntPtr info);
108
109         private bool _disposed = false;
110         private EcoreEventType _eventType;
111         private readonly EventInfoParser _parser;
112         private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
113
114         /// <summary>
115         /// Creates and initializes a new instance of the EcoreEvent class.
116         /// </summary>
117         /// <param name="type">EcoreEventType</param>
118         public EcoreEvent(EcoreEventType type) : this(type, null)
119         {
120         }
121
122         /// <summary>
123         /// Creates and initializes a new instance of the EcoreEvent class.
124         /// </summary>
125         /// <param name="type">EcoreEventType</param>
126         /// <param name="parser">EventInfoParser</param>
127         public EcoreEvent(EcoreEventType type, EventInfoParser parser)
128         {
129             _eventType = type;
130             _parser = parser;
131         }
132
133         ~EcoreEvent()
134         {
135             Dispose(false);
136         }
137
138         private struct NativeCallback
139         {
140             public Interop.Ecore.EcoreEventCallback callback;
141             public IntPtr nativeHandler;
142             public EventHandler<TEventArgs> eventHandler;
143         }
144
145         /// <summary>
146         /// On Event Handler of EcoreEvent.
147         /// </summary>
148         public event EventHandler<TEventArgs> On
149         {
150             add
151             {
152                 EventHandler<TEventArgs> handler = value;
153                 var cb = new Interop.Ecore.EcoreEventCallback((data, type, info) =>
154                 {
155                     TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, _eventType, info);
156                     handler(this, ea);
157                 });
158                 IntPtr hNative = Interop.Ecore.ecore_event_handler_add(_eventType.GetValue(), cb, IntPtr.Zero);
159                 _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler, nativeHandler = hNative });
160             }
161             remove
162             {
163                 EventHandler<TEventArgs> handler = value;
164                 var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
165                 foreach (var cb in callbacks)
166                 {
167                     Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
168                 }
169             }
170         }
171
172         protected virtual void Dispose(bool disposing)
173         {
174             if (!_disposed)
175             {
176                 if (disposing)
177                 {
178                     // Place holder to dispose managed state (managed objects).
179                 }
180                 foreach (var cb in _nativeCallbacks)
181                 {
182                     Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
183                 }
184                 _nativeCallbacks.Clear();
185                 _disposed = true;
186             }
187         }
188
189         public void Dispose()
190         {
191             Dispose(true);
192             GC.SuppressFinalize(this);
193         }
194     }
195
196     /// <summary>
197     /// Event class for EcoreEvent
198     /// </summary>
199     public class EcoreEvent : EcoreEvent<EventArgs>
200     {
201         /// <summary>
202         /// Creates and initializes a new instance of the EcoreEvent class.
203         /// </summary>
204         /// <param name="type">EcoreEventType</param>
205         public EcoreEvent(EcoreEventType type) : base(type)
206         {
207         }
208     }
209 }
210