mirror of
https://github.com/tbamud/tbamud.git
synced 2026-01-03 16:08:49 +01:00
Added lists .c .h and mud_event .c .h
This commit is contained in:
parent
dd280c1b58
commit
b34c23da96
4 changed files with 487 additions and 0 deletions
321
src/lists.c
Normal file
321
src/lists.c
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
/**************************************************************************
|
||||
* File: lists.c Part of tbaMUD *
|
||||
* Usage: Loading/saving/editing of Ideas, Bugs and Typos lists *
|
||||
* *
|
||||
* All rights reserved. See license for complete information. *
|
||||
* *
|
||||
* Written by Joseph Arnusch (Vatiken) for the tbaMUD codebase *
|
||||
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
|
||||
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
|
||||
**************************************************************************/
|
||||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
#include "db.h"
|
||||
#include "dg_event.h"
|
||||
|
||||
/* Global lists */
|
||||
struct list_data * global_lists = NULL;
|
||||
|
||||
struct list_data * create_list(void)
|
||||
{
|
||||
struct list_data *pNewList;
|
||||
static bool first_list = TRUE;
|
||||
|
||||
CREATE(pNewList, struct list_data, 1);
|
||||
|
||||
pNewList->pFirstItem = NULL;
|
||||
pNewList->pLastItem = NULL;
|
||||
pNewList->iIterators = 0;
|
||||
pNewList->iSize = 0;
|
||||
|
||||
/* Add to global lists, primarily for debugging purposes */
|
||||
if (first_list == FALSE) {
|
||||
mudlog(CMP, LVL_GOD, TRUE, "Adding to global list.");
|
||||
add_to_list(pNewList, global_lists);
|
||||
} else
|
||||
first_list = FALSE;
|
||||
|
||||
return (pNewList);
|
||||
}
|
||||
|
||||
struct item_data * create_item(void)
|
||||
{
|
||||
struct item_data *pNewItem;
|
||||
|
||||
CREATE(pNewItem, struct item_data, 1);
|
||||
|
||||
pNewItem->pNextItem = NULL;
|
||||
pNewItem->pPrevItem = NULL;
|
||||
pNewItem->pContent = NULL;
|
||||
|
||||
return (pNewItem);
|
||||
}
|
||||
|
||||
void free_list(struct list_data * pList)
|
||||
{
|
||||
void * pContent;
|
||||
|
||||
if (pList->iSize)
|
||||
while ((pContent = simple_list(pList)))
|
||||
remove_from_list(pContent, pList);
|
||||
|
||||
if (pList->iSize > 0)
|
||||
mudlog(CMP, LVL_GOD, TRUE, "List being freed while not empty.");
|
||||
|
||||
/* Global List for debugging */
|
||||
mudlog(CMP, LVL_GOD, TRUE, "Removing from global list.");
|
||||
remove_from_list(pList, global_lists);
|
||||
|
||||
free(pList);
|
||||
}
|
||||
|
||||
void add_to_list(void * pContent, struct list_data * pList)
|
||||
{
|
||||
struct item_data * pNewItem;
|
||||
struct item_data * pLastItem;
|
||||
|
||||
/* Allocate our memory */
|
||||
pNewItem = create_item();
|
||||
|
||||
/* Place the contents in the item */
|
||||
pNewItem->pContent = pContent;
|
||||
pNewItem->pNextItem = NULL;
|
||||
|
||||
/* If we are the first entry in the list, mark us as such */
|
||||
if (pList->pFirstItem == NULL)
|
||||
pList->pFirstItem = pNewItem;
|
||||
|
||||
/* Grab our last item from the list and attach it to our new item */
|
||||
if (pList->pLastItem) {
|
||||
pLastItem = pList->pLastItem;
|
||||
pLastItem->pNextItem = pNewItem;
|
||||
pNewItem->pPrevItem = pLastItem;
|
||||
}
|
||||
|
||||
/* Make our new item our last item in the list */
|
||||
pList->pLastItem = pNewItem;
|
||||
|
||||
pList->iSize++;
|
||||
}
|
||||
|
||||
void remove_from_list(void * pContent, struct list_data * pList)
|
||||
{
|
||||
struct item_data *pRemovedItem;
|
||||
|
||||
if ((pRemovedItem = find_in_list(pContent, pList)) == NULL) {
|
||||
mudlog(CMP, LVL_GOD, TRUE, "SYSERR: Attempting to remove contents that don't exist in list.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pRemovedItem == pList->pFirstItem)
|
||||
pList->pFirstItem = pRemovedItem->pNextItem;
|
||||
|
||||
if (pRemovedItem == pList->pLastItem)
|
||||
pList->pLastItem = pRemovedItem->pPrevItem;
|
||||
|
||||
if (pRemovedItem->pPrevItem)
|
||||
pRemovedItem->pPrevItem->pNextItem = pRemovedItem->pNextItem;
|
||||
|
||||
if (pRemovedItem->pNextItem)
|
||||
pRemovedItem->pNextItem->pPrevItem = pRemovedItem->pPrevItem;
|
||||
|
||||
pList->iSize--;
|
||||
|
||||
if (pList->iSize == 0) {
|
||||
pList->pFirstItem = NULL;
|
||||
pList->pLastItem = NULL;
|
||||
}
|
||||
|
||||
free(pRemovedItem);
|
||||
}
|
||||
|
||||
/** Merges an iterator with a list
|
||||
* @post Don't forget to remove the iterator with remove_iterator().
|
||||
* */
|
||||
|
||||
void * merge_iterator(struct iterator_data * pIterator, struct list_data * pList)
|
||||
{
|
||||
void * pContent;
|
||||
|
||||
if (pList == NULL) {
|
||||
mudlog(NRM, LVL_GOD, TRUE, "SYSERR: Attempting to merge iterator to NULL list.");
|
||||
pIterator->pList = NULL;
|
||||
pIterator->pItem = NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (pList->pFirstItem == NULL) {
|
||||
mudlog(NRM, LVL_GOD, TRUE, "SYSERR: Attempting to merge iterator to empty list.");
|
||||
pIterator->pList = NULL;
|
||||
pIterator->pItem = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pList->iIterators++;
|
||||
pIterator->pList = pList;
|
||||
pIterator->pItem = pList->pFirstItem;
|
||||
|
||||
pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL;
|
||||
|
||||
return (pContent);
|
||||
}
|
||||
|
||||
void remove_iterator(struct iterator_data * pIterator)
|
||||
{
|
||||
if (pIterator->pList == NULL) {
|
||||
mudlog(NRM, LVL_GOD, TRUE, "SYSERR: Attempting to remove iterator from NULL list.");
|
||||
return;
|
||||
}
|
||||
|
||||
pIterator->pList->iIterators--;
|
||||
pIterator->pList = NULL;
|
||||
pIterator->pItem = NULL;
|
||||
}
|
||||
|
||||
/** Spits out an item and cycles down the list
|
||||
* @return Returns the content of the list
|
||||
* */
|
||||
|
||||
void * next_in_list(struct iterator_data * pIterator)
|
||||
{
|
||||
void * pContent;
|
||||
struct item_data * pTempItem;
|
||||
|
||||
if (pIterator->pList == NULL) {
|
||||
mudlog(NRM, LVL_GOD, TRUE, "SYSERR: Attempting to get content from iterator with NULL list.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Cycle down the list */
|
||||
pTempItem = pIterator->pItem->pNextItem;
|
||||
pIterator->pItem = pTempItem;
|
||||
|
||||
/* Grab the content */
|
||||
pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL;
|
||||
|
||||
return (pContent);
|
||||
}
|
||||
|
||||
/** Searches through the a list and returns the item block that holds pContent
|
||||
* @return Returns the actual item block and not the pContent itself, since
|
||||
* it is assumed you already have the pContent.
|
||||
* */
|
||||
|
||||
struct item_data * find_in_list(void * pContent, struct list_data * pList)
|
||||
{
|
||||
struct iterator_data Iterator;
|
||||
void * pFoundItem;
|
||||
struct item_data *pItem = NULL;
|
||||
bool found;
|
||||
|
||||
pFoundItem = merge_iterator(&Iterator, pList);
|
||||
|
||||
for (found = FALSE; pFoundItem != NULL; pFoundItem = next_in_list(&Iterator)) {
|
||||
if (pFoundItem == pContent) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
pItem = Iterator.pItem;
|
||||
|
||||
remove_iterator(&Iterator);
|
||||
|
||||
if (found)
|
||||
return (pItem);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** This is the "For Dummies" function, as although it's not as flexible,
|
||||
* it is even easier applied for list searches then using your own iterators
|
||||
* and next_in_list()
|
||||
* @usage Common usage would be as follows:
|
||||
*
|
||||
* while ((var = (struct XXX_data *) simple_list(XXX_list))) {
|
||||
* blah blah....
|
||||
* }
|
||||
* @return Will return the next list content until it hits the end, in which
|
||||
* will detach itself from the list.
|
||||
* */
|
||||
|
||||
void * simple_list(struct list_data * pList)
|
||||
{
|
||||
static struct iterator_data Iterator;
|
||||
static bool loop = FALSE;
|
||||
static struct list_data *pLastList = NULL;
|
||||
void * pContent;
|
||||
|
||||
if (!loop || pLastList != pList) {
|
||||
if (pLastList != pList)
|
||||
mudlog(CMP, LVL_GRGOD, TRUE, "SYSERR: simple_list() forced to reset itself.");
|
||||
|
||||
pContent = merge_iterator(&Iterator, pList);
|
||||
if (pContent != NULL) {
|
||||
pLastList = pList;
|
||||
loop = TRUE;
|
||||
return (pContent);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((pContent = next_in_list(&Iterator)) != NULL)
|
||||
return (pContent);
|
||||
|
||||
remove_iterator(&Iterator);
|
||||
loop = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * random_from_list(struct list_data * pList)
|
||||
{
|
||||
struct iterator_data Iterator;
|
||||
void * pFoundItem;
|
||||
bool found;
|
||||
int number;
|
||||
int count = 1;
|
||||
|
||||
if (pList->iSize <= 0)
|
||||
return NULL;
|
||||
else
|
||||
number = rand_number(1, pList->iSize);
|
||||
|
||||
pFoundItem = merge_iterator(&Iterator, pList);
|
||||
|
||||
for (found = FALSE; pFoundItem != NULL; pFoundItem = next_in_list(&Iterator), count++) {
|
||||
if (count == number) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
remove_iterator(&Iterator);
|
||||
|
||||
if (found)
|
||||
return (pFoundItem);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct list_data * randomize_list(struct list_data * pList)
|
||||
{
|
||||
struct list_data * newList;
|
||||
void * pContent;
|
||||
|
||||
if (pList->iSize == 0)
|
||||
return NULL;
|
||||
|
||||
newList = create_list();
|
||||
|
||||
while ((pContent = random_from_list(pList)) != NULL) {
|
||||
remove_from_list(pContent, pList);
|
||||
add_to_list(pContent, newList);
|
||||
}
|
||||
|
||||
free_list(pList);
|
||||
|
||||
return (newList);
|
||||
}
|
||||
41
src/lists.h
Normal file
41
src/lists.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* file: list.h
|
||||
*/
|
||||
|
||||
#ifndef _LISTS_HEADER
|
||||
#define _LISTS_HEADER
|
||||
|
||||
struct item_data {
|
||||
struct item_data * pPrevItem;
|
||||
struct item_data * pNextItem;
|
||||
void * pContent;
|
||||
};
|
||||
|
||||
struct list_data {
|
||||
struct item_data * pFirstItem;
|
||||
struct item_data * pLastItem;
|
||||
int iIterators;
|
||||
int iSize;
|
||||
};
|
||||
|
||||
struct iterator_data {
|
||||
struct list_data * pList;
|
||||
struct item_data * pItem;
|
||||
};
|
||||
|
||||
/* Externals */
|
||||
extern struct list_data * global_lists;
|
||||
extern struct list_data * ticker_list;
|
||||
|
||||
/* Locals */
|
||||
void add_to_list(void * pContent, struct list_data * pList);
|
||||
void * random_from_list(struct list_data * pList);
|
||||
struct list_data * randomize_list(struct list_data * pList);
|
||||
struct list_data * create_list(void);
|
||||
void * merge_iterator(struct iterator_data * pIterator, struct list_data * pList);
|
||||
void remove_iterator(struct iterator_data * pIterator);
|
||||
void * next_in_list(struct iterator_data * pIterator);
|
||||
void remove_from_list(void * pContent, struct list_data * pList);
|
||||
struct item_data * find_in_list(void * pContent, struct list_data * pList);
|
||||
void * simple_list(struct list_data * pList);
|
||||
void free_list(struct list_data * pList);
|
||||
#endif
|
||||
89
src/mud_event.c
Normal file
89
src/mud_event.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
#include "db.h"
|
||||
#include "dg_event.h"
|
||||
#include "constants.h"
|
||||
#include "comm.h" /* For access to the game pulse */
|
||||
#include "mud_event.h"
|
||||
|
||||
/* Global List */
|
||||
struct list_data * world_events = NULL;
|
||||
|
||||
void init_events(void)
|
||||
{
|
||||
/* Allocate Event List */
|
||||
world_events = create_list();
|
||||
|
||||
/* Attach Our Events */
|
||||
attach_mud_event(display_usage, new_mud_event(EVENT_WORLD, NULL, NULL), 10 * PASSES_PER_SEC);
|
||||
}
|
||||
|
||||
void attach_mud_event(void (*func), struct mud_event_data *pMudEvent, long time)
|
||||
{
|
||||
struct event * pEvent;
|
||||
struct descriptor_data * d;
|
||||
struct char_data * ch;
|
||||
|
||||
pEvent = event_create(func, pMudEvent, time);
|
||||
pEvent->isMudEvent = TRUE;
|
||||
pMudEvent->pEvent = pEvent;
|
||||
|
||||
switch (pMudEvent->iEvent_Type) {
|
||||
case EVENT_WORLD:
|
||||
add_to_list(pEvent, world_events);
|
||||
break;
|
||||
case EVENT_DESC:
|
||||
d = (struct descriptor_data *) pMudEvent->pStruct;
|
||||
add_to_list(pEvent, d->events);
|
||||
break;
|
||||
case EVENT_CHAR:
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
add_to_list(pEvent, ch->events);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct mud_event_data *new_mud_event(int iEvent_Type, void *pStruct, char *sVariables)
|
||||
{
|
||||
struct mud_event_data *pMudEvent;
|
||||
char *varString;
|
||||
|
||||
CREATE(pMudEvent, struct mud_event_data, 1);
|
||||
varString = (sVariables != NULL) ? strdup(sVariables) : NULL;
|
||||
|
||||
pMudEvent->iEvent_Type = iEvent_Type;
|
||||
pMudEvent->pStruct = pStruct;
|
||||
pMudEvent->sVariables = varString;
|
||||
pMudEvent->pEvent = NULL;
|
||||
|
||||
return (pMudEvent);
|
||||
}
|
||||
|
||||
void free_mud_event(struct mud_event_data *pMudEvent)
|
||||
{
|
||||
struct descriptor_data * d;
|
||||
struct char_data * ch;
|
||||
|
||||
switch (pMudEvent->iEvent_Type) {
|
||||
case EVENT_WORLD:
|
||||
remove_from_list(pMudEvent->pEvent, world_events);
|
||||
break;
|
||||
case EVENT_DESC:
|
||||
d = (struct descriptor_data *) pMudEvent->pStruct;
|
||||
remove_from_list(pMudEvent->pEvent, d->events);
|
||||
break;
|
||||
case EVENT_CHAR:
|
||||
ch = (struct char_data *) pMudEvent->pStruct;
|
||||
remove_from_list(pMudEvent->pEvent, ch->events);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pMudEvent->sVariables != NULL)
|
||||
free(pMudEvent->sVariables);
|
||||
|
||||
pMudEvent->pEvent->event_obj = NULL;
|
||||
free(pMudEvent);
|
||||
}
|
||||
36
src/mud_event.h
Normal file
36
src/mud_event.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file mud_event.h
|
||||
*
|
||||
* Part of the core tbaMUD source code distribution, which is a derivative
|
||||
* of, and continuation of, CircleMUD.
|
||||
*/
|
||||
#ifndef _MUD_EVENT_H_
|
||||
#define _MUD_EVENT_H_
|
||||
|
||||
#include "dg_event.h"
|
||||
|
||||
#define EVENT_WORLD 0
|
||||
#define EVENT_DESC 1
|
||||
#define EVENT_CHAR 2
|
||||
|
||||
struct mud_event_data {
|
||||
struct event * pEvent;
|
||||
int iEvent_Type;
|
||||
void * pStruct;
|
||||
char * sVariables;
|
||||
};
|
||||
|
||||
/* Externals */
|
||||
extern struct list_data * world_events;
|
||||
|
||||
/* Local Functions */
|
||||
void init_events(void);
|
||||
struct mud_event_data *new_mud_event(int iEvent_Type, void *pStruct, char *sVariables);
|
||||
void attach_mud_event(void (*func), struct mud_event_data *pMudEvent, long time);
|
||||
void free_mud_event(struct mud_event_data *pMudEvent);
|
||||
|
||||
/* Events */
|
||||
EVENTFUNC(get_protocols);
|
||||
EVENTFUNC(display_usage);
|
||||
|
||||
#endif /* _MUD_EVENT_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue