killed list double code

yay. look, i cut some of that annoying list code repetitions you always have with linked lists in C. let's just pretend C had templates, put some void-pointers in, add the necessary (void *) casts to show that you are really serious about this and wazaah, you created another funny piece of (C++)--
This commit is contained in:
Lukas Weber 2010-10-27 19:51:49 +02:00
parent 3203fc754f
commit a4a2d9a1a1
7 changed files with 141 additions and 79 deletions

View file

@ -7,6 +7,7 @@ set(SRCs
projectile.c
animation.c
fairy.c
list.c
stages/stage0.c)
find_package(SDL REQUIRED)

View file

@ -20,47 +20,30 @@
#include "fairy.h"
#include "global.h"
#include "list.h"
void create_fairy(int x, int y, int v, int angle, int hp, FairyRule rule) {
Fairy *fairy, *last = global.fairies;
Fairy *fairy = create_element((void **)&global.fairies, sizeof(Fairy));
fairy = malloc(sizeof(Fairy));
if(last != NULL) {
while(last->next != NULL)
last = last->next;
last->next = fairy;
} else {
global.fairies = fairy;
}
*fairy = ((Fairy) { .prev = last,
.next = NULL,
.sx = x,
.sy = y,
.x = x,
.y = y,
.v = v,
.angle = angle,
.rule = rule,
.birthtime = global.frames,
.moving = 0,
.hp = hp,
.dir = 0
*fairy = ((Fairy) {
.sx = x,
.sy = y,
.x = x,
.y = y,
.v = v,
.angle = angle,
.rule = rule,
.birthtime = global.frames,
.moving = 0,
.hp = hp,
.dir = 0
});
init_animation(&fairy->ani, 2, 4, 2, FILE_PREFIX "gfx/fairy.png");
}
void delete_fairy(Fairy *fairy) {
if(fairy->prev != NULL)
fairy->prev->next = fairy->next;
if(fairy->next != NULL)
fairy->next->prev = fairy->prev;
if(global.fairies == fairy)
global.fairies = fairy->next;
free(fairy);
delete_element((void **)&global.fairies, fairy);
}
void draw_fairy(Fairy *f) {
@ -68,16 +51,7 @@ void draw_fairy(Fairy *f) {
}
void free_fairies() {
Fairy *fairy = global.fairies;
Fairy *tmp;
while(fairy != 0) {
tmp = fairy;
fairy = fairy->next;
delete_fairy(tmp);
}
global.fairies = NULL;
delete_all_elements((void **)&global.fairies);
}
void process_fairies() {

View file

@ -28,6 +28,9 @@ struct Fairy;
typedef void (*FairyRule)(struct Fairy*);
typedef struct Fairy {
struct Fairy *next;
struct Fairy *prev;
int birthtime;
int hp;
@ -42,9 +45,6 @@ typedef struct Fairy {
Animation ani;
FairyRule rule;
struct Fairy *next;
struct Fairy *prev;
} Fairy;
void create_fairy(int x, int y, int speed, int angle, int hp, FairyRule rule);

70
src/list.c Normal file
View file

@ -0,0 +1,70 @@
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
---
Copyright (C) 2010, Lukas Weber <laochailan@web.de>
*/
#include "list.h"
#include <stdlib.h>
typedef struct {
void *next;
void *prev;
} List;
void *create_element(void **dest, int size) {
void *last = *dest;
void *e = malloc(size);
if(last != NULL) {
while(((List *)last)->next != NULL)
last = ((List *)last)->next;
((List *)last)->next = e;
} else {
*dest = e;
}
((List *)e)->prev = last;
((List *)e)->next = NULL;
return e;
}
void *delete_element(void **dest, void *e) {
if(((List *)e)->prev != NULL)
((List *)((List *)e)->prev)->next = ((List *)e)->next;
if(((List *)e)->next != NULL)
((List *)((List *)e)->next)->prev = ((List *)e)->prev;
if(*dest == e)
*dest = ((List *)e)->next;
free(e);
}
void *delete_all_elements(void **dest) {
void *e = *dest;
void *tmp;
while(e != 0) {
tmp = e;
e = ((List *)e)->next;
delete_element(dest, tmp);
}
*dest = NULL;
}

32
src/list.h Normal file
View file

@ -0,0 +1,32 @@
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
---
Copyright (C) 2010, Lukas Weber <laochailan@web.de>
*/
#ifndef LIST_H
#define LIST_H
/* I got annoyed of the code doubling caused by simple linked lists,
* so i do some void-magic here to save the lines.
*/
void *create_element(void **dest, int size);
void *delete_element(void **dest, void *e);
void *delete_all_elements(void **dest);
#endif

View file

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <math.h>
#include "global.h"
#include "list.h"
ProjCache _projs;
@ -34,19 +35,19 @@ void load_projectiles() {
}
Projectile *create_projectile(Texture *tex, int x, int y, int angle, Color clr, ProjRule rule, float args, ...) {
Projectile *p, *last = global.projs;
Projectile *p = create_element((void **)&global.projs, sizeof(Projectile));
p = malloc(sizeof(Projectile));
if(last != NULL) {
while(last->next != NULL)
last = last->next;
last->next = p;
} else {
global.projs = p;
}
*p = ((Projectile){ global.frames,x,y,x,y,angle,rule,tex,FairyProj,NULL,last,clr });
p->birthtime = global.frames;
p->x = x;
p->y = y;
p->sx = x;
p->sy = y;
p->angle = angle;
p->rule = rule;
p->tex = tex;
p->type = FairyProj;
p->clr = clr;
va_list ap;
int i;
@ -60,27 +61,11 @@ Projectile *create_projectile(Texture *tex, int x, int y, int angle, Color clr,
}
void delete_projectile(Projectile *proj) {
if(proj->prev != NULL)
proj->prev->next = proj->next;
if(proj->next != NULL)
proj->next->prev = proj->prev;
if(global.projs == proj)
global.projs = proj->next;
free(proj);
delete_element((void **)&global.projs, proj);
}
void free_projectiles() {
Projectile *proj = global.projs;
Projectile *tmp;
while(proj != 0) {
tmp = proj;
proj = proj->next;
delete_projectile(tmp);
}
global.projs = NULL;
delete_all_elements((void **)&global.projs);
}
int test_collision(Projectile *p) {
@ -184,7 +169,7 @@ void process_projectiles() {
} else {
proj = proj->next;
}
}
}
}
void simple(int *x, int *y, int angle, int sx, int sy, int time, float* a) { // sure is physics in here; a[0]: velocity

View file

@ -35,6 +35,9 @@ struct Projectile;
typedef void (*ProjRule)(int *x, int *y, int angle, int sx, int sy, int time, float* a);
typedef struct Projectile {
struct Projectile *next;
struct Projectile *prev;
int birthtime;
int x;
@ -50,9 +53,6 @@ typedef struct Projectile {
enum { PlrProj, FairyProj } type;
struct Projectile *next;
struct Projectile *prev;
Color clr;
float args[4];