#include "MessageHandler.h" #include "MessageObserver.h" MessageHandler::MessageHandler() { // Set up messages keyboardMessageMap.reserve(sf::Keyboard::KeyCount); keyboardControllMap.reserve(sf::Keyboard::KeyCount); mouseMessageMap.reserve(sf::Mouse::ButtonCount); } MessageHandler::~MessageHandler() {} // Load Key Bindings from a File void MessageHandler::loadMessagesFromFile(std::string filePath) { loadingKeys.startTime(); std::ifstream infile(filePath); int keyNumber, keyCode; std::string message; std::string correspondingKey; // Read a line from current file std::string textLine; auto cuntLineNumber = 0; while (getline(infile, textLine)) { cuntLineNumber++; if (!textLine.empty()) { std::stringstream parseToken(textLine); // Parse into correct format if (((parseToken >> keyNumber).fail()) || (parseToken >> keyCode).fail() || (parseToken >> message).fail() || (parseToken >> correspondingKey).fail() ) { // Invalid line from file std::cout << "Mapping Keys: The Line is invalid: " << cuntLineNumber << std::endl; continue; } //Change keyCode into correct type switch (keyNumber) { // Keyboard case 0: if (keyCode > sf::Keyboard::KeyCount || keyCode < 0) { std::cout << "The Keyboard code is out of range. At Line: " << cuntLineNumber << std::endl; continue; } keyboardMessageMap.erase(sf::Keyboard::Key(keyCode)); keyboardMessageMap.emplace(sf::Keyboard::Key(keyCode), message); keyboardControllMap.erase(sf::Keyboard::Key(keyCode)); keyboardControllMap.emplace(sf::Keyboard::Key(keyCode), correspondingKey); break; // Mouse case 1: if (keyCode > sf::Mouse::ButtonCount || keyCode < 0) { std::cout << "The Mouse code is out of range. At Line: " << cuntLineNumber << std::endl; continue; } mouseMessageMap.erase(sf::Mouse::Button(keyCode)); mouseMessageMap.emplace(sf::Mouse::Button(keyCode), message); mouseControllMap.erase(sf::Mouse::Button(keyCode)); mouseControllMap.emplace(sf::Mouse::Button(keyCode), correspondingKey); if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) { message.append(correspondingKey); } break; // Invalid number default:; std::cout << "Mapping Keys:: The map number is invalid. At Line: " << cuntLineNumber << std::endl; } } } loadingKeys.finishProfiler(); } // Print the Key bindings for the player void MessageHandler::printKeyMap() { std::cout << "Keyboard Keybindings " << std::endl; std::cout << "KeyCode\tFunction" << std::endl; for (auto assign : keyboardMessageMap) { std::cout << assign.first << "\t" << assign.second << std::endl; } std::cout << "Keyboard Button: " << std::endl; std::cout << "KeyCode\tButton" << std::endl; for (auto assign : keyboardControllMap) { std::cout << assign.first << "\t" << assign.second << std::endl; } std::cout << "\nMouse Keybindings " << std::endl; std::cout << "KeyCode\tFunction" << std::endl; for (auto assign : mouseMessageMap) { std::cout << assign.first << "\t" << assign.second << std::endl; } std::cout << "Mouse Button: " << std::endl; std::cout << "KeyCode\tFunction" << std::endl; for (auto assign : mouseControllMap) { std::cout << assign.first << "\t" << assign.second << std::endl; } } // Add Message Observer void MessageHandler::addMessageObserver(MessageObserver* message) { messageList.push_front(message); } // Remove Message Observer void MessageHandler::removeMessageObserver(MessageObserver* message) { messageList.remove(message); } // Process Messages - Events void MessageHandler::processMessages() { // Keyboard messages for (auto assign : keyboardMessageMap) { auto messageKey = assign.first; MessageState currentMessageState; // Check for previous previous message states - If there are no previous message states if(keyboardState.count(messageKey) > 0) { currentMessageState = advanceMessageState(keyboardState[messageKey], sf::Keyboard::isKeyPressed(messageKey)); } // check for valid message states - If no valid message state - set as UP message State else { currentMessageState = advanceMessageState(MessageState::UP_STATE, sf::Keyboard::isKeyPressed(messageKey)); } keyboardState[messageKey] = currentMessageState; MessageEvent message{0, assign.second, currentMessageState }; sendMessage(message); } //Mouse messages for (auto assign : mouseMessageMap) { auto button = assign.first; MessageState currentMessageState; // check for valid message states- If there are previous message states if (mouseState.count(button) > 0) { currentMessageState = advanceMessageState(mouseState[button], sf::Mouse::isButtonPressed(button)); } // check for valid message states - if no valid message state - set as UP message State else { currentMessageState = advanceMessageState(MessageState::UP_STATE, sf::Mouse::isButtonPressed(button)); } mouseState[button] = currentMessageState; MessageEvent message{ 1, assign.second, currentMessageState, sf::Mouse::getPosition() }; sendMessage(message); } } // Step through the Message States MessageState MessageHandler::advanceMessageState(MessageState current, bool isKeyPressed) { //Update new message state based on old message state and proceed MessageState newMessageState; switch (current) { case MessageState::PRESSED_STATE: case MessageState::DOWN_STATE: { if (isKeyPressed) newMessageState = MessageState::DOWN_STATE; else newMessageState = MessageState::RELEASED_STATE; break; } case MessageState::RELEASED_STATE: case MessageState::UP_STATE: { if (isKeyPressed) newMessageState = MessageState::PRESSED_STATE; else newMessageState = MessageState::UP_STATE; break; } default: newMessageState = MessageState::UP_STATE; } return newMessageState; } // Send message void MessageHandler::sendMessage(MessageEvent message) { for (auto iterator = messageList.begin(), end = messageList.end(); iterator != end; ++iterator) { (*iterator)->onNotify(message); } }