summaryrefslogtreecommitdiff
path: root/src/events.c
blob: dd0e14f51af311b5b15e1a47db8b4447c699bf58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "SDL/SDL_stdinc.h"

#include "events.h"

inline int eventSerializedSize() {
	//FIXME : A rendre portable
	return sizeof(event_t);
}

void eventSerialize(const event_t *e, char *buf) {
	//FIXME : A rendre portable
	SDL_memcpy(buf,e,sizeof(event_t));
}

int eventUnserialize(event_t *e, char *buf) {
	//FIXME : A rendre portable et vérifier les champs
	SDL_memcpy(e,buf,sizeof(event_t));
	return 0;
}

void eventListInit(eventList_t *elist) {
	elist->first=NULL;
	elist->last=NULL;
	elist->lock= SDL_CreateMutex();
}

void eventListFree(eventList_t *elist) {
	event_t *next;
	event_t *curr = elist->first;
	while(curr!=NULL) {
		next = curr->next;
		free(curr);
		curr=next;
	}
}
int eventListLock(eventList_t *elist) {
	return SDL_mutexP(elist->lock);
}

int eventListUnlock(eventList_t *elist) {
	return SDL_mutexV(elist->lock);
}

void eventListAdd(eventList_t *elist, event_t *event) {
	if (elist->first==NULL) {
		elist->first=elist->last=event;
		event->next=event->prev=NULL;
	} else {
		elist->last->next = event;
		event->prev = elist->last;
		event->next = NULL;
		elist->last = event;
	}
}

event_t * eventListPop(eventList_t *elist) {
	event_t *res = elist->first;

	if (res!=NULL) {
		elist->first=res->next;
	}

	return res;
}

int eventListItemCount(eventList_t *elist) {
	int i=0;
	event_t *cur = elist->first;
	while(cur!=NULL) { ++i, cur=cur->next; }
	return i;
}

// Private methods below (not present in .h file)
void _eventListCopyItemValues(event_t *dst, const event_t *src) {
	dst->clientId = src->clientId;	
	dst->eventTick = src->eventTick;	
	dst->serverTick = src->serverTick;
	dst->type = src->type;
	dst->lemId = src->lemId;	
	dst->newRole = src->newRole;
}


void _eventList_sort(event_t *left, event_t *right) {

	event_t *start, *curr, copy; 

	// If the left and right pointers are the same, then return
	if (left == right) return;

	// Set the Start and the Current item pointers
	start = left;
	curr = start->next;

	// Loop until we get to the right
	while (1)
	{
		// If the start item is less then the right
		if ( 
			(start->eventTick < curr->eventTick) ||
			(
				(start->eventTick == curr->eventTick) &&
				(start->clientId < curr->clientId)
			)
		   )
		{
			// Swap the items TODO : change references
			_eventListCopyItemValues(&copy, curr);
			_eventListCopyItemValues(curr, start);
			_eventListCopyItemValues(start, &copy);
		}	
		
		// Check if we have reached the right end
		if (curr == right) break;

		// Move to the next item in the list
		curr = curr->next;
	}

	// Swap the First and Current items
	_eventListCopyItemValues(&copy, left);
	_eventListCopyItemValues(left, curr);
	_eventListCopyItemValues(curr, &copy);

	// Save this Current item
	const event_t *oldCurr = curr;

	// Check if we need to sort the left hand size of the Current point
	curr = curr->prev;
	if (curr != NULL)
	{
		if ((left->prev != curr) && (curr->next != left))
			_eventList_sort(left, curr);
	}

	// Check if we need to sort the right hand size of the Current point
	curr = oldCurr->next;
	if (curr != NULL)
	{
		if ((curr->prev != right) && (right->next != curr))
			_eventList_sort(curr, right);
	}
}

void eventList_sort(eventList_t *elist) {
	_eventList_sort(elist->first,elist->last);
}