예제 #1
0
 /// <summary>
 /// Creates a new SDL_Window and SDL_Renderer.
 ///
 /// NOTE:  windowClosed will be called asyncronously in parentForm's thread.
 /// </summary>
 /// <param name="parentForm">The parent Form of the SDL_Window.</param>
 /// <param name="windowWidth">Width of the window to create.</param>
 /// <param name="windowHeight">Height of the window to create.</param>
 /// <param name="windowTitle">Title to give the SDL_Window.</param>
 /// <param name="windowClosed">Delegate for the SDL_Window closing by the user clicking the close button.</param>
 /// <param name="drawsPerSecond">Number of times per second the scene should be rendered.</param>
 /// <param name="eventsPerSecond">Number of times per second the events should be checked, not the number of events to be processed.</param>
 /// <param name="fastRender">If false, will make more extensive sanity checks.</param>
 /// <param name="showCursorOverWindow"> Show the mouse cursor when over the SDL_Window?</param>
 public SDLRenderer(
     Form parentForm,
     int windowWidth,
     int windowHeight,
     string windowTitle,
     void_RendererOnly windowClosed,
     int drawsPerSecond        = DEFAULT_DRAWS_PER_SECOND,
     int eventsPerSecond       = DEFAULT_EVENTS_PER_SECOND,
     bool fastRender           = true,
     bool showCursorOverWindow = true
     ) : base()
 {
     INTERNAL_Init_Main(parentForm, null, windowWidth, windowHeight, windowTitle, windowClosed, drawsPerSecond, eventsPerSecond, fastRender, showCursorOverWindow);
 }
예제 #2
0
            protected virtual void Dispose(bool disposing)
            {
                if (_disposed)
                {
                    return;
                }

                if (sync != null)
                {
                    sync.Dispose();
                }

                sync     = null;
                cbInvoke = null;

                // This is no longer a valid state
                _disposed = true;
            }
예제 #3
0
        void INTERNAL_SDLThread_InvokeQueue_PrepareInvoke(void_RendererOnly del, bool asyncBegin)
        {
            // Invoke will cause a queued event in the SDL thread.  Normal Invoke/BeginInvoke
            // cannot be used as the main loop for the SDL thread is always running.
            // Due to this being handled through a queue system the call can be delayed.

            // Begin/Invoke struct
            var ueInfo = new Invoke_RendererOnly();

            ueInfo.cbInvoke = del;
            ueInfo.sync     = null;

            if (!asyncBegin)
            {
                // Create a semaphore with 1 slot and 0 available to handle Invoke()
                // This way we already hold the lone semaphore slot before we push
                // the event to the queue.  When the event is handled it will release
                // the semaphore count and allow this thread to resume execution.
                ueInfo.sync = new SemaphoreSlim(0, 1);
            }

            // Add this event to the queue
            INTERNAL_SDLThread_InvokeQueue_Add(ueInfo);

            // Was this an Invoke?
            if (!asyncBegin)
            {
                // Wait for the SDL thread to handle the Invoke()
                ueInfo.sync.Wait();
                ueInfo.sync.Release();

                // We need to free the unmanaged resources here
                ueInfo.Dispose();
                ueInfo = null;
            }
        }
예제 #4
0
        // The actual constructor
        void INTERNAL_Init_Main(
            Form mainForm,
            Control targetControl,
            int windowWidth,
            int windowHeight,
            string windowTitle,
            void_RendererOnly windowClosed,
            int drawsPerSecond,
            int eventsPerSecond,
            bool fastRender,
            bool showCursorOverControl)
        {
            // Will this be an anchored window?
            _anchored = (targetControl != null);

            // mainForm must be set regardless
            if (mainForm == null)
            {
                throw new ArgumentException("mainForm/parentForm cannot be null!");
            }

            // windowClosed must be set for an unanchored window
            if ((!_anchored) && (windowClosed == null))
            {
                throw new ArgumentException("windowClosed cannot be null!");
            }

            // Assign the control objects the SDL_Window and SDL_Renderer will attach to
            _targetControl       = targetControl;
            _parent              = _anchored ? targetControl : mainForm;
            _parentHandle        = _parent.Handle;
            _mainForm            = mainForm;
            _mainFormHandle      = _mainForm.Handle;
            _targetControlHandle = _anchored ? _targetControl.Handle : IntPtr.Zero;
            _windowSize          = _anchored ? _targetControl.Size : new Size(windowWidth, windowHeight);
            _windowTitle         = windowTitle;
            WindowClosed         = windowClosed;

            // Create an empty invoke queue
            _invokeQueue = new List <Invoke_RendererOnly>();

            // Clear SDLThread controls
            _threadState           = SDLThreadState.Inactive;
            _exitRequested         = false;
            _pauseThread           = false;
            _rendererResetRequired = false;
            _rendererResetRequired = false;
            _windowSaveRequested   = false;

            // Clear SDLThread Performance Feedback variables
            _actualFPS        = 0;
            _potentialFPS     = 0;
            _averageFrameTime = 0;

            // Set initial render API state
            _clearColor = Color.FromArgb(0);
            _showCursor = showCursorOverControl;
            _fastRender = fastRender;
            _drawsPS    = drawsPerSecond;
            _eventsPS   = eventsPerSecond;

            // Since we are not a procedural language, we'll tell SDL to stfu.
            SDL.SDL_SetMainReady();

            // Initialize SDL
            _sdlInitialized = INTERNAL_Init_SDLSystems(
                SDL.SDL_INIT_TIMER |
                SDL.SDL_INIT_VIDEO
                );
            if (!_sdlInitialized)
            {
                throw new Exception(string.Format("Unable to initialize SDL!\n\n{0}", SDL.SDL_GetError()));
            }

            // Now start the "SDLThread" to handle this renderer
            var threadInitOk = INTERNAL_Init_SDLThread();

            if (!threadInitOk)
            {
                throw new Exception(string.Format("Error in thread startup!\n\n{0}", SDL.SDL_GetError()));
            }
        }
예제 #5
0
 public void BeginInvoke(void_RendererOnly del)
 {
     INTERNAL_SDLThread_InvokeQueue_PrepareInvoke(del, true);
 }
예제 #6
0
 public void Invoke(void_RendererOnly del)
 {
     INTERNAL_SDLThread_InvokeQueue_PrepareInvoke(del, false);
 }