Refactored SilverMUD to use the queue type for command events.
- Removed the old commandQueue type. - Removed the functions relating to creating, pushing, popping, and peeking the commandQueues. - Refactored the gameLogicHandler to use a queue type.
This commit is contained in:
parent
602f177a8f
commit
f411333203
161
src/gamelogic.c
161
src/gamelogic.c
|
@ -21,11 +21,11 @@ void * gameLogicHandler(void * parameters)
|
||||||
{
|
{
|
||||||
gameLogicParameters * threadParameters = parameters;
|
gameLogicParameters * threadParameters = parameters;
|
||||||
inputMessage * currentInput = NULL;
|
inputMessage * currentInput = NULL;
|
||||||
commandQueue * commandQueue = createCommandQueue();
|
queue * commandQueue = createQueue();
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
// Evaluate remaining commands:
|
// Evaluate remaining commands:
|
||||||
while(commandQueue->currentLength != 0)
|
while(commandQueue->itemCount != 0)
|
||||||
{
|
{
|
||||||
evaluateNextCommand(threadParameters, commandQueue);
|
evaluateNextCommand(threadParameters, commandQueue);
|
||||||
}
|
}
|
||||||
|
@ -93,30 +93,8 @@ void * gameLogicHandler(void * parameters)
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a commandQueue:
|
|
||||||
commandQueue * createCommandQueue(void)
|
|
||||||
{
|
|
||||||
commandQueue * newCommandQueue = calloc(1, sizeof(commandQueue));
|
|
||||||
newCommandQueue->back = NULL;
|
|
||||||
newCommandQueue->front = NULL;
|
|
||||||
newCommandQueue->lock = false;
|
|
||||||
newCommandQueue->paused = false;
|
|
||||||
newCommandQueue->currentLength = 0;
|
|
||||||
return newCommandQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the front commandEvent from a commandQueue:
|
|
||||||
commandEvent * peekCommand(commandQueue * queue)
|
|
||||||
{
|
|
||||||
// Do nothing until the command queue is unlocked.
|
|
||||||
while(queue->lock);
|
|
||||||
|
|
||||||
// Return the front item.
|
|
||||||
return queue->front;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enqueue a messaged command to a commandQueue:
|
// Enqueue a messaged command to a commandQueue:
|
||||||
int queueMessagedCommand(commandQueue * queue, inputMessage * messageToQueue)
|
void queueMessagedCommand(queue * queue, inputMessage * messageToQueue)
|
||||||
{
|
{
|
||||||
// Prepare the new commandEvent:
|
// Prepare the new commandEvent:
|
||||||
commandEvent * newCommand = calloc(1, sizeof(commandEvent));
|
commandEvent * newCommand = calloc(1, sizeof(commandEvent));
|
||||||
|
@ -145,48 +123,11 @@ int queueMessagedCommand(commandQueue * queue, inputMessage * messageToQueue)
|
||||||
*character = tolower(*character);
|
*character = tolower(*character);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the queue to unlock:
|
pushQueue(queue, newCommand, COMMAND);
|
||||||
while (queue->lock);
|
|
||||||
|
|
||||||
// Check that we're not overflowing the queue:
|
|
||||||
if ((queue->currentLength + 1) > MAXQUEUELENGTH)
|
|
||||||
{
|
|
||||||
// Free the new command, it's getting dumped:
|
|
||||||
free(newCommand);
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the queue is empty, set the first commandEvent as both the front and back of the queue:
|
|
||||||
if(queue->front == NULL)
|
|
||||||
{
|
|
||||||
queue->front = newCommand;
|
|
||||||
queue->back = newCommand;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue->back->next = newCommand;
|
|
||||||
queue->back = newCommand;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue a command to a commandQueue:
|
// Enqueue a command to a commandQueue:
|
||||||
int queueCommand(commandQueue * queue, char * command, char * arguments, int commandLength, int argumentsLength, playerInfo * callingPlayer)
|
void queueCommand(queue * queue, char * command, char * arguments, int commandLength, int argumentsLength, playerInfo * callingPlayer)
|
||||||
{
|
{
|
||||||
// Prepare the new commandEvent:
|
// Prepare the new commandEvent:
|
||||||
commandEvent * newCommand = calloc(1, sizeof(commandEvent));
|
commandEvent * newCommand = calloc(1, sizeof(commandEvent));
|
||||||
|
@ -196,96 +137,20 @@ int queueCommand(commandQueue * queue, char * command, char * arguments, int com
|
||||||
|
|
||||||
// Copy the command and arguments:
|
// Copy the command and arguments:
|
||||||
strncpy(newCommand->command, command, commandLength);
|
strncpy(newCommand->command, command, commandLength);
|
||||||
strncpy(newCommand->arguments, arguments, argumentsLength);
|
if(argumentsLength > 0)
|
||||||
|
{
|
||||||
|
strncpy(newCommand->arguments, arguments, argumentsLength);
|
||||||
|
}
|
||||||
// Ensure the arguments are safe to parse, without adding newlines:
|
// Ensure the arguments are safe to parse, without adding newlines:
|
||||||
userNameSanatize(newCommand->command, 16);
|
userNameSanatize(newCommand->command, 16);
|
||||||
|
|
||||||
// Wait for the queue to unlock:
|
pushQueue(queue, newCommand, COMMAND);
|
||||||
while (queue->lock);
|
|
||||||
|
|
||||||
// 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 commandEvent as both the front and back of the queue:
|
|
||||||
if(queue->front == NULL)
|
|
||||||
{
|
|
||||||
queue->front = newCommand;
|
|
||||||
queue->back = newCommand;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
queue->back->next = newCommand;
|
|
||||||
queue->back = newCommand;
|
|
||||||
queue->currentLength++;
|
|
||||||
|
|
||||||
// Unlock the queue:
|
|
||||||
queue->lock = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dequeue the front commandEvent from a commandQueue:
|
|
||||||
int dequeueCommand(commandQueue * 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->command);
|
|
||||||
free(queue->front->arguments);
|
|
||||||
free(queue->front);
|
|
||||||
queue->front = NULL;
|
|
||||||
queue->back = NULL;
|
|
||||||
queue->currentLength--;
|
|
||||||
queue->lock = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the front item:
|
|
||||||
else
|
|
||||||
{
|
|
||||||
commandEvent * commandToDelete = queue->front;
|
|
||||||
queue->front = queue->front->next;
|
|
||||||
free(commandToDelete->command);
|
|
||||||
free(commandToDelete->arguments);
|
|
||||||
free(commandToDelete);
|
|
||||||
queue->currentLength--;
|
|
||||||
queue->lock = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the next commandEvent:
|
// Evaluate the next commandEvent:
|
||||||
int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
|
int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
|
||||||
{
|
{
|
||||||
commandEvent * currentCommand = peekCommand(queue);
|
commandEvent * currentCommand = peekQueue(queue)->data.command;
|
||||||
while(queue->lock);
|
while(queue->lock);
|
||||||
queue->lock = true;
|
queue->lock = true;
|
||||||
if(currentCommand == NULL)
|
if(currentCommand == NULL)
|
||||||
|
@ -686,7 +551,7 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
|
||||||
// Remove the current command and unlock the queue:
|
// Remove the current command and unlock the queue:
|
||||||
currentCommand = NULL;
|
currentCommand = NULL;
|
||||||
queue->lock = false;
|
queue->lock = false;
|
||||||
dequeueCommand(queue);
|
popQueue(queue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,6 @@ typedef struct commandEvent
|
||||||
char * arguments;
|
char * arguments;
|
||||||
} commandEvent;
|
} commandEvent;
|
||||||
|
|
||||||
// A first-in first-out queue for message input from players:
|
|
||||||
typedef struct commandQueue
|
|
||||||
{
|
|
||||||
bool lock;
|
|
||||||
bool paused;
|
|
||||||
int currentLength;
|
|
||||||
commandEvent * back;
|
|
||||||
commandEvent * front;
|
|
||||||
} commandQueue;
|
|
||||||
|
|
||||||
// A data-structure containing the needed parameters for a main game loop:
|
// A data-structure containing the needed parameters for a main game loop:
|
||||||
typedef struct gameLogicParameters
|
typedef struct gameLogicParameters
|
||||||
{
|
{
|
||||||
|
@ -58,27 +48,15 @@ int movePlayerToArea(playerInfo * player, char * requestedPath);
|
||||||
// Thread function which runs the main game loop, given the needed parameters:
|
// Thread function which runs the main game loop, given the needed parameters:
|
||||||
void * gameLogicHandler(void * parameters);
|
void * gameLogicHandler(void * parameters);
|
||||||
|
|
||||||
// Create a commandQueue:
|
|
||||||
commandQueue * createCommandQueue(void);
|
|
||||||
|
|
||||||
// Enqueue a command to a commandQueue:
|
// Enqueue a command to a commandQueue:
|
||||||
int queueCommand(commandQueue * queue, char * command, char * arguments,
|
void queueCommand(queue * queue, char * command, char * arguments,
|
||||||
int commandLength, int argumentsLength , playerInfo * callingPlayer);
|
int commandLength, int argumentsLength , playerInfo * callingPlayer);
|
||||||
|
|
||||||
// Enqueue a messaged command to a commandQueue:
|
// Enqueue a messaged command to a commandQueue:
|
||||||
int queueMessagedCommand(commandQueue * queue, inputMessage * messageToQueue);
|
void queueMessagedCommand(queue * queue, inputMessage * messageToQueue);
|
||||||
|
|
||||||
// Dequeue the front commandEvent from a commandQueue:
|
|
||||||
int dequeueCommand(commandQueue * queue);
|
|
||||||
|
|
||||||
// Return the front commandEvent from a commandQueue:
|
|
||||||
commandEvent * peekCommand(commandQueue * queue);
|
|
||||||
|
|
||||||
// Evaluate the next commandEvent:
|
// Evaluate the next commandEvent:
|
||||||
int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue);
|
int evaluateNextCommand(gameLogicParameters * parameters, queue * queue);
|
||||||
|
|
||||||
/* // Evaluate the given commandEvent: */
|
|
||||||
/* int evaluateCommand(gameLogicParameters * parameters, commandEvent * command); */
|
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
// -=[ Gameplay Primitives ]=-:
|
// -=[ Gameplay Primitives ]=-:
|
||||||
|
|
Loading…
Reference in New Issue