aboutsummaryrefslogtreecommitdiffstats
path: root/src/menu/event_manager.hpp
blob: e8d42c3dcf71af5ddbacd99e2ac8617396c0ff73 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef EVENT_MANAGER_HPP
#define EVENT_MANAGER_HPP

#include <SDL/SDL.h>

#include <boost/bind.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/progress.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/signals2.hpp>

#include <log4cpp/Category.hh>

#include "utils/point.hpp"

namespace usdx
{
	/**
	 * This class is the junction point between the SDL Thread (with the SDL
	 * main loop) and the event thread. The EventManager buffers the SDL
	 * Events until the thread has time to handle the events. Because one
	 * thread pushes the events and an other thread is reading the access to
	 * the buffer have to be mutual exclusive.
	 */
	class EventManager
	{
	private:
		static log4cpp::Category&  log;

		EventManager(const EventManager&);		//< no copy
		EventManager& operator=(const EventManager&);	//< no assignment

		/**
		 * Type of the buffer for the Events.
		 */
		typedef boost::circular_buffer<const SDL_Event*> buffer_type;

		/**
		 * Buffer to store the events.
		 */
		buffer_type buffer;

		/**
		 * How many events currently waiting to getting handled.
		 */
		buffer_type::size_type waiting;

		/**
		 * Mutex to guaranty the mutual exclusion between the multiple
		 * threads.
		 */
		mutable boost::shared_mutex mutex;

		boost::condition not_empty;
		boost::condition not_full;

		/**
		 * Returns if the buffer is contains at least one element or
		 * not.
		 * This functions is not thread-safe! Intended to use as
		 * condition for boost::condition#wait.
		 */
		bool is_not_empty() const;

		/**
		 * Returns if the buffer has at least space for one element left
		 * or not.
		 * This functions is not thread-safe! Intended to use as
		 * condition for boost::condition#wait.
		 */
		bool is_not_full() const;

		/**
		 * This function is used to get the next event from the
		 * buffer. If no event is waiting, this method blocks until
		 * there is one event available.
		 */
		void get_next_event(SDL_Event& event);

	public:
		EventManager(int capacity = 20);
		virtual ~EventManager();

		void add_event(const SDL_Event& item);

		/**
		 * This function is intended to be used as separate thread. It
		 * will run forever until for example a
		 * boost::thread_interrupted is thrown.
		 */
		void handle_events(void);

		/**
		 * This function returns (thread-safe) weather there is space in
		 * left the buffer for a new element or not.
		 */
		bool available(void);


		boost::signals2::signal<void (const Point<int>&)> mouse_move;
		boost::signals2::signal<void (uint8_t, const Point<int>&)> mouse_down;
		boost::signals2::signal<void (uint8_t, const Point<int>&)> mouse_up;
	};
}

#endif