Refactored the input queue to use the new queue type
- Removed all traces of the previous inputMessageQueue type. - Removed the pointer "next" in inputMessage. - Rewrote the the main thread and game logic thread to use a queue for input.
This commit is contained in:
parent
8ae3eaf2b8
commit
9b3df5928b
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "queue.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "gamelogic.h"
|
#include "gamelogic.h"
|
||||||
#include "playerdata.h"
|
#include "playerdata.h"
|
||||||
|
@ -28,25 +29,21 @@ void * gameLogicLoop(void * parameters)
|
||||||
{
|
{
|
||||||
evaluateNextCommand(threadParameters, commandQueue);
|
evaluateNextCommand(threadParameters, commandQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for new messages and pop them off the queue:
|
// Check for new messages and pop them off the queue:
|
||||||
if(threadParameters->inputQueue->currentLength != 0)
|
if(threadParameters->inputQueue->itemCount != 0)
|
||||||
{
|
{
|
||||||
while(threadParameters->inputQueue->lock == true);
|
while(threadParameters->inputQueue->lock == true);
|
||||||
threadParameters->inputQueue->lock = true;
|
threadParameters->inputQueue->lock = true;
|
||||||
currentInput = peekInputMessage(threadParameters->inputQueue);
|
currentInput = peekQueue(threadParameters->inputQueue)->data.inputMessage;
|
||||||
userInputSanatize(currentInput->content->messageContent, MAX);
|
userInputSanatize(currentInput->content->messageContent, MAX);
|
||||||
// A slash as the first character means the message is a user command:
|
// A slash as the first character means the message is a user command:
|
||||||
if(currentInput->content->messageContent[0] == '/')
|
if(currentInput->content->messageContent[0] == '/')
|
||||||
{
|
{
|
||||||
queueMessagedCommand(commandQueue, currentInput);
|
queueMessagedCommand(commandQueue, currentInput);
|
||||||
}
|
}
|
||||||
else if(currentInput->sender->currentArea == getFromList(threadParameters->areaList, 0)->area)
|
|
||||||
{
|
else if (!(currentInput->sender->currentArea == getFromList(threadParameters->areaList, 0)->area))
|
||||||
currentInput = NULL;
|
|
||||||
threadParameters->inputQueue->lock = false;
|
|
||||||
dequeueInputMessage(threadParameters->inputQueue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
strncpy(currentInput->content->senderName, currentInput->sender->playerName, 32);
|
strncpy(currentInput->content->senderName, currentInput->sender->playerName, 32);
|
||||||
// Create an array of players in the same area to receive the message:
|
// Create an array of players in the same area to receive the message:
|
||||||
|
@ -72,7 +69,7 @@ void * gameLogicLoop(void * parameters)
|
||||||
}
|
}
|
||||||
currentInput = NULL;
|
currentInput = NULL;
|
||||||
threadParameters->inputQueue->lock = false;
|
threadParameters->inputQueue->lock = false;
|
||||||
dequeueInputMessage(threadParameters->inputQueue);
|
popQueue(threadParameters->inputQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
|
|
|
@ -2,11 +2,15 @@
|
||||||
// Barry Kane, 2022.
|
// Barry Kane, 2022.
|
||||||
#ifndef GAMELOGIC_H
|
#ifndef GAMELOGIC_H
|
||||||
#define GAMELOGIC_H
|
#define GAMELOGIC_H
|
||||||
|
#include "queue.h"
|
||||||
#include "areadata.h"
|
#include "areadata.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "playerdata.h"
|
#include "playerdata.h"
|
||||||
#include "inputoutput.h"
|
#include "inputoutput.h"
|
||||||
|
|
||||||
|
// Let the compiler know there will be structs defined elsewhere:
|
||||||
|
typedef struct queue queue;
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// -=[ Main Game Loop ]=-:
|
// -=[ Main Game Loop ]=-:
|
||||||
// =======================
|
// =======================
|
||||||
|
@ -17,7 +21,7 @@ typedef struct gameLogicParameters
|
||||||
int * playerCount;
|
int * playerCount;
|
||||||
list * areaList;
|
list * areaList;
|
||||||
playerInfo * connectedPlayers;
|
playerInfo * connectedPlayers;
|
||||||
inputMessageQueue * inputQueue;
|
queue * inputQueue;
|
||||||
outputMessageQueue * outputQueue;
|
outputMessageQueue * outputQueue;
|
||||||
list * globalSkillList;
|
list * globalSkillList;
|
||||||
} gameLogicParameters;
|
} gameLogicParameters;
|
||||||
|
|
|
@ -212,112 +212,6 @@ int dequeueOutputMessage(outputMessageQueue * queue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputMessageQueue * createInputMessageQueue(void)
|
|
||||||
{
|
|
||||||
inputMessageQueue * newQueue = malloc(sizeof(inputMessageQueue));
|
|
||||||
newQueue->front = NULL;
|
|
||||||
newQueue->back = NULL;
|
|
||||||
newQueue->currentLength = 0;
|
|
||||||
newQueue->lock = false;
|
|
||||||
return newQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dequeueInputMessage(inputMessageQueue * queue)
|
|
||||||
{
|
|
||||||
// Wait for the queue to unlock:
|
|
||||||
while (queue->lock);
|
|
||||||
|
|
||||||
// Lock the queue:
|
|
||||||
queue->lock = true;
|
|
||||||
|
|
||||||
// Check the list isn't empty:
|
|
||||||
if(queue->front == NULL)
|
|
||||||
{
|
|
||||||
queue->lock = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is only one item in the queue:
|
|
||||||
else if(queue->front == queue->back)
|
|
||||||
{
|
|
||||||
free(queue->front->content);
|
|
||||||
free(queue->front);
|
|
||||||
queue->front = NULL;
|
|
||||||
queue->back = NULL;
|
|
||||||
queue->currentLength--;
|
|
||||||
queue->lock = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the front item:
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inputMessage * messageToDelete = queue->front;
|
|
||||||
queue->front = queue->front->next;
|
|
||||||
free(messageToDelete->content);
|
|
||||||
free(messageToDelete);
|
|
||||||
queue->currentLength--;
|
|
||||||
queue->lock = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int queueInputMessage(inputMessageQueue * queue, userMessage messageToQueue, playerInfo * sendingPlayer)
|
|
||||||
{
|
|
||||||
// Copy the message into a new input message:
|
|
||||||
inputMessage * input = malloc(sizeof(inputMessage));
|
|
||||||
|
|
||||||
// Allocate the internal userMessage to store the message:
|
|
||||||
input->content = malloc(sizeof(userMessage));
|
|
||||||
|
|
||||||
// Copy the userMessage to the internal userMessage:
|
|
||||||
strncpy(input->content->senderName, messageToQueue.senderName, 32);
|
|
||||||
strncpy(input->content->messageContent, messageToQueue.messageContent, MAX);
|
|
||||||
|
|
||||||
// We have no targets, NULL sends to all players in an area:
|
|
||||||
input->sender = sendingPlayer;
|
|
||||||
|
|
||||||
// Wait for the queue to unlock:
|
|
||||||
while (queue->lock);
|
|
||||||
|
|
||||||
// Lock the queue:
|
|
||||||
queue->lock = true;
|
|
||||||
|
|
||||||
// Check that we're not overflowing the queue:
|
|
||||||
if ((queue->currentLength + 1) > MAXQUEUELENGTH)
|
|
||||||
{
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the queue is empty, set the first message as both the front and back of the queue:
|
|
||||||
if(queue->front == NULL)
|
|
||||||
{
|
|
||||||
queue->front = input;
|
|
||||||
queue->back = input;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue->back->next = input;
|
|
||||||
queue->back = input;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void userInputSanatize(char * inputString, int length)
|
void userInputSanatize(char * inputString, int length)
|
||||||
{
|
{
|
||||||
for(int index = 0; index <= length; index++)
|
for(int index = 0; index <= length; index++)
|
||||||
|
@ -345,12 +239,6 @@ void userNameSanatize(char * inputString, int length)
|
||||||
inputString[length - 1] = '\0';
|
inputString[length - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the front inputMessage from an inputMessageQueue:
|
|
||||||
inputMessage * peekInputMessage(inputMessageQueue * queue)
|
|
||||||
{
|
|
||||||
return queue->front;
|
|
||||||
}
|
|
||||||
|
|
||||||
outputMessage * peekOutputMessage(outputMessageQueue * queue)
|
outputMessage * peekOutputMessage(outputMessageQueue * queue)
|
||||||
{
|
{
|
||||||
return queue->front;
|
return queue->front;
|
||||||
|
|
|
@ -67,32 +67,10 @@ outputMessage * peekOutputMessage(outputMessageQueue * queue);
|
||||||
typedef struct inputMessage inputMessage;
|
typedef struct inputMessage inputMessage;
|
||||||
typedef struct inputMessage
|
typedef struct inputMessage
|
||||||
{
|
{
|
||||||
inputMessage * next;
|
|
||||||
playerInfo * sender;
|
playerInfo * sender;
|
||||||
userMessage * content;
|
userMessage * content;
|
||||||
} inputMessage;
|
} inputMessage;
|
||||||
|
|
||||||
// A first-in first-out queue for message input from players:
|
|
||||||
typedef struct inputMessageQueue
|
|
||||||
{
|
|
||||||
bool lock;
|
|
||||||
int currentLength;
|
|
||||||
inputMessage * back;
|
|
||||||
inputMessage * front;
|
|
||||||
} inputMessageQueue;
|
|
||||||
|
|
||||||
// Create a inputMessageQueue:
|
|
||||||
inputMessageQueue * createInputMessageQueue(void);
|
|
||||||
|
|
||||||
// Enqueue a userMessage to an inputMessageQueue:
|
|
||||||
int queueInputMessage(inputMessageQueue * queue, userMessage messageToQueue, playerInfo * sendingPlayer);
|
|
||||||
|
|
||||||
// Dequeue the front inputMessage from an inputMessageQueue:
|
|
||||||
int dequeueInputMessage(inputMessageQueue * queue);
|
|
||||||
|
|
||||||
// Return the front inputMessage from an inputMessageQueue:
|
|
||||||
inputMessage * peekInputMessage(inputMessageQueue * queue);
|
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// -=[Input Sanitation]=-:
|
// -=[Input Sanitation]=-:
|
||||||
// =======================
|
// =======================
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
|
|
||||||
|
#include "../queue.h"
|
||||||
#include "../areadata.h"
|
#include "../areadata.h"
|
||||||
#include "../gamelogic.h"
|
#include "../gamelogic.h"
|
||||||
#include "../constants.h"
|
#include "../constants.h"
|
||||||
|
@ -45,7 +46,7 @@ int main(int argc, char ** argv)
|
||||||
playerInfo connectedPlayers[PLAYERCOUNT];
|
playerInfo connectedPlayers[PLAYERCOUNT];
|
||||||
char testString[32] = "Hehe.";
|
char testString[32] = "Hehe.";
|
||||||
struct sockaddr_in serverAddress, clientAddress;
|
struct sockaddr_in serverAddress, clientAddress;
|
||||||
inputMessageQueue * inputQueue = createInputMessageQueue();
|
queue * inputQueue = createQueue();
|
||||||
outputMessageQueue * outputQueue = createOutputMessageQueue();
|
outputMessageQueue * outputQueue = createOutputMessageQueue();
|
||||||
|
|
||||||
// Parse command-line options:
|
// Parse command-line options:
|
||||||
|
@ -215,7 +216,7 @@ int main(int argc, char ** argv)
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
// Clear the set of file descriptors angad add the master socket:
|
// Clear the set of file descriptors and add the master socket:
|
||||||
FD_ZERO(&connectedClients);
|
FD_ZERO(&connectedClients);
|
||||||
FD_SET(socketFileDesc, &connectedClients);
|
FD_SET(socketFileDesc, &connectedClients);
|
||||||
clientsAmount = socketFileDesc;
|
clientsAmount = socketFileDesc;
|
||||||
|
@ -275,7 +276,18 @@ int main(int argc, char ** argv)
|
||||||
strcpy(sendBuffer.messageContent, "Welcome to the server!");
|
strcpy(sendBuffer.messageContent, "Welcome to the server!");
|
||||||
messageSend(tlssessions[index], &sendBuffer);
|
messageSend(tlssessions[index], &sendBuffer);
|
||||||
strcpy(receiveBuffer.messageContent, "/look");
|
strcpy(receiveBuffer.messageContent, "/look");
|
||||||
queueInputMessage(inputQueue, receiveBuffer, &connectedPlayers[index]);
|
|
||||||
|
// Allocate the memory for a new input message:
|
||||||
|
inputMessage * newMessage = malloc(sizeof(inputMessage));
|
||||||
|
newMessage->content = malloc(sizeof(userMessage));
|
||||||
|
|
||||||
|
// Copy in the correct data:
|
||||||
|
memcpy(newMessage->content, &receiveBuffer, sizeof(userMessage));
|
||||||
|
newMessage->sender = &connectedPlayers[index];
|
||||||
|
|
||||||
|
// Push the new message onto the queue:
|
||||||
|
pushQueue(inputQueue, newMessage, INPUT_MESSAGE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +327,16 @@ int main(int argc, char ** argv)
|
||||||
// Otherwise, they've sent a message:
|
// Otherwise, they've sent a message:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
queueInputMessage(inputQueue, receiveBuffer, &connectedPlayers[index]);
|
// Allocate the memory for a new input message:
|
||||||
|
inputMessage * newMessage = malloc(sizeof(inputMessage));
|
||||||
|
newMessage->content = malloc(sizeof(userMessage));
|
||||||
|
|
||||||
|
// Copy in the correct data:
|
||||||
|
memcpy(newMessage->content, &receiveBuffer, sizeof(userMessage));
|
||||||
|
newMessage->sender = &connectedPlayers[index];
|
||||||
|
|
||||||
|
// Push the new message onto the queue:
|
||||||
|
pushQueue(inputQueue, newMessage, INPUT_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue