d6d9675f46b2de5b4752ea2b93caff316432d1d4
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Common / Disposable.cs
1 /*
2  * Copyright(c) 2019 Samsung Electronics Co., Ltd.
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.ComponentModel;
18
19 namespace Tizen.NUI
20 {
21     /// <summary>
22     /// Disposable class.
23     /// </summary>
24     /// <since_tizen> 6 </since_tizen>
25     public class Disposable : global::System.IDisposable
26     {
27         /// <summary>
28         /// A Flag to check if it is already disposed.
29         /// </summary>
30         /// <since_tizen> 6 </since_tizen>
31         protected bool disposed = false;
32
33         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
34         private bool swigCMemOwn { get; set; }
35         private bool isDisposeQueued = false;
36
37         /// <summary>
38         /// Create an instance of Disposable.
39         /// </summary>
40         /// <since_tizen> 6 </since_tizen>
41         public Disposable()
42         {
43             swigCMemOwn = false;
44             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
45         }
46
47         /// This will not be public.
48         [EditorBrowsable(EditorBrowsableState.Never)]
49         public Disposable(global::System.IntPtr cPtr, bool cMemoryOwn)
50         {
51             swigCMemOwn = cMemoryOwn;
52             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
53         }
54
55         /// <summary>
56         /// Dispose.
57         /// </summary>
58         /// <since_tizen> 6 </since_tizen>
59         ~Disposable() => Dispose(false);
60
61         /// <summary>
62         /// Dispose.
63         /// </summary>
64         /// <since_tizen> 6 </since_tizen>
65         public void Dispose()
66         {
67             Dispose(true);
68             System.GC.SuppressFinalize(this);
69         }
70
71         /// <summary>
72         /// Hidden API (Inhouse API).
73         /// Dispose. 
74         /// </summary>
75         /// <remarks>
76         /// Following the guide of https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose.
77         /// This will replace "protected virtual void Dispose(DisposeTypes type)" which is exactly same in functionality.
78         /// </remarks>
79         /// <param name="disposing">true in order to free managed objects</param>
80         // Protected implementation of Dispose pattern.
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         protected virtual void Dispose(bool disposing)
83         {
84             if (disposed)
85             {
86                 return;
87             }
88
89             if (disposing)
90             {
91                 // TODO: dispose managed state (managed objects).
92                 // Explicit call. user calls Dispose()
93
94                 //Throw excpetion if Dispose() is called in separate thread.
95                 if (!Window.IsInstalled())
96                 {
97                     throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
98                 }
99
100                 if (isDisposeQueued)
101                 {
102                     Dispose(DisposeTypes.Implicit);
103                 }
104                 else
105                 {
106                     Dispose(DisposeTypes.Explicit);
107                 }
108             }
109             else
110             {
111                 // Implicit call. user doesn't call Dispose(), so this object is added into DisposeQueue to be disposed automatically.
112                 if (!isDisposeQueued)
113                 {
114                     isDisposeQueued = true;
115                     DisposeQueue.Instance.Add(this);
116                 }
117             }
118
119             // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
120             // TODO: set large fields to null.
121         }
122
123         /// <summary>
124         /// Dispose.
125         /// </summary>
126         /// <since_tizen> 6 </since_tizen>
127         protected virtual void Dispose(DisposeTypes type)
128         {
129             if (disposed)
130             {
131                 return;
132             }
133
134             if (type == DisposeTypes.Explicit)
135             {
136                 //Called by User
137                 //Release your own managed resources here.
138                 //You should release all of your own disposable objects here.
139             }
140
141             //Release your own unmanaged resources here.
142             //You should not access any managed member here except static instance.
143             //because the execution order of Finalizes is non-deterministic.
144             if (swigCPtr.Handle != global::System.IntPtr.Zero)
145             {
146                 if (SwigCMemOwn)
147                 {
148                     swigCMemOwn = false;
149                     ReleaseSwigCPtr(swigCPtr);
150                 }
151                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
152             }
153
154             disposed = true;
155         }
156
157         /// <summary>
158         /// Release swigCPtr.
159         /// </summary>
160         /// <since_tizen> 6 </since_tizen>
161         /// This will not be public opened.
162         [EditorBrowsable(EditorBrowsableState.Never)]
163         protected virtual void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
164         {
165         }
166
167         internal global::System.Runtime.InteropServices.HandleRef SwigCPtr
168         {
169             get => swigCPtr;
170             set
171             {
172                 swigCPtr = value;
173             }
174         }
175
176         internal bool SwigCMemOwn => swigCMemOwn;
177
178         /// <summary>
179         /// A Flag to check if it is already disposed.
180         /// </summary>
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         protected internal bool Disposed => disposed;
183     }
184 }