Events.cs :  » Game » SDL » SdlDotNet » Core » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » SDL 
SDL » SdlDotNet » Core » Events.cs
#region LICENSE
/*
 * Copyright (C) 2004 - 2007 David Hudson (jendave@yahoo.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#endregion LICENSE

using System;
using System.Threading;
using System.Collections;
using System.Runtime.InteropServices;
using System.Resources;

using Tao.Sdl;
using SdlDotNet.Input;
using SdlDotNet.Audio;
using SdlDotNet.Graphics;

namespace SdlDotNet.Core{
    #region SdlFlag

    /// <summary>
    /// Enum for values that are returned by the SDL C library functions.
    /// This reduces the amount of "magic numbers" in the code.
    /// </summary>
    /// <remarks></remarks>
    internal enum SdlFlag
    {
        /// <summary>
        /// Error
        /// </summary>
        Error = -1,
        /// <summary>
        /// Surccess
        /// </summary>
        Success = 0,
        /// <summary>
        /// Plays in infinite loop.
        /// </summary>
        InfiniteLoop = -1,
        /// <summary>
        /// Error
        /// </summary>
        Error2 = 1,
        /// <summary>
        /// Success
        /// </summary>
        Success2 = 1,
        /// <summary>
        /// None
        /// </summary>
        None = 0,
        /// <summary>
        /// First available channel
        /// </summary>
        FirstFreeChannel = -1,
        /// <summary>
        /// True
        /// </summary>
        TrueValue = 1,
        /// <summary>
        /// False
        /// </summary>
        FalseValue = 0,
    }

    #endregion

    #region EventMask

    /// <summary>
    /// EventMask
    /// </summary>
    /// <remarks>Only used internally to remove events from the event queue</remarks>
    public enum EventMask
    {
        /// <summary>
        /// No event mask
        /// </summary>
        None = 0,
        /// <summary>
        /// Active Event mask
        /// </summary>
        ActiveEvent = Sdl.SDL_ACTIVEEVENTMASK,
        /// <summary>
        /// Key down mask
        /// </summary>
        KeyDown = Sdl.SDL_KEYDOWNMASK,
        /// <summary>
        /// Key up mask
        /// </summary>
        KeyUp = Sdl.SDL_KEYUPMASK,
        /// <summary>
        /// Mouse motion mask
        /// </summary>
        MouseMotion = Sdl.SDL_MOUSEMOTIONMASK,
        /// <summary>
        /// Mouse button down mask
        /// </summary>
        MouseButtonDown = Sdl.SDL_MOUSEBUTTONDOWNMASK,
        /// <summary>
        /// mouse button up mask
        /// </summary>
        MouseButtonUp = Sdl.SDL_MOUSEBUTTONUPMASK,
        /// <summary>
        /// mouse event mask
        /// </summary>
        MouseEvent = Sdl.SDL_MOUSEEVENTMASK,
        /// <summary>
        /// joystick axis motion mask
        /// </summary>
        JoystickAxisMotion = Sdl.SDL_JOYAXISMOTIONMASK,
        /// <summary>
        /// joystick ball motion mask
        /// </summary>
        JoystickBallMotion = Sdl.SDL_JOYBALLMOTIONMASK,
        /// <summary>
        /// joystick hat motion mask
        /// </summary>
        JoystickHatMotion = Sdl.SDL_JOYHATMOTIONMASK,
        /// <summary>
        /// joystick button down mask
        /// </summary>
        JoystickButtonDown = Sdl.SDL_JOYBUTTONDOWNMASK,
        /// <summary>
        /// joystick button up mask
        /// </summary>
        JoystickButtonUp = Sdl.SDL_JOYBUTTONUPMASK,
        /// <summary>
        /// joystick event mask
        /// </summary>
        JoystickEvent = Sdl.SDL_JOYEVENTMASK,
        /// <summary>
        /// Video resize event mask
        /// </summary>
        VideoResize = Sdl.SDL_VIDEORESIZEMASK,
        /// <summary>
        /// Video expose event mask
        /// </summary>
        VideoExpose = Sdl.SDL_VIDEOEXPOSEMASK,
        /// <summary>
        /// Quit event mask
        /// </summary>
        Quit = Sdl.SDL_QUITMASK,
        /// <summary>
        /// Window Manager event mask
        /// </summary>
        WindowManagerEvent = Sdl.SDL_SYSWMEVENTMASK,
        /// <summary>
        /// Mask for all events
        /// </summary>
        AllEvents = Sdl.SDL_ALLEVENTS,
        /// <summary>
        /// Mask for User Events
        /// </summary>
        UserEvent = 1 << Sdl.SDL_USEREVENT
    }

    #endregion

    #region EventTypes

    /// <summary>
    /// Event Types
    /// </summary>
    /// <remarks></remarks>
    [FlagsAttribute]
    public enum EventTypes
    {
        /// <summary>
        /// No event
        /// </summary>
        None = Sdl.SDL_NOEVENT,
        /// <summary>
        /// Active event
        /// </summary>
        ActiveEvent = Sdl.SDL_ACTIVEEVENT,
        /// <summary>
        /// Key down event
        /// </summary>
        KeyDown = Sdl.SDL_KEYDOWN,
        /// <summary>
        /// Key up event
        /// </summary>
        KeyUp = Sdl.SDL_KEYUP,
        /// <summary>
        /// Mouse Motion event
        /// </summary>
        MouseMotion = Sdl.SDL_MOUSEMOTION,
        /// <summary>
        /// Mouse button down event
        /// </summary>
        MouseButtonDown = Sdl.SDL_MOUSEBUTTONDOWN,
        /// <summary>
        /// Mouse button up event
        /// </summary>
        MouseButtonUp = Sdl.SDL_MOUSEBUTTONUP,
        /// <summary>
        /// Joystick Axis motion event
        /// </summary>
        JoystickAxisMotion = Sdl.SDL_JOYAXISMOTION,
        /// <summary>
        /// Joystick ball motion event
        /// </summary>
        JoystickBallMotion = Sdl.SDL_JOYBALLMOTION,
        /// <summary>
        /// Joystick hat motion event
        /// </summary>
        JoystickHatMotion = Sdl.SDL_JOYHATMOTION,
        /// <summary>
        /// Joystick button down event
        /// </summary>
        JoystickButtonDown = Sdl.SDL_JOYBUTTONDOWN,
        /// <summary>
        /// joystick button up event
        /// </summary>
        JoystickButtonUp = Sdl.SDL_JOYBUTTONUP,
        /// <summary>
        /// Video resize event
        /// </summary>
        VideoResize = Sdl.SDL_VIDEORESIZE,
        /// <summary>
        /// Video expose event
        /// </summary>
        VideoExpose = Sdl.SDL_VIDEOEXPOSE,
        /// <summary>
        /// Quit event
        /// </summary>
        Quit = Sdl.SDL_QUIT,
        /// <summary>
        /// Window manager event
        /// </summary>
        WindowManagerEvent = Sdl.SDL_SYSWMEVENT,
        /// <summary>
        /// user-defined event
        /// </summary>
        UserEvent = Sdl.SDL_USEREVENT
    }

    #endregion

    /// <summary>
    /// Contains events which can be attached to to read user input and other miscellaneous occurances.
    /// You can obtain an instance of this class by accessing the Events property of the main Sdl object.
    /// You must call the PollAndDelegate() member in order for any events to fire.
    /// </summary>
    public sealed class Events
    {
        #region Private fields

        private static Hashtable userEvents = new Hashtable();
        private static int userEventId;
        private const int QUERY_EVENTS_MAX = 254;
        static readonly Events instance = new Events();
        static ResourceManager stringManager;
        //static bool isInitialized = Video.Initialize();

        #endregion

        #region Constructors

        Events()
        {
        }

        #endregion Constructors

        #region Public Events

        /// <summary>
        /// Fires when the application has become active or inactive
        /// </summary>
        public static event EventHandler<ActiveEventArgs> AppActive;

        /// <summary>
        /// Fires when a key is pressed
        /// </summary>
        public static event EventHandler<KeyboardEventArgs> KeyboardDown;

        /// <summary>
        /// Fires when a key is released
        /// </summary>
        public static event EventHandler<KeyboardEventArgs> KeyboardUp;

        /// <summary>
        /// Fires when the mouse moves
        /// </summary>
        public static event EventHandler<MouseMotionEventArgs> MouseMotion;

        /// <summary>
        /// Fires when a mouse button is pressed
        /// </summary>
        public static event EventHandler<MouseButtonEventArgs> MouseButtonDown;

        /// <summary>
        /// Fires when a mouse button is released
        /// </summary>
        public static event EventHandler<MouseButtonEventArgs> MouseButtonUp;

        /// <summary>
        /// Fires when a joystick axis changes
        /// </summary>
        public static event EventHandler<JoystickAxisEventArgs> JoystickAxisMotion;

        /// <summary>
        /// Fires when a joystick button is pressed
        /// </summary>
        public static event EventHandler<JoystickButtonEventArgs> JoystickButtonDown;

        /// <summary>
        /// Fires when a joystick button is released
        /// </summary>
        public static event EventHandler<JoystickButtonEventArgs> JoystickButtonUp;

        /// <summary>
        /// Fires when a joystick hat changes
        /// </summary>
        public static event EventHandler<JoystickHatEventArgs> JoystickHatMotion;

        /// <summary>
        /// Fires when a joystick trackball changes
        /// </summary>
        public static event EventHandler<JoystickBallEventArgs> JoystickBallMotion;

        /// <summary>
        /// Fires when the user resizes the window
        /// </summary>
        public static event EventHandler<VideoResizeEventArgs> VideoResize;

        /// <summary>
        /// Fires when a portion of the window is uncovered
        /// </summary>
        public static event EventHandler<VideoExposeEventArgs> VideoExpose;

        /// <summary>
        /// Fires when a user closes the window
        /// </summary>
        public static event EventHandler<QuitEventArgs> Quit;

        /// <summary>
        /// Fires when a user event is consumed
        /// </summary>
        public static event EventHandler<UserEventArgs> UserEvent;

        /// <summary>
        /// Fires when a sound channel finishes playing.
        /// Will only occur if you call SdlDotNet.Audio.Music.Channel.EnableChannelCallbacks().
        /// </summary>
        public static event EventHandler<ChannelFinishedEventArgs> ChannelFinished;

        /// <summary>
        /// Fires when a music sample finishes playing.
        /// Will only occur if you call SdlDotNet.Audio.Music.EnableMusicCallbacks().
        /// </summary>
        public static event EventHandler<MusicFinishedEventArgs> MusicFinished;

        /// <summary>
        /// Fires every frame.
        /// </summary>
        public static event EventHandler<TickEventArgs> Tick;

        #endregion

        #region Public Methods

        ///// <summary>
        ///// 
        ///// </summary>
        //public static bool IsInitialized
        //{
        //    get { return Events.isInitialized; }
        //}

        /// <summary>
        /// 
        /// </summary>
        public static ResourceManager StringManager
        {
            get { return stringManager; }
            set { stringManager = value; }
        }

        /// <summary>
        /// Closes all SDL subsystems
        /// </summary>
        public static void Close()
        {
            AppActive = null;
            KeyboardDown = null;
            KeyboardUp = null;
            MouseMotion = null;
            MouseButtonDown = null;
            MouseButtonUp = null;
            JoystickAxisMotion = null;
            Tick = null;
            MusicFinished = null;
            ChannelFinished = null;
            VideoExpose = null;
            VideoResize = null;
            UserEvent = null;
            //Quit = null;
            JoystickBallMotion = null;
            JoystickHatMotion = null;
            JoystickButtonUp = null;
            JoystickButtonDown = null;

            //while(Events.Poll());
            Events.CloseJoysticks();
            Events.CloseCDRom();
            Events.CloseMixer();
            Events.CloseTimer();
            Events.CloseVideo();
            Sdl.SDL_Quit();
            Quit = null;
        }

        /// <summary>
        /// Closes and destroys this object
        /// </summary>
        public static void CloseVideo()
        {
            try
            {
                if (Sdl.SDL_WasInit(Sdl.SDL_INIT_VIDEO) != 0)
                {
                    Sdl.SDL_QuitSubSystem(Sdl.SDL_INIT_VIDEO);
                }
            }
            catch (AccessViolationException)
            { }
        }

        /// <summary>
        /// Closes and destroys this object
        /// </summary>
        public static void CloseTimer()
        {
            try
            {
                if (Sdl.SDL_WasInit(Sdl.SDL_INIT_TIMER) != 0)
                {
                    Sdl.SDL_QuitSubSystem(Sdl.SDL_INIT_TIMER);
                }
            }
            catch (AccessViolationException)
            { }
        }

        /// <summary>
        /// Closes and destroys this object
        /// </summary>
        public static void CloseJoysticks()
        {
            try
            {
                if (Sdl.SDL_WasInit(Sdl.SDL_INIT_JOYSTICK) != 0)
                {
                    Sdl.SDL_QuitSubSystem(Sdl.SDL_INIT_JOYSTICK);
                }
            }
            catch (AccessViolationException)
            { }
        }

        /// <summary>
        /// Closes and destroys this object
        /// </summary>
        /// <remarks></remarks>
        public static void CloseCDRom()
        {
            try
            {
                if (Sdl.SDL_WasInit(Sdl.SDL_INIT_CDROM) != 0)
                {
                    Sdl.SDL_QuitSubSystem(Sdl.SDL_INIT_CDROM);
                }
            }
            catch (AccessViolationException)
            { }
        }

        /// <summary>
        /// Closes and destroys this object
        /// </summary>
        public static void CloseMixer()
        {
            try
            {
                SdlMixer.Mix_CloseAudio();
                if (Sdl.SDL_WasInit(Sdl.SDL_INIT_AUDIO) != 0)
                {
                    Sdl.SDL_QuitSubSystem(Sdl.SDL_INIT_AUDIO);
                }
            }
            catch (AccessViolationException)
            { }
        }

        /// <summary>
        /// Call to close the audio subsystem
        /// </summary>
        public static void CloseAudio()
        {
            Sdl.SDL_CloseAudio();

            Mixer.AudioOpen = false;
            Mixer.AudioLocked = false;

            Events.CloseMixer();
        }

        /// <summary>
        /// Checks the event queue, and processes 
        /// any events it finds by invoking the event properties
        /// </summary>
        /// <returns>
        /// True if any events were in the queue, otherwise False
        /// </returns>
        public static bool Poll()
        {
            try
            {
                Sdl.SDL_Event ev;
                int ret = Sdl.SDL_PollEvent(out ev);
                if (ret == (int)SdlFlag.Error)
                {
                    throw SdlException.Generate();
                }
                if (ret == (int)SdlFlag.None)
                {
                    return false;
                }
                else
                {
                    ProcessEvent(ev);
                    return true;
                }
            }
            catch (AccessViolationException)
            {
                return false;
            }
        }

        /// <summary>
        /// Polls and processes a given number of events before returning false
        /// </summary>
        /// <remarks>If the are no more events, the method will return false</remarks>
        /// <param name="numberOfEvents">
        /// Nunmber of events to process at a time at most
        /// </param>
        /// <returns>Returns false when done processing events</returns>
        public static bool Poll(int numberOfEvents)
        {
            Sdl.SDL_Event ev;
            for (int i = 0; i <= numberOfEvents; i++)
            {
                int ret = Sdl.SDL_PollEvent(out ev);
                if (ret == (int)SdlFlag.Error)
                {
                    throw SdlException.Generate();
                }
                if (ret == (int)SdlFlag.None)
                {
                    break;
                }
                else
                {
                    ProcessEvent(ev);
                }
            }
            return false;
        }

        /// <summary>
        /// Checks the event queue, and waits until an event is available
        /// </summary>
        /// <remarks></remarks>
        public static void Wait()
        {
            Sdl.SDL_Event ev;
            if (Sdl.SDL_WaitEvent(out ev) == (int)SdlFlag.Error2)
            {
                throw SdlException.Generate();
            }
            ProcessEvent(ev);
        }

        /// <summary>
        /// Pushes a user-defined event on the event queue
        /// </summary>
        /// <remarks></remarks>
        /// <param name="userEventArgs">
        /// An opaque object representing a user-defined event.
        /// Will be passed back to the UserEvent handler delegate when this event is processed.
        /// </param>
        public static void PushUserEvent(UserEventArgs userEventArgs)
        {
            if (userEventArgs == null)
            {
                throw new ArgumentNullException("userEventArgs");
            }

            lock (instance)
            {
                userEvents[userEventId] = userEventArgs;
                userEventArgs.UserCode = userEventId;
                userEventId++;
            }

            Sdl.SDL_Event evt = userEventArgs.EventStruct;
            if (Sdl.SDL_PushEvent(out evt) != (int)SdlFlag.Success)
            {
                //throw SdlException.Generate();
            }
        }

        /// <summary>
        /// Adds an event to the Event queue.
        /// </summary>
        /// <param name="sdlEvent">Event to add to queue</param>
        public static void Add(SdlEventArgs sdlEvent)
        {
            //      SdlEventArgs[] events = new SdlEventArgs[1];
            //      events[0] = sdlEvent;
            //      Add(events);
            if (sdlEvent == null)
            {
                throw new ArgumentNullException("sdlEvent");
            }
            Sdl.SDL_Event evt = sdlEvent.EventStruct;
            if (Sdl.SDL_PushEvent(out evt) != (int)SdlFlag.Success)
            {
                //throw SdlException.Generate();
            }
        }

        /// <summary>
        /// Adds an array of events to the event queue.
        /// </summary>
        /// <param name="sdlEvents">Array of events to add to queue.</param>
        /// <returns></returns>
        public static void Add(SdlEventArgs[] sdlEvents)
        {
            if (sdlEvents == null)
            {
                throw new ArgumentNullException("sdlEvents");
            }
            //Sdl.SDL_Event[] events = new Sdl.SDL_Event[sdlEvents.Length];
            for (int i = 0; i < sdlEvents.Length; i++)
            {
                Add(sdlEvents[i]);
            }
            //
            //      int result = 
            //        Sdl.SDL_PeepEvents(
            //        events, 
            //        events.Length, 
            //        Sdl.SDL_ADDEVENT, 
            //        (int)EventMask.None);
            //
            //      if (result == (int)SdlFlag.Error)
            //      {
            //        if (quitFlag == false)
            //        {
            //          throw SdlException.Generate();
            //        }
            //      }
        }

        /// <summary>
        /// Raises Event and places it on the event queue
        /// </summary>
        /// <param name="sdlEvent">Event to be raised</param>
        public static void AddEvent(SdlEventArgs sdlEvent)
        {
            Events.Add(sdlEvent);
        }

        /// <summary>
        /// Returns an array of events in the event queue.
        /// </summary>
        /// <param name="eventMask">Mask for event that will be removed from queue</param>
        /// <param name="numberOfEvents">Number of events to remove</param>
        public static void Remove(EventMask eventMask, int numberOfEvents)
        {
            Sdl.SDL_Event[] events = new Sdl.SDL_Event[numberOfEvents];
            Sdl.SDL_PumpEvents();
            int result =
                Sdl.SDL_PeepEvents(
                events,
                events.Length,
                Sdl.SDL_GETEVENT,
                (int)eventMask);
            if (result == (int)SdlFlag.Error)
            {
                throw SdlException.Generate();
            }
        }

        /// <summary>
        /// Remove all events from the queue
        /// </summary>
        public static void Remove()
        {
            Remove(EventMask.AllEvents, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// Remove the last number of events from the queue
        /// </summary>
        /// <param name="numberOfEvents">number of events to remove</param>
        public static void Remove(int numberOfEvents)
        {
            Remove(EventMask.AllEvents, numberOfEvents);
        }

        /// <summary>
        /// Remove all events of a certain type
        /// </summary>
        /// <param name="eventMask">
        /// Events to remove
        /// </param>
        public static void Remove(EventMask eventMask)
        {
            Remove(eventMask, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// Retrieve events of a certain type
        /// </summary>
        /// <param name="eventMask">Event to retrieve</param>
        /// <param name="numberOfEvents">Number of events to retrieve</param>
        /// <returns>Array containing events</returns>
        public static SdlEventArgs[] Retrieve(EventMask eventMask, int numberOfEvents)
        {
            Sdl.SDL_PumpEvents();

            Sdl.SDL_Event[] events = new Sdl.SDL_Event[numberOfEvents];

            int result = Sdl.SDL_PeepEvents(
                events,
                events.Length,
                Sdl.SDL_GETEVENT,
                (int)eventMask
                );

            if (result == (int)SdlFlag.Error)
            {
                throw SdlException.Generate();
            }

            SdlEventArgs[] eventsArray = new SdlEventArgs[result];
            for (int i = 0; i < eventsArray.Length; i++)
            {
                if (events[i].type == (byte)EventTypes.UserEvent)
                {
                    eventsArray[i] = (UserEventArgs)userEvents[events[i].user.code];
                    userEvents.Remove(events[i].user.code);
                }
                else
                {
                    eventsArray[i] = SdlEventArgs.CreateEventArgs(events[i]);
                }
            }

            return eventsArray;
        }

        /// <summary>
        /// Retrieve a certain number of events
        /// </summary>
        /// <param name="numberOfEvents">Number of events to retrieve</param>
        /// <returns>Array of Events</returns>
        public static SdlEventArgs[] Retrieve(int numberOfEvents)
        {
            return Retrieve(EventMask.AllEvents, numberOfEvents);
        }

        /// <summary>
        /// Retrieve all events
        /// </summary>
        /// <returns>Array of events</returns>
        public static SdlEventArgs[] Retrieve()
        {
            return Retrieve(EventMask.AllEvents, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// Retrieve events of a certain type
        /// </summary>
        /// <param name="eventMask">Event to retrieve</param>
        /// <returns>Array containing events</returns>
        public static SdlEventArgs[] Retrieve(EventMask eventMask)
        {
            return Retrieve(eventMask, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// Returns an array of events in the event queue. 
        /// It does not remove them from the event queue.
        /// </summary>
        /// <param name="eventMask">Mask of events to find in queue</param>
        /// <param name="numberOfEvents">Number of events to find in queue</param>
        /// <returns>Array of events in queue.</returns>
        public static SdlEventArgs[] Peek(EventMask eventMask, int numberOfEvents)
        {
            Sdl.SDL_Event[] events = new Sdl.SDL_Event[numberOfEvents];
            Sdl.SDL_PumpEvents();
            int result =
                Sdl.SDL_PeepEvents(
                events,
                events.Length,
                Sdl.SDL_PEEKEVENT,
                (int)eventMask);
            if (result == (int)SdlFlag.Error)
            {
                throw SdlException.Generate();
            }
            SdlEventArgs[] eventsArray = new SdlEventArgs[result];
            for (int i = 0; i < eventsArray.Length; i++)
            {
                if (events[i].type == (byte)EventTypes.UserEvent)
                {
                    eventsArray[i] = (UserEventArgs)userEvents[events[i].user.code];
                }
                else
                {
                    eventsArray[i] = SdlEventArgs.CreateEventArgs(events[i]);
                }
            }
            return eventsArray;
        }
        /// <summary>
        /// View number of events in the queue
        /// </summary>
        /// <param name="numberOfEvents">number of events to retrieve</param>
        /// <returns>Array of events from queue</returns>
        public static SdlEventArgs[] Peek(int numberOfEvents)
        {
            return Peek(EventMask.AllEvents, numberOfEvents);
        }

        /// <summary>
        /// View all events in the queue
        /// </summary>
        /// <returns>Array of all events in queue</returns>
        public static SdlEventArgs[] Peek()
        {
            return Peek(EventMask.AllEvents, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// View all events of a certain type in the queue
        /// </summary>
        /// <param name="eventMask">Type of events to view</param>
        /// <returns>Array of events</returns>
        public static SdlEventArgs[] Peek(EventMask eventMask)
        {
            return Peek(eventMask, QUERY_EVENTS_MAX);
        }

        /// <summary>
        /// check to se if a certain kind of event is queued
        /// </summary>
        /// <param name="eventMask">Mask for event to check for</param>
        /// <returns>If event is queued, then method returns true</returns>
        public static bool IsEventQueued(EventMask eventMask)
        {
            SdlEventArgs[] eventArray = Peek(eventMask, QUERY_EVENTS_MAX);
            if (eventArray.Length > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Disables event from appearing in the queue
        /// </summary>
        /// <param name="eventType">Event to disable</param>
        public static void IgnoreEvent(EventTypes eventType)
        {
            Sdl.SDL_EventState((byte)eventType, Sdl.SDL_IGNORE);
        }

        /// <summary>
        /// Event type will be processed by queue.
        /// </summary>
        /// <remarks>all events are enabled by default</remarks>
        /// <param name="eventType">Event to enable</param>
        public static void EnableEvent(EventTypes eventType)
        {
            Sdl.SDL_EventState((byte)eventType, Sdl.SDL_ENABLE);
        }

        /// <summary>
        /// Check to see if this type of event is enabled
        /// </summary>
        /// <param name="eventType">Event to check to see if it is enabled</param>
        /// <returns>If event is enabled, the method returns true.</returns>
        public static bool IsEventEnabled(EventTypes eventType)
        {
            return (Sdl.SDL_EventState((byte)eventType, Sdl.SDL_QUERY) == Sdl.SDL_ENABLE);
        }

        #endregion

        #region Private Methods

        private static void ProcessEvent(Sdl.SDL_Event ev)
        {
            switch ((EventTypes)ev.type)
            {
                case EventTypes.ActiveEvent:
                    OnActiveEvent(new ActiveEventArgs(ev));
                    break;

                case EventTypes.JoystickAxisMotion:
                    OnJoystickAxisMotion(new JoystickAxisEventArgs(ev));
                    break;

                case EventTypes.JoystickBallMotion:
                    OnJoystickBallMotion(new JoystickBallEventArgs(ev));
                    break;

                case EventTypes.JoystickButtonDown:
                    OnJoystickButtonDown(new JoystickButtonEventArgs(ev));
                    break;

                case EventTypes.JoystickButtonUp:
                    OnJoystickButtonUp(new JoystickButtonEventArgs(ev));
                    break;

                case EventTypes.JoystickHatMotion:
                    OnJoystickHatMotion(new JoystickHatEventArgs(ev));
                    break;

                case EventTypes.KeyDown:
                    OnKeyboardDown(new KeyboardEventArgs(ev));
                    break;

                case EventTypes.KeyUp:
                    OnKeyboardUp(new KeyboardEventArgs(ev));
                    break;

                case EventTypes.MouseButtonDown:
                    OnMouseButtonDown(new MouseButtonEventArgs(ev));
                    break;

                case EventTypes.MouseButtonUp:
                    OnMouseButtonUp(new MouseButtonEventArgs(ev));
                    break;

                case EventTypes.MouseMotion:
                    OnMouseMotion(new MouseMotionEventArgs(ev));
                    break;

                case EventTypes.Quit:
                    OnQuitEvent(new QuitEventArgs(ev));
                    break;

                case EventTypes.UserEvent:
                    OnUserEvent(new UserEventArgs(ev));
                    break;

                case EventTypes.VideoExpose:
                    OnVideoExpose(new VideoExposeEventArgs(ev));
                    break;

                case EventTypes.VideoResize:
                    OnVideoResize(new VideoResizeEventArgs(ev));
                    break;
            }
        }

        static void OnActiveEvent(ActiveEventArgs e)
        {
            if (AppActive != null)
            {
                AppActive(new Events(), e);
            }
        }

        static void OnJoystickAxisMotion(JoystickAxisEventArgs e)
        {
            if (JoystickAxisMotion != null)
            {
                if (((e.RawAxisValue < (-1) * JoystickAxisEventArgs.JoystickThreshold) ||
                    (e.RawAxisValue > JoystickAxisEventArgs.JoystickThreshold)) && (e.AxisIndex == 0 || e.AxisIndex == 1))
                {
                    JoystickAxisMotion(instance, e);
                }
            }
        }

        static void OnJoystickBallMotion(JoystickBallEventArgs e)
        {
            if (JoystickBallMotion != null)
            {
                JoystickBallMotion(instance, e);
            }
        }

        static void OnJoystickButtonDown(JoystickButtonEventArgs e)
        {
            if (JoystickButtonDown != null)
            {
                JoystickButtonDown(instance, e);
            }
        }

        static void OnJoystickButtonUp(JoystickButtonEventArgs e)
        {
            if (JoystickButtonUp != null)
            {
                JoystickButtonUp(instance, e);
            }
        }

        static void OnJoystickHatMotion(JoystickHatEventArgs e)
        {
            if (JoystickHatMotion != null)
            {
                JoystickHatMotion(instance, e);
            }
        }

        static void OnKeyboardDown(KeyboardEventArgs e)
        {
            if (KeyboardDown != null)
            {
                KeyboardDown(instance, e);
            }
        }

        static void OnKeyboardUp(KeyboardEventArgs e)
        {
            if (KeyboardUp != null)
            {
                KeyboardUp(instance, e);
            }
        }

        static void OnMouseButtonDown(MouseButtonEventArgs e)
        {
            if (MouseButtonDown != null)
            {
                MouseButtonDown(instance, e);
            }
        }

        static void OnMouseButtonUp(MouseButtonEventArgs e)
        {
            if (MouseButtonUp != null)
            {
                MouseButtonUp(instance, e);
            }
        }

        static void OnMouseMotion(MouseMotionEventArgs e)
        {
            if (MouseMotion != null)
            {
                MouseMotion(instance, e);
            }
        }

        static void OnQuitEvent(QuitEventArgs e)
        {
            if (Quit != null)
            {
                Quit(instance, e);
            }
        }

        static void OnUserEvent(UserEventArgs e)
        {
            if (UserEvent != null || ChannelFinished != null || MusicFinished != null)
            {
                object ret;
                lock (instance)
                {
                    ret = (UserEventArgs)userEvents[e.UserCode];
                }
                if (ret != null)
                {
                    if (ret.GetType().Name == "ChannelFinishedEventArgs")
                    {
                        if (ChannelFinished != null)
                        {
                            ChannelFinished(instance, (ChannelFinishedEventArgs)ret);
                        }
                    }
                    else if (ret.GetType().Name == "MusicFinishedEventArgs")
                    {
                        if (MusicFinished != null)
                        {
                            MusicFinished(instance, (MusicFinishedEventArgs)ret);
                        }
                    }
                    else
                    {
                        if (UserEvent != null)
                        {
                            UserEvent(instance, (UserEventArgs)ret);
                        }
                    }
                }
                userEvents.Remove(e.UserCode);
            }
        }

        static void OnVideoExpose(VideoExposeEventArgs e)
        {
            if (VideoExpose != null)
            {
                VideoExpose(instance, e);
            }
        }

        static void OnVideoResize(VideoResizeEventArgs e)
        {
            if (VideoResize != null)
            {
                VideoResize(instance, e);
            }
        }

        #endregion

        #region Internal Methods

        internal static void NotifyChannelFinished(int channel)
        {
            PushUserEvent(new ChannelFinishedEventArgs(channel));
        }

        internal static void NotifyMusicFinished()
        {
            PushUserEvent(new MusicFinishedEventArgs());
        }

        internal static void OnTick(TickEventArgs e)
        {
            if (Tick != null)
            {
                Tick(instance, e);
            }
        }

        #endregion

        #region Event Ticker

        private static int targetFps = 60;
        private static int fps = 60;
        private static int lastTick;
        private static float ticksPerFrame = (1000.0f / (float)targetFps);
        private static bool quitFlag;

        /// <summary>
        /// Quits application by raising and quit event.
        /// </summary>
        public static void QuitApplication()
        {
            System.GC.Collect();
            quitFlag = true;
        }

        /// <summary>
        /// Starts the framerate ticker. 
        /// Must be called to start the manager interface.
        /// </summary>
        public static void Run()
        {
            lastTick = 0;
            quitFlag = false;
            Timer.Initialize();
            ThreadTicker();
            Events.Close();
        }

        /// <summary>
        /// Gets the current FPS and sets the wanted framerate.
        /// </summary>
        public static int Fps
        {
            get
            {
                return fps;
            }
            set
            {
                TargetFps = value;
            }
        }

        /// <summary>
        /// Gets and sets the wanted framerate of the ticker.
        /// </summary>
        public static int TargetFps
        {
            get
            {
                return targetFps;
            }
            set
            {
                if (value == 0)
                {
                    targetFps = 1;
                }
                else if (value > 100000 || value == -1)
                {
                    targetFps = 100000;
                }
                else
                {
                    targetFps = value;
                }
                ticksPerFrame = (1000.0f / (float)targetFps);
            }
        }

        /// <summary>
        /// The private method, run by the ticker thread, 
        /// that controls timing to call the event.
        /// </summary>
        private static void ThreadTicker()
        {
            int frames = 0;
            int lastTime = Timer.TicksElapsed;
            int currentTime;
            int currentTick;
            int targetTick;

            while (!quitFlag)
            {

                // Poll all events
                while (Events.Poll()) ;
                currentTick = Timer.TicksElapsed;
                targetTick = lastTick + (int)ticksPerFrame;

                if (currentTick <= targetTick)
                {
                    // Using Thread
                    Thread.Sleep(targetTick - currentTick);
                }
                currentTick = Timer.TicksElapsed;

                Events.OnTick(new TickEventArgs(currentTick, lastTick, fps));
                lastTick = currentTick;
                currentTime = Timer.TicksElapsed;
                frames++;
                if (lastTime + 1000 <= currentTime)
                {
                    fps = frames;
                    frames = 0;
                    lastTime = currentTime;
                }
            }
        }

        #endregion
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.