// // The Open Toolkit Library License // // Copyright (c) 2006 - 2013 the Open Toolkit library. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do // so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // using System; using OpenTK.Platform; using System.Diagnostics; namespace OpenTK { /// /// Provides static methods to manage an OpenTK application. /// public sealed class Toolkit : IDisposable { private Factory platform_factory; private static Toolkit toolkit; private volatile static bool initialized; private static readonly object InitLock = new object(); private Toolkit(Factory factory) { if (factory == null) { throw new ArgumentNullException("factory"); } platform_factory = factory; } /// /// Initializes OpenTK with default options. /// /// /// /// You *must* call this method if you are combining OpenTK with a /// third-party windowing toolkit (e.g. GTK#). In this case, this should be the /// first method called by your application: /// /// static void Main() /// { /// using (OpenTK.Toolkit.Init()) /// { /// ... /// } /// } /// /// /// /// The reason is that some toolkits do not configure the underlying platform /// correctly or configure it in a way that is incompatible with OpenTK. /// Calling this method first ensures that OpenTK is given the chance to /// initialize itself and configure the platform correctly. /// /// /// /// An IDisposable instance that you can use to dispose of the resources /// consumed by OpenTK. /// public static Toolkit Init() { return Init(ToolkitOptions.Default); } /// /// Initializes OpenTK with the specified options. Use this method /// to influence the OpenTK.Platform implementation that will be used. /// /// /// /// You *must* call this method if you are combining OpenTK with a /// third-party windowing toolkit (e.g. GTK#). In this case, this should be the /// first method called by your application: /// /// static void Main() /// { /// using (OpenTK.Toolkit.Init()) /// { /// ... /// } /// } /// /// /// /// The reason is that some toolkits do not configure the underlying platform /// correctly or configure it in a way that is incompatible with OpenTK. /// Calling this method first ensures that OpenTK is given the chance to /// initialize itself and configure the platform correctly. /// /// /// A ToolkitOptions instance /// containing the desired options. /// /// An IDisposable instance that you can use to dispose of the resources /// consumed by OpenTK. /// public static Toolkit Init(ToolkitOptions options) { if (options == null) { throw new ArgumentNullException("options"); } lock (InitLock) { if (!initialized) { initialized = true; Configuration.Init(options); Options = options; // The actual initialization takes place in the // platform-specific factory constructors. toolkit = new Toolkit(new Factory()); } return toolkit; } } internal static ToolkitOptions Options { get; private set; } /// /// Disposes of the resources consumed by this instance. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool manual) { if (manual) { lock (InitLock) { if (initialized) { platform_factory.Dispose(); platform_factory = null; toolkit = null; initialized = false; } } } } #if DEBUG /// /// Finalizes this instance. /// ~Toolkit() { Debug.Print("[Warning] {0} leaked, did you forget to call Dispose()?"); // We may not Dispose() the toolkit from the finalizer thread, // as that will crash on many operating systems. } #endif } }