/* * List-like data structures * * Copyright (C) 2006-2008 Alejandro Valenzuela Roca, * * http://mexinetica.com/~lanjoe9 * * This file is part of MotorJ, a free framework for videogame development. * * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ /* NOTICE: Candidate to C++ Class Objectification */ #include "data_structs.h" void list_init(list_header * header){ header->first = NULL; header->last = NULL; header->mid = NULL; header->count = 0; } list_node * node_at(unsigned index, list_header * header){ list_node * node; unsigned walk; if ((header->count == 0) || (index > header->count-1)){ return NULL; } else if (header->count < 2){ node = header->first; walk = index; } else if (index < (header->count/2)){ node = header->first; walk = index; } else { node = header->mid; walk = index - (header->count/2); walk += (!(header->count % 2)); } while (walk){ walk--; node = node->nxt; } return node; } list_node * list_append(int type, void * data, list_header * header){ list_node * node; //printf ("append\n"); if (! header->last){ //printf("! header last\n"); header->first = new list_node; header->mid = header->first; header->first->prv = NULL; node = header->first; } else { node = header->last; node->nxt = new list_node; node->nxt->prv = node; node = node->nxt; } //printf("Init node set; storing data\n"); node->type = type; node->data = data; header->last = node; header->count++; if (header->count > 2 && header->count % 2){ //printf("Moving nxt\n"); header->mid = header->mid->nxt; } node->nxt = NULL; return node; //printf("End of append\n"); } void list_readjust(list_header * header) { if (header->count > 1) { if (header->count % 2){ //printf("Moving nxt\n"); header->mid = header->mid->prv; } } else header->first = header->mid = header->last = NULL; header->count--; } // Pop the last node in the list list_node * list_pop(list_header * header){ list_node * res = NULL; if (header->count){ res = header->last; header->last = header->last->prv; //header->last = NULL; list_readjust(header); //res->nxt = NULL; //res->prv = NULL; } return res; } // Remove the node from its current position, joining the previous and next // node together list_node * list_yank_node(list_node * node, list_header * header) { if (node) { if (node->prv) { node->prv->nxt = node->nxt; } if (node == header->first) { header->first = node->nxt; } if (node->nxt) { node->nxt->prv = node->prv; } if (node == header->last) { header->last = node->prv; } // pointer rearrangement list_readjust(header); } return node; } // Indexed version of the yank_node function list_node * list_yank(unsigned index, list_header * header) { list_node * node = node_at(index, header); list_yank_node(node, header); return (node); } /* list_delete will NOT attempt to delete the data */ void list_delete(list_header * header, bool deleteHeader) { list_node * node; list_node * next; unsigned r; if (header->count) { node = header->first; for (r = 0; r < header->count; r++) { next = node->nxt; delete node; node = next; } if (deleteHeader) { delete header; header = NULL; } else { list_init(header); } } } void list_empty(void * data_empty(void * data), list_header * header){ list_node * node; list_node * next; unsigned r; if (header->count){ node = header->first; for (r = 0; r < header->count; r++){ data_empty(node->data); next = node->nxt; delete node; node = next; } delete header; } } list_node * list_find_type(int type, unsigned offset, list_header * header){ list_node * result; if (offset) result = node_at(offset, header); else result = header->first; while (result && result->type != type){ result = result->nxt; } return result; } list_node * list_find_type_noffset(int type, list_node * offset) { list_node * result; result = offset; while (result && result->type != type){ result = result->nxt; } return result; } void node_swap(list_node * node0, list_node * node1) { void * tmp_data; int tmp_type; tmp_data = node0->data; tmp_type = node0->type; node0->data = node1->data; node0->type = node1->type; node1->data = tmp_data; node1->type = tmp_type; }