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 <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include "queue.h"
|
||||
#include "constants.h"
|
||||
#include "gamelogic.h"
|
||||
#include "playerdata.h"
|
||||
|
@ -28,25 +29,21 @@ void * gameLogicLoop(void * parameters)
|
|||
{
|
||||
evaluateNextCommand(threadParameters, commandQueue);
|
||||
}
|
||||
|
||||
// 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);
|
||||
threadParameters->inputQueue->lock = true;
|
||||
currentInput = peekInputMessage(threadParameters->inputQueue);
|
||||
currentInput = peekQueue(threadParameters->inputQueue)->data.inputMessage;
|
||||
userInputSanatize(currentInput->content->messageContent, MAX);
|
||||
// A slash as the first character means the message is a user command:
|
||||
if(currentInput->content->messageContent[0] == '/')
|
||||
{
|
||||
queueMessagedCommand(commandQueue, currentInput);
|
||||
}
|
||||
else if(currentInput->sender->currentArea == getFromList(threadParameters->areaList, 0)->area)
|
||||
{
|
||||
currentInput = NULL;
|
||||
threadParameters->inputQueue->lock = false;
|
||||
dequeueInputMessage(threadParameters->inputQueue);
|
||||
}
|
||||
else
|
||||
|
||||
else if (!(currentInput->sender->currentArea == getFromList(threadParameters->areaList, 0)->area))
|
||||
{
|
||||
strncpy(currentInput->content->senderName, currentInput->sender->playerName, 32);
|
||||
// Create an array of players in the same area to receive the message:
|
||||
|
@ -72,7 +69,7 @@ void * gameLogicLoop(void * parameters)
|
|||
}
|
||||
currentInput = NULL;
|
||||
threadParameters->inputQueue->lock = false;
|
||||
dequeueInputMessage(threadParameters->inputQueue);
|
||||
popQueue(threadParameters->inputQueue);
|
||||
}
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
|
|
|
@ -2,11 +2,15 @@
|
|||
// Barry Kane, 2022.
|
||||
#ifndef GAMELOGIC_H
|
||||
#define GAMELOGIC_H
|
||||
#include "queue.h"
|
||||
#include "areadata.h"
|
||||
#include "constants.h"
|
||||
#include "playerdata.h"
|
||||
#include "inputoutput.h"
|
||||
|
||||
// Let the compiler know there will be structs defined elsewhere:
|
||||
typedef struct queue queue;
|
||||
|
||||
// =======================
|
||||
// -=[ Main Game Loop ]=-:
|
||||
// =======================
|
||||
|
@ -17,7 +21,7 @@ typedef struct gameLogicParameters
|
|||
int * playerCount;
|
||||
list * areaList;
|
||||
playerInfo * connectedPlayers;
|
||||
inputMessageQueue * inputQueue;
|
||||
queue * inputQueue;
|
||||
outputMessageQueue * outputQueue;
|
||||
list * globalSkillList;
|
||||
} 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)
|
||||
{
|
||||
for(int index = 0; index <= length; index++)
|
||||
|
@ -345,12 +239,6 @@ void userNameSanatize(char * inputString, int length)
|
|||
inputString[length - 1] = '\0';
|
||||
}
|
||||
|
||||
// Return the front inputMessage from an inputMessageQueue:
|
||||
inputMessage * peekInputMessage(inputMessageQueue * queue)
|
||||
{
|
||||
return queue->front;
|
||||
}
|
||||
|
||||
outputMessage * peekOutputMessage(outputMessageQueue * queue)
|
||||
{
|
||||
return queue->front;
|
||||
|
|
|
@ -67,32 +67,10 @@ outputMessage * peekOutputMessage(outputMessageQueue * queue);
|
|||
typedef struct inputMessage inputMessage;
|
||||
typedef struct inputMessage
|
||||
{
|
||||
inputMessage * next;
|
||||
playerInfo * sender;
|
||||
userMessage * content;
|
||||
} 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]=-:
|
||||
// =======================
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
|
||||
#include "../queue.h"
|
||||
#include "../areadata.h"
|
||||
#include "../gamelogic.h"
|
||||
#include "../constants.h"
|
||||
|
@ -45,7 +46,7 @@ int main(int argc, char ** argv)
|
|||
playerInfo connectedPlayers[PLAYERCOUNT];
|
||||
char testString[32] = "Hehe.";
|
||||
struct sockaddr_in serverAddress, clientAddress;
|
||||
inputMessageQueue * inputQueue = createInputMessageQueue();
|
||||
queue * inputQueue = createQueue();
|
||||
outputMessageQueue * outputQueue = createOutputMessageQueue();
|
||||
|
||||
// Parse command-line options:
|
||||
|
@ -215,7 +216,7 @@ int main(int argc, char ** argv)
|
|||
|
||||
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_SET(socketFileDesc, &connectedClients);
|
||||
clientsAmount = socketFileDesc;
|
||||
|
@ -275,7 +276,18 @@ int main(int argc, char ** argv)
|
|||
strcpy(sendBuffer.messageContent, "Welcome to the server!");
|
||||
messageSend(tlssessions[index], &sendBuffer);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +327,16 @@ int main(int argc, char ** argv)
|
|||
// Otherwise, they've sent a message:
|
||||
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