using System; using System.Collections.Generic; using System.Linq; using System.Text; using Aiwaz.Contracts; using Aiwaz.Common; using SlimDX; namespace Aiwaz.Core { public static class Engine { public static SlimDX.DXGI.Factory Factory { get; private set; } public static SlimDX.Direct3D10.Device Device { get; private set; } public static DeviceEnumerator DeviceEnumerator { get; private set; } public static EngineStates EngineStates { get; private set; } public static FileSystem FileSystem { get; private set; } public static bool Initialized = false; private static List managedEngineDisposables; private static Dictionary managedNamedObjects; public static void Initialize(DisplayAdapter adapter) { if (Initialized) throw new OnlyOneInstanceAllowedException(typeof(Engine).Name); managedEngineDisposables = new List(); managedNamedObjects = new Dictionary(); EngineStates = new EngineStates(); DeviceEnumerator = new DeviceEnumerator(null); DeviceEnumerator.DesiredFormat = SlimDX.DXGI.Format.R8G8B8A8_UNorm; FileSystem = new FileSystem(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Initializing engine."); if (adapter == null) { if (!DeviceEnumerator.HasEnumerated && !DeviceEnumerator.TryEnumerate()) throw new InitializingFailedException(typeof(Engine).Name, "Failed to enumerate device."); adapter = DeviceEnumerator.FindBestAdapter(false); DeviceEnumerator.Verbose(); } SlimDX.Direct3D10.DeviceCreationFlags deviceFlags = SlimDX.Direct3D10.DeviceCreationFlags.None; #if DEBUG // we want debug informations when we run a debug build deviceFlags |= SlimDX.Direct3D10.DeviceCreationFlags.Debug; #endif // lets create the device now Device = new SlimDX.Direct3D10.Device(adapter.Adapter, SlimDX.Direct3D10.DriverType.Hardware, deviceFlags); if(Device == null) throw new InitializingFailedException(typeof(Engine).Name, "Failed to create device."); Factory = new SlimDX.DXGI.Factory(); if(Factory == null) throw new InitializingFailedException(typeof(Engine).Name, "Failed to create GI factory."); Console.WriteLine("Finished initializing engine.\n"); Initialized = true; } public static void RegisterEngineDisposable(IDisposable disposable) { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); RemoveOrphanedObjects(); managedEngineDisposables.Add(new WeakReference(disposable)); } public static bool UnregisterEngineDisposable(IDisposable disposable) { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); RemoveOrphanedObjects(); var weak = managedEngineDisposables.FirstOrDefault(item => item.Target == disposable); if (weak != null) return managedEngineDisposables.Remove(weak); return false; } public static bool ExistsName(string name) { foreach (var o in managedNamedObjects) { if (o.Key == name) return true; } return false; } public static void RegisterNamedObject(string name, object item) { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); RemoveOrphanedObjects(); managedNamedObjects.Add(name, new WeakReference(item)); } public static void UnregisterNamedObject(string name) { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); RemoveOrphanedObjects(); managedNamedObjects.Remove(name); } public static object FindNamedObject(string name) { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); RemoveOrphanedObjects(); WeakReference result; if (managedNamedObjects.TryGetValue(name, out result) && result.IsAlive) return result.Target; return null; } private static void RemoveOrphanedObjects() { int count = managedEngineDisposables.Count; do { managedEngineDisposables.RemoveAll(item => item.IsAlive == false); } while (count > managedEngineDisposables.Count); } public static void Uninitialize() { if (!Initialized) throw new InvalidOperationException("Engine not initialized!"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Uninitializing engine."); while (managedEngineDisposables.Count > 0) { var weakDisposable = managedEngineDisposables.First(); if (weakDisposable.IsAlive && weakDisposable.Target is IDisposable) ((IDisposable)weakDisposable.Target).Dispose(); managedEngineDisposables.Remove(weakDisposable); } if (Device != null) Device.Dispose(); Device = null; if (Factory != null) Factory.Dispose(); Factory = null; if (DeviceEnumerator != null) DeviceEnumerator.Dispose(); DeviceEnumerator = null; if (FileSystem != null) FileSystem.Dispose(); FileSystem = null; } } }