diff options
Diffstat (limited to 'mwe/events/src')
| -rw-r--r-- | mwe/events/src/event.cpp | 52 | ||||
| -rw-r--r-- | mwe/events/src/eventHandler.cpp | 2 | ||||
| -rw-r--r-- | mwe/events/src/eventManager.cpp | 130 | ||||
| -rw-r--r-- | mwe/events/src/keyCodes.cpp | 139 | ||||
| -rw-r--r-- | mwe/events/src/loopManager.cpp | 87 | ||||
| -rw-r--r-- | mwe/events/src/main.cpp | 82 | ||||
| -rw-r--r-- | mwe/events/src/timer.cpp | 53 | ||||
| -rw-r--r-- | mwe/events/src/window.cpp | 29 | 
8 files changed, 574 insertions, 0 deletions
| diff --git a/mwe/events/src/event.cpp b/mwe/events/src/event.cpp new file mode 100644 index 0000000..c9201d0 --- /dev/null +++ b/mwe/events/src/event.cpp @@ -0,0 +1,52 @@ +#include "event.h" +#include "keyCodes.h" +// Event class methods +Event::Event(std::string eventType) { eventData["eventType"] = eventType; } + +void Event::addArgument(const std::string & key, +						const std::variant<int, std::string, float> & value) { +	eventData[key] = value; +} + +std::variant<int, std::string, float> +Event::getArgument(const std::string & key) const { +	return eventData.at(key); +} + +std::string Event::getType() const { +	return std::get<std::string>(eventData.at("eventType")); +} +std::string Event::toString() const { return std::to_string(getEventType()); } +bool Event::getHandled() const { return isHandled; } + +void Event::markHandled() { isHandled = true; } + +// KeyPressedEvent class methods +KeyPressedEvent::KeyPressedEvent(int keycode) +	: Event("KeyPressedEvent"), key(keycode), repeatCount(0) {} + +Keycode KeyPressedEvent::getKeyCode() const { return key; } + +int KeyPressedEvent::getRepeatCount() const { return repeatCount; } + +// KeyReleasedEvent class methods +KeyReleasedEvent::KeyReleasedEvent(int keycode) +	: Event("KeyReleasedEvent"), key(keycode) {} + +Keycode KeyReleasedEvent::getKeyCode() const { return key; } + +// MousePressedEvent class methods +MousePressedEvent::MousePressedEvent(int mouseX, int mouseY) +	: Event("MousePressedEvent"), mouseX(mouseX), mouseY(mouseY) {} + +std::pair<int, int> MousePressedEvent::getMousePosition() const { +	return {mouseX, mouseY}; +} + +//Collision event +CollisionEvent::CollisionEvent(Collision collision) +	: collisionData(collision), Event("CollisionEvent") {} + +Collision CollisionEvent::getCollisionData() const { +	return this->collisionData; +} diff --git a/mwe/events/src/eventHandler.cpp b/mwe/events/src/eventHandler.cpp new file mode 100644 index 0000000..7fb8d70 --- /dev/null +++ b/mwe/events/src/eventHandler.cpp @@ -0,0 +1,2 @@ +#include "eventHandler.h" +void IEventHandlerWrapper::exec(const Event & e) { call(e); } diff --git a/mwe/events/src/eventManager.cpp b/mwe/events/src/eventManager.cpp new file mode 100644 index 0000000..34a093d --- /dev/null +++ b/mwe/events/src/eventManager.cpp @@ -0,0 +1,130 @@ +#include "eventManager.h" + +void EventManager::shutdown() { subscribers.clear(); } + +void EventManager::subscribe(int eventType, +							 std::unique_ptr<IEventHandlerWrapper> && handler, +							 int eventId) { +	if (eventId) { +		std::unordered_map< +			int, std::unordered_map< +					 int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: +			iterator subscribers +			= subscribersByEventId.find(eventType); + +		if (subscribers != subscribersByEventId.end()) { +			std::unordered_map< +				int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & +				handlersMap +				= subscribers->second; +			std::unordered_map< +				int, +				std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator +				handlers +				= handlersMap.find(eventId); +			if (handlers != handlersMap.end()) { +				handlers->second.emplace_back(std::move(handler)); +				return; +			} +		} +		subscribersByEventId[eventType][eventId].emplace_back( +			std::move(handler)); + +	} else { +		auto & handlers = subscribers[eventType]; +		handlers.emplace_back(std::move(handler)); +	} +} + +void EventManager::unsubscribe(int eventType, const std::string & handlerName, +							   int eventId) { +	if (eventId) { +		std::unordered_map< +			int, std::unordered_map< +					 int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>>:: +			iterator subscriberList +			= subscribersByEventId.find(eventType); +		if (subscriberList != subscribersByEventId.end()) { +			std::unordered_map< +				int, std::vector<std::unique_ptr<IEventHandlerWrapper>>> & +				handlersMap +				= subscriberList->second; +			std::unordered_map< +				int, +				std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator +				handlers +				= handlersMap.find(eventId); +			if (handlers != handlersMap.end()) { +				std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks +					= handlers->second; +				for (std::vector< +						 std::unique_ptr<IEventHandlerWrapper>>::iterator it +					 = callbacks.begin(); +					 it != callbacks.end(); ++it) { +					if (it->get()->getType() == handlerName) { +						it = callbacks.erase(it); +						return; +					} +				} +			} +		} +	} else { +		std::unordered_map< +			int, std::vector<std::unique_ptr<IEventHandlerWrapper>>>::iterator +			handlersIt +			= subscribers.find(eventType); +		if (handlersIt != subscribers.end()) { +			std::vector<std::unique_ptr<IEventHandlerWrapper>> & handlers +				= handlersIt->second; +			for (std::vector<std::unique_ptr<IEventHandlerWrapper>>::iterator it +				 = handlers.begin(); +				 it != handlers.end(); ++it) { +				if (it->get()->getType() == handlerName) { +					it = handlers.erase(it); +					return; +				} +			} +		} +	} +} + +void EventManager::triggerEvent(const Event & event_, int eventId) { +	if (eventId > 0) { +		auto handlersIt +			= subscribersByEventId[event_.getEventType()].find(eventId); +		if (handlersIt != subscribersByEventId[event_.getEventType()].end()) { +			std::vector<std::unique_ptr<IEventHandlerWrapper>> & callbacks +				= handlersIt->second; +			for (auto it = callbacks.begin(); it != callbacks.end();) { +				(*it)->exec(event_); +				if ((*it)->isDestroyOnSuccess()) { +					it = callbacks.erase(it); +				} else { +					++it; +				} +			} +		} +	} else { +		auto & handlers = subscribers[event_.getEventType()]; +		for (std::unique_ptr<IEventHandlerWrapper> & handler : handlers) { +			handler->exec(event_); +		} +	} +} + +void EventManager::queueEvent(std::unique_ptr<Event> && event_, int eventId) { +	eventsQueue.emplace_back(std::move(event_), eventId); +} + +void EventManager::dispatchEvents() { +	for (std::vector<std::pair<std::unique_ptr<Event>, int>>::iterator eventIt +		 = eventsQueue.begin(); +		 eventIt != eventsQueue.end();) { +		if (!eventIt->first.get()->getHandled()) { +			triggerEvent(*eventIt->first.get(), eventIt->second); +			eventIt = eventsQueue.erase(eventIt); +		} else { +			++eventIt; +		} +	} +} diff --git a/mwe/events/src/keyCodes.cpp b/mwe/events/src/keyCodes.cpp new file mode 100644 index 0000000..5f3aa96 --- /dev/null +++ b/mwe/events/src/keyCodes.cpp @@ -0,0 +1,139 @@ +#include "keyCodes.h" + +const std::unordered_map<SDL_Keycode, Keycode> sdlToCustom +	= {{SDLK_SPACE, Space}, +	   {SDLK_QUOTE, Apostrophe}, +	   {SDLK_COMMA, Comma}, +	   {SDLK_MINUS, Minus}, +	   {SDLK_PERIOD, Period}, +	   {SDLK_SLASH, Slash}, + +	   {SDLK_0, D0}, +	   {SDLK_1, D1}, +	   {SDLK_2, D2}, +	   {SDLK_3, D3}, +	   {SDLK_4, D4}, +	   {SDLK_5, D5}, +	   {SDLK_6, D6}, +	   {SDLK_7, D7}, +	   {SDLK_8, D8}, +	   {SDLK_9, D9}, + +	   {SDLK_SEMICOLON, Semicolon}, +	   {SDLK_EQUALS, Equal}, + +	   {SDLK_a, A}, +	   {SDLK_b, B}, +	   {SDLK_c, C}, +	   {SDLK_d, D}, +	   {SDLK_e, E}, +	   {SDLK_f, F}, +	   {SDLK_g, G}, +	   {SDLK_h, H}, +	   {SDLK_i, I}, +	   {SDLK_j, J}, +	   {SDLK_k, K}, +	   {SDLK_l, L}, +	   {SDLK_m, M}, +	   {SDLK_n, N}, +	   {SDLK_o, O}, +	   {SDLK_p, P}, +	   {SDLK_q, Q}, +	   {SDLK_r, R}, +	   {SDLK_s, S}, +	   {SDLK_t, T}, +	   {SDLK_u, U}, +	   {SDLK_v, V}, +	   {SDLK_w, W}, +	   {SDLK_x, X}, +	   {SDLK_y, Y}, +	   {SDLK_z, Z}, + +	   {SDLK_LEFTBRACKET, LeftBracket}, +	   {SDLK_BACKSLASH, Backslash}, +	   {SDLK_RIGHTBRACKET, RightBracket}, +	   {SDLK_BACKQUOTE, GraveAccent}, + +	   {SDLK_ESCAPE, Escape}, +	   {SDLK_RETURN, Enter}, +	   {SDLK_TAB, Tab}, +	   {SDLK_BACKSPACE, Backspace}, +	   {SDLK_INSERT, Insert}, +	   {SDLK_DELETE, Delete}, +	   {SDLK_RIGHT, Right}, +	   {SDLK_LEFT, Left}, +	   {SDLK_DOWN, Down}, +	   {SDLK_UP, Up}, +	   {SDLK_PAGEUP, PageUp}, +	   {SDLK_PAGEDOWN, PageDown}, +	   {SDLK_HOME, Home}, +	   {SDLK_END, End}, + +	   {SDLK_CAPSLOCK, CapsLock}, +	   {SDLK_SCROLLLOCK, ScrollLock}, +	   {SDLK_NUMLOCKCLEAR, NumLock}, +	   {SDLK_PRINTSCREEN, PrintScreen}, +	   {SDLK_PAUSE, Pause}, + +	   {SDLK_F1, F1}, +	   {SDLK_F2, F2}, +	   {SDLK_F3, F3}, +	   {SDLK_F4, F4}, +	   {SDLK_F5, F5}, +	   {SDLK_F6, F6}, +	   {SDLK_F7, F7}, +	   {SDLK_F8, F8}, +	   {SDLK_F9, F9}, +	   {SDLK_F10, F10}, +	   {SDLK_F11, F11}, +	   {SDLK_F12, F12}, +	   {SDLK_F13, F13}, +	   {SDLK_F14, F14}, +	   {SDLK_F15, F15}, +	   {SDLK_F16, F16}, +	   {SDLK_F17, F17}, +	   {SDLK_F18, F18}, +	   {SDLK_F19, F19}, +	   {SDLK_F20, F20}, +	   {SDLK_F21, F21}, +	   {SDLK_F22, F22}, +	   {SDLK_F23, F23}, +	   {SDLK_F24, F24}, + +	   {SDLK_KP_0, KP0}, +	   {SDLK_KP_1, KP1}, +	   {SDLK_KP_2, KP2}, +	   {SDLK_KP_3, KP3}, +	   {SDLK_KP_4, KP4}, +	   {SDLK_KP_5, KP5}, +	   {SDLK_KP_6, KP6}, +	   {SDLK_KP_7, KP7}, +	   {SDLK_KP_8, KP8}, +	   {SDLK_KP_9, KP9}, + +	   {SDLK_KP_DECIMAL, KPDecimal}, +	   {SDLK_KP_DIVIDE, KPDivide}, +	   {SDLK_KP_MULTIPLY, KPMultiply}, +	   {SDLK_KP_MINUS, KPSubtract}, +	   {SDLK_KP_PLUS, KPAdd}, +	   {SDLK_KP_ENTER, KPEnter}, +	   {SDLK_KP_EQUALS, KPEqual}, + +	   {SDLK_LSHIFT, LeftShift}, +	   {SDLK_LCTRL, LeftControl}, +	   {SDLK_LALT, LeftAlt}, +	   {SDLK_LGUI, LeftSuper}, + +	   {SDLK_RSHIFT, RightShift}, +	   {SDLK_RCTRL, RightControl}, +	   {SDLK_RALT, RightAlt}, +	   {SDLK_RGUI, RightSuper}, + +	   {SDLK_MENU, Menu}}; +Keycode getCustomKey(SDL_Keycode sdlKey) { +	auto it = sdlToCustom.find(sdlKey); +	if (it != sdlToCustom.end()) { +		return it->second; +	} +	return 0; +} diff --git a/mwe/events/src/loopManager.cpp b/mwe/events/src/loopManager.cpp new file mode 100644 index 0000000..8ecb932 --- /dev/null +++ b/mwe/events/src/loopManager.cpp @@ -0,0 +1,87 @@ +#include "loopManager.h" + +LoopManager::LoopManager() {} +void LoopManager::processInput() { +	SDL_Event event; +	SDL_PollEvent(&event); +	switch (event.type) { +		case SDL_QUIT: +			gameRunning = false; +			break; +		case SDL_KEYDOWN: +			triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); +			break; +		case SDL_MOUSEBUTTONDOWN: +			int x, y; +			SDL_GetMouseState(&x, &y); +			triggerEvent(MousePressedEvent(x, y)); +			break; +	} +} +void LoopManager::setRunning(bool running) { this->gameRunning = running; } +void LoopManager::fixedUpdate() { +	//fprintf(stderr, "fixed update\n"); +} +void LoopManager::loop() { +	LoopTimer & timer = LoopTimer::getInstance(); +	timer.start(); + +	while (gameRunning) { +		timer.update(); + +		while (timer.getLag() >= timer.getFixedDeltaTime()) { +			processInput(); +			fixedUpdate(); +			timer.advanceFixedUpdate(); +		} + +		update(); +		render(); + +		timer.enforceFrameRate(); +	} + +	window.destroyWindow(); +} +void onKey(const KeyPressedEvent & e) { +	int keyCode = e.getKeyCode(); +	std::cout << "keycode pressed: " << keyCode << std::endl; +} +void onMouse(const MousePressedEvent & e) { +	fprintf(stderr, "mouse Position X: %d Y: %d\n", e.getMousePosition().first, +			e.getMousePosition().second); +} +void LoopManager::setup() { +	gameRunning = window.initWindow(); +	LoopTimer::getInstance().start(); +	LoopTimer::getInstance().setFPS(50); +	EventHandler<KeyPressedEvent> callback = onKey; +	subscribe<KeyPressedEvent>(callback, false); +	EventHandler<MousePressedEvent> mouseCallback = onMouse; +	subscribe<MousePressedEvent>(mouseCallback, false); +	EventHandler<KeyPressedEvent> closeWindowCallback +		= [this](const KeyPressedEvent & e) { +			  if (e.getKeyCode() == Escape) { +				  this->setRunning(false); +			  } +		  }; +	subscribe<KeyPressedEvent>(closeWindowCallback, false); +} +void LoopManager::render() { +	//fprintf(stderr, "**********render********** \n"); +	if (gameRunning) { +		//window.render(objectList); +	} +} + +void LoopManager::update() { +	//fprintf(stderr, "**********normal update********** \n"); +	LoopTimer & timer = LoopTimer::getInstance(); + +	float delta = timer.getDeltaTime(); + +	// for (int i = 0; i < objectList.size(); i++) { +	// 	objectList[i]->setX(objectList[i]->getX() + 50 * delta); +	// 	objectList[i]->setY(objectList[i]->getY() + 50 * delta); +	// } +} diff --git a/mwe/events/src/main.cpp b/mwe/events/src/main.cpp new file mode 100644 index 0000000..f7e0766 --- /dev/null +++ b/mwe/events/src/main.cpp @@ -0,0 +1,82 @@ +#include "customTypes.h" +#include "event.h" +#include "loopManager.h" +#include <SDL2/SDL.h> +#include <iostream> +#include <memory> +class PlayerDamagedEvent : public Event { +public: +	PlayerDamagedEvent(int damage, int playerID) +		: Event("PlayerDamaged"), damage(damage), playerID(playerID) {} + +	REGISTER_EVENT_TYPE(PlayerDamagedEvent); + +	int getDamage() const { return damage; } +	int getPlayerID() const { return playerID; } + +private: +	int damage; +	int playerID; +}; +void onPlayerDamaged(const PlayerDamagedEvent & e) { +	std::cout << "Player " << e.getPlayerID() << " took " << e.getDamage() +			  << " damage." << std::endl; +} + +void onKeyPressed1(const KeyPressedEvent & e) { +	int keyCode = e.getKeyCode(); +	fprintf(stderr, "first function KeyCode %d\n", keyCode); +} +void onKeyPressed(const KeyPressedEvent & e) { +	int keyCode = e.getKeyCode(); +	fprintf(stderr, "second function KeyCode %d\n", keyCode); +} +void CollisionHandler(const CollisionEvent & e) { +	std::cout << "collision betwee object id: " +			  << e.getCollisionData().objectIdA +			  << " and id: " << e.getCollisionData().objectIdB << std::endl; +} +void testCollisionEvent() { +	Collision testCollision(1, 2, {3, 4}, {5, 6}, 7.8f); +	subscribe<CollisionEvent>(CollisionHandler, 1); +	// EventHandler<PlayerDamagedEvent> +	triggerEvent(CollisionEvent(testCollision), 1); +} +int main(int argc, char * args[]) { +	LoopManager gameLoop; +	// Create an event handler for KeyPressedEvent +	// EventHandler<KeyPressedEvent> callback = [](const KeyPressedEvent& e) { +	//     onKeyPressed(e); +	// }; +	// custom event class poc +	subscribe<PlayerDamagedEvent>(onPlayerDamaged); +	triggerEvent(PlayerDamagedEvent(50, 1)); +	subscribe<KeyPressedEvent>(onKeyPressed, 1, false); +	subscribe<KeyPressedEvent>(onKeyPressed1, false); +	// queueEvent(std::move(anotherKeyPressEvent)); +	triggerEvent(KeyPressedEvent(42), 1); + +	EventManager::getInstance().dispatchEvents(); +	//collision event call +	testCollisionEvent(); + +	gameLoop.setup(); +	gameLoop.loop(); +	return 0; +} +// void collisionUpdate(){ +// 	int count; +// 	//iedere collision +// 	for (int i = 0; i < count; i++) +// 	{ +// 		//trigger object 1 +// 		//triger object 2 +// 		triggerEvent(CollisionEvent(1,2),1); +// 		triggerEvent(CollisionEvent(1,2),2); +// 	} + +// } +// int main(){ + +// 	return 0; +// } diff --git a/mwe/events/src/timer.cpp b/mwe/events/src/timer.cpp new file mode 100644 index 0000000..0b89bf5 --- /dev/null +++ b/mwe/events/src/timer.cpp @@ -0,0 +1,53 @@ +#include "timer.h" + +LoopTimer::LoopTimer() {} +LoopTimer & LoopTimer::getInstance() { +	static LoopTimer instance; +	return instance; +} + +void LoopTimer::start() { +	lastFrameTime = SDL_GetTicks64(); +	elapsedTime = 0; +	elapsedFixedTime = 0; +	deltaTime = 0; +} + +// Update the timer, calculate deltaTime +void LoopTimer::update() { +	uint64_t currentFrameTime = SDL_GetTicks64(); +	deltaTime = (currentFrameTime - lastFrameTime) / 1000.0; + +	if (deltaTime > maximumDeltaTime) { +		deltaTime = maximumDeltaTime; +	} + +	elapsedTime += deltaTime; +	lastFrameTime = currentFrameTime; +} + +double LoopTimer::getDeltaTime() const { return deltaTime; } +int LoopTimer::getCurrentTime() const { return SDL_GetTicks(); } + +void LoopTimer::advanceFixedUpdate() { elapsedFixedTime += fixedDeltaTime; } + +double LoopTimer::getFixedDeltaTime() const { return fixedDeltaTime; } + +void LoopTimer::setFPS(int FPS) { +	this->FPS = FPS; +	frameTargetTime = 1.0 / FPS; +} + +int LoopTimer::getFPS() const { return FPS; } + +void LoopTimer::enforceFrameRate() { +	uint64_t currentFrameTime = SDL_GetTicks64(); +	double frameDuration = (currentFrameTime - lastFrameTime) / 1000.0; + +	if (frameDuration < frameTargetTime) { +		uint32_t delayTime +			= (uint32_t) ((frameTargetTime - frameDuration) * 1000.0); +		SDL_Delay(delayTime); +	} +} +double LoopTimer::getLag() const { return elapsedTime - elapsedFixedTime; } diff --git a/mwe/events/src/window.cpp b/mwe/events/src/window.cpp new file mode 100644 index 0000000..41eb85f --- /dev/null +++ b/mwe/events/src/window.cpp @@ -0,0 +1,29 @@ +#include "window.h" +WindowManager::WindowManager() {} +WindowManager::~WindowManager() { destroyWindow(); } +SDL_Renderer * WindowManager::getRenderer() { return renderer; } + +bool WindowManager::initWindow() { +	if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { +		fprintf(stderr, "Error inititalising SDL.\n"); +		return false; +	} +	window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, +							  SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, +							  SCREEN_HEIGHT, SDL_WINDOW_SHOWN); +	if (!window) { +		fprintf(stderr, "Error creating SDL Window. \n"); +		return false; +	} +	renderer = SDL_CreateRenderer(window, -1, 0); +	if (!renderer) { +		fprintf(stderr, "Error creating SDL renderer. \n"); +		return false; +	} +	return true; +} +void WindowManager::destroyWindow() { +	SDL_DestroyRenderer(renderer); +	SDL_DestroyWindow(window); +	SDL_Quit(); +} |