Exemplo n.º 1
0
        protected void WorkerThreadFrameDispatcher(SynchronizationContext uiThreadSyncContext)
        {
            Threading.ResetThread(Thread.CurrentThread.ManagedThreadId);
            try
            {
                stopWatch      = System.Diagnostics.Stopwatch.StartNew();
                tick           = 0;
                prevUpdateTime = DateTime.Now;

                while (!cts.IsCancellationRequested)
                {
                    // either use UI thread to render one frame or this worker thread
                    bool pauseThread = false;
                    if (RenderOnUIThread)
                    {
                        uiThreadSyncContext.Send((s) =>
                        {
                            pauseThread = RunIteration(cts.Token);
                        }, null);
                    }
                    else
                    {
                        pauseThread = RunIteration(cts.Token);
                    }


                    if (pauseThread)
                    {
                        _waitForPausedStateProcessed.Set();
                        _waitForMainGameLoop.WaitOne(); // pause this thread
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("AndroidGameView", ex.ToString());
            }
            finally
            {
                bool c = cts.IsCancellationRequested;

                cts = null;

                if (glSurfaceAvailable)
                {
                    DestroyGLSurface();
                }

                if (glContextAvailable)
                {
                    DestroyGLContext();
                    ContextLostInternal();
                }

                lock (_lockObject)
                {
                    _internalState = InternalState.Exited_GameThread;
                }
            }
        }
Exemplo n.º 2
0
        // Return true to trigger worker thread pause
        bool RunIteration(CancellationToken token)
        {
            // set main game thread global ID
            Threading.ResetThread(Thread.CurrentThread.ManagedThreadId);

            InternalState currentState = InternalState.Exited_GameThread;

            lock (_lockObject)
            {
                currentState = _internalState;
            }

            switch (currentState)
            {
            // exit states
            case InternalState.Exiting:     // when ui thread wants to exit
                processStateExiting();
                break;

            case InternalState.Exited_GameThread:     // when game thread processed exiting event
                lock (_lockObject)
                {
                    _waitForExitedStateProcessed.Set();
                    cts.Cancel();
                }
                break;

            // pause states
            case InternalState.Pausing_UIThread:     // when ui thread wants to pause
                processStatePausing();
                break;

            case InternalState.Paused_GameThread:     // when game thread processed pausing event

                // this must be processed outside of this loop, in the new task thread!
                return(true);    // trigger pause of worker thread

            // other states
            case InternalState.Resuming_UIThread:     // when ui thread wants to resume
                processStateResuming();

                // pause must wait for resume in case pause/resume is called in very quick succession
                lock (_lockObject)
                {
                    _waitForResumedStateProcessed.Set();
                }
                break;

            case InternalState.Running_GameThread:     // when we are running game
                processStateRunning(token);

                break;

            case InternalState.ForceRecreateSurface:
                processStateForceSurfaceRecreation();
                break;

            // default case, error
            default:
                processStateDefault();
                cts.Cancel();
                break;
            }

            return(false);
        }