[OpenTK] Introduce OpenTK (#336)
[platform/core/csapi/tizenfx.git] / external / src / OpenTK / OpenTK / Toolkit.cs
1 //
2 // The Open Toolkit Library License
3 //
4 // Copyright (c) 2006 - 2013 the Open Toolkit library.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 // the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 // OTHER DEALINGS IN THE SOFTWARE.
24 //
25
26 using System;
27 using OpenTK.Platform;
28 using System.Diagnostics;
29
30 namespace OpenTK
31 {
32     /// <summary>
33     /// Provides static methods to manage an OpenTK application.
34     /// </summary>
35     public sealed class Toolkit : IDisposable
36     {
37         private Factory platform_factory;
38         private static Toolkit toolkit;
39
40         private volatile static bool initialized;
41         private static readonly object InitLock = new object();
42
43         private Toolkit(Factory factory)
44         {
45             if (factory == null)
46             {
47                 throw new ArgumentNullException("factory");
48             }
49             platform_factory = factory;
50         }
51
52         /// <summary>
53         /// Initializes OpenTK with default options.
54         /// </summary>
55         /// <remarks>
56         /// <para>
57         /// You *must* call this method if you are combining OpenTK with a
58         /// third-party windowing toolkit (e.g. GTK#). In this case, this should be the
59         /// first method called by your application:
60         /// <code>
61         /// static void Main()
62         /// {
63         ///     using (OpenTK.Toolkit.Init())
64         ///     {
65         ///      ...
66         ///     }
67         /// }
68         /// </code>
69         /// </para>
70         /// <para>
71         /// The reason is that some toolkits do not configure the underlying platform
72         /// correctly or configure it in a way that is incompatible with OpenTK.
73         /// Calling this method first ensures that OpenTK is given the chance to
74         /// initialize itself and configure the platform correctly.
75         /// </para>
76         /// </remarks>
77         /// <returns>
78         /// An IDisposable instance that you can use to dispose of the resources
79         /// consumed by OpenTK.
80         /// </returns>
81         public static Toolkit Init()
82         {
83             return Init(ToolkitOptions.Default);
84         }
85
86         /// <summary>
87         /// Initializes OpenTK with the specified options. Use this method
88         /// to influence the OpenTK.Platform implementation that will be used.
89         /// </summary>
90         /// <remarks>
91         /// <para>
92         /// You *must* call this method if you are combining OpenTK with a
93         /// third-party windowing toolkit (e.g. GTK#). In this case, this should be the
94         /// first method called by your application:
95         /// <code>
96         /// static void Main()
97         /// {
98         ///     using (OpenTK.Toolkit.Init())
99         ///     {
100         ///      ...
101         ///     }
102         /// }
103         /// </code>
104         /// </para>
105         /// <para>
106         /// The reason is that some toolkits do not configure the underlying platform
107         /// correctly or configure it in a way that is incompatible with OpenTK.
108         /// Calling this method first ensures that OpenTK is given the chance to
109         /// initialize itself and configure the platform correctly.
110         /// </para>
111         /// </remarks>
112         /// <param name="options">A <c>ToolkitOptions</c> instance
113         /// containing the desired options.</param>
114         /// <returns>
115         /// An IDisposable instance that you can use to dispose of the resources
116         /// consumed by OpenTK.
117         /// </returns>
118         public static Toolkit Init(ToolkitOptions options)
119         {
120             if (options == null)
121             {
122                 throw new ArgumentNullException("options");
123             }
124
125             lock (InitLock)
126             {
127                 if (!initialized)
128                 {
129                     initialized = true;
130                     Configuration.Init(options);
131                     Options = options;
132
133                     // The actual initialization takes place in the
134                     // platform-specific factory constructors.
135                     toolkit = new Toolkit(new Factory());
136                 }
137                 return toolkit;
138             }
139         }
140
141         internal static ToolkitOptions Options { get; private set; }
142
143         /// <summary>
144         /// Disposes of the resources consumed by this instance.
145         /// </summary>
146         public void Dispose()
147         {
148             Dispose(true);
149             GC.SuppressFinalize(this);
150         }
151
152         private void Dispose(bool manual)
153         {
154             if (manual)
155             {
156                 lock (InitLock)
157                 {
158                     if (initialized)
159                     {
160                         platform_factory.Dispose();
161                         platform_factory = null;
162                         toolkit = null;
163                         initialized = false;
164                     }
165                 }
166             }
167         }
168
169         #if DEBUG
170         /// <summary>
171         /// Finalizes this instance.
172         /// </summary>
173         ~Toolkit()
174         {
175             Debug.Print("[Warning] {0} leaked, did you forget to call Dispose()?");
176             // We may not Dispose() the toolkit from the finalizer thread,
177             // as that will crash on many operating systems.
178         }
179         #endif
180     }
181 }