Пример #1
0
 /// <summary>
 /// Deferres a routine into the OpenAL thread and waits for the execution.
 /// </summary>
 /// <param name="routine">The routine to be deferred.</param>
 public void InvokeOpenAL(DeferredRoutine routine)
 {
     if (routine == null)
     {
         return;
     }
     if (Thread.CurrentThread == this.soundThread)
     {
         routine();
     }
     else
     {
         var handler = new DeferredRoutineHandler()
         {
             Routine        = routine,
             WaitHandle     = new ManualResetEvent(false),
             CreatingMethod = new StackTrace().GetFrame(1).GetMethod()
         };
         this.deferredALRoutines.Enqueue(handler);
         handler.WaitHandle.WaitOne();
     }
 }
Пример #2
0
        /// <summary>
        /// Deferres a routine into another thread so the current thread can continue.
        /// </summary>
        /// <remarks>Useful for loading assets or resources.</remarks>
        /// <param name="openGL">Defines if the routine is deferred into the OpenGL thread or not.</param>
        /// <param name="routine">The routine to be deferred.</param>
        public WaitHandle DeferRoutine(bool openGL, DeferredRoutine routine)
        {
            if (routine == null)
            {
                return(null);
            }
            var handler = new DeferredRoutineHandler()
            {
                Routine    = routine,
                WaitHandle = new ManualResetEvent(false)
            };

            if (openGL)
            {
                this.deferredGLRoutines.Enqueue(handler);
            }
            else
            {
                this.deferredRoutines.Enqueue(handler);
            }
            return(handler.WaitHandle);
        }
Пример #3
0
        /// <summary>
        /// Starts the game main loop.
        /// </summary>
        public void Run()
        {
            this.drawThread = Thread.CurrentThread;

            Game.currentGame.Value = this;

            var presentation = this.GetPresentationParameters();

            using (GameWindow window = new GameWindow(
                       presentation.Resolution.Width,
                       presentation.Resolution.Height,
                       presentation.GraphicsMode,
                       presentation.Title,
                       presentation.IsFullscreen ? GameWindowFlags.Fullscreen : GameWindowFlags.Default,
                       presentation.DisplayDevice ?? DisplayDevice.Default,
                       4, 1,
#if DEBUG
                       GraphicsContextFlags.Default | GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug))
#else
                       GraphicsContextFlags.Default | GraphicsContextFlags.ForwardCompatible))
#endif
            {
                window.VSync    = presentation.VSync ? VSyncMode.On : VSyncMode.Off;
                window.Closing += (s, e) => { this.isRunning = false; };
                window.Visible  = true;

                this.input = new InputManager(
                    window.Keyboard,
                    window.Mouse,
                    window.Joysticks.ToArray());

                this.Utilities = new GameUtilities(this);

                this.Assets = new AssetManager();
                this.Size   = presentation.Resolution;

                this.isRunning = true;

                // Start the deferral threads for deferred routines
                for (int i = 0; i < this.deferralThreads.Length; i++)
                {
                    this.deferralThreads[i]      = new Thread(this.DeferRoutines);
                    this.deferralThreads[i].Name = "OpenWorld Deferred Routines Host";
                    this.deferralThreads[i].Start();
                }

                // Start the sound thread.
                this.soundThread      = new Thread(this.SoundLoop);
                this.soundThread.Name = "OpenWorld Sound Thread";
                this.soundThread.Start();

                // Load everything in the draw thread
                this.OnLoad();

                // Start the update thread.
                this.updateThread      = new Thread(this.UpdateLoop);
                this.updateThread.Name = "OpenWorld Game Update Thread";
                this.updateThread.Start();

                Thread.CurrentThread.Name = "OpenWorld Game Render Thread";

                while (this.isRunning)
                {
                    do
                    {
                        DeferredRoutineHandler handler = null;
                        if (this.deferredGLRoutines.TryDequeue(out handler))
                        {
                            handler.Routine();
                            handler.WaitHandle.Set();
                        }
                        Thread.Sleep(0);
                    } while (!this.isRendering);

                    // Process the window, draw everything, then show it.
                    window.ProcessEvents();
                    if (!window.IsExiting)
                    {
                        this.OnDrawPreState(this.Time);

                        if (this.currentState != null)
                        {
                            this.currentState.Draw(this.Time);
                        }

                        this.OnDrawPostState(this.Time);

                        window.SwapBuffers();
                    }
                    this.isRendering = false;

                    Thread.Sleep(16);
                }

                // Unload everything in the draw thread.
                this.OnUnload();

                for (int i = 0; i < this.deferralThreads.Length; i++)
                {
                    this.deferralThreads[i].Join();
                    this.deferralThreads[i] = null;
                }

                this.updateThread.Join();

                this.input = null;
                this.Size  = new System.Drawing.Size();

                if (this.Disposing != null)
                {
                    this.Disposing();
                }

                this.Assets.CleanUp();
                this.Assets = null;
            }

            Game.currentGame.Value = null;
            this.drawThread        = null;
        }