Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_user.c
Go to the documentation of this file.
1
7#include "nilorea/n_user.h"
8
15 N_USERLIST* ulist = NULL;
16 Malloc(ulist, N_USERLIST, 1);
17 __n_assert(ulist, return NULL);
18 __n_assert(max > 0, return NULL);
19
20 Malloc(ulist->list, N_USER, (size_t)max);
21 __n_assert(ulist->list, Free(ulist); return NULL);
22
23 ulist->max = max;
24 ulist->highter = -1;
25 for (int it = 0; it < max; it++) {
26 ulist->list[it].state = 0;
27 ulist->list[it].nb_rec_pos = 10;
28 ulist->list[it].only_last_pos = 1;
29 ulist->list[it].id = -1;
30 Malloc(ulist->list[it].last_positions, VECTOR3D, 10);
31 ulist->list[it].netw_waitlist = new_generic_list(MAX_LIST_ITEMS);
32 memset(ulist->list[it].position, 0, 3 * sizeof(double));
33 ulist->list[it].netw = NULL;
34 memset(ulist->list[it].name, 0, 1024);
35 ulist->list[it].netw = NULL;
36 }
37
38 init_lock(ulist->user_rwbolt);
39
40 return ulist;
41} /* userlist_new() */
42
51int userlist_set_position_behavior(N_USERLIST* ulist, int id, int nb_rec_pos, int only_last_pos) {
52 __n_assert(ulist, return FALSE);
53 __n_assert(nb_rec_pos < 1, return FALSE);
54 __n_assert(only_last_pos < 0 || only_last_pos > 1, return FALSE);
55
56 read_lock(ulist->user_rwbolt);
57 __n_assert(ulist->list[id].state == 0, return FALSE);
58 unlock(ulist->user_rwbolt);
59
60 write_lock(ulist->user_rwbolt);
61 ulist->list[id].nb_rec_pos = nb_rec_pos;
62 ulist->list[id].only_last_pos = only_last_pos;
63 if (only_last_pos) {
64 Realloc(ulist->list[id].last_positions, VECTOR3D, 1);
65 if (!ulist->list[id].last_positions) {
66 n_log(LOG_ERR, "could not resize to only_last_pos VECTOR3D");
67 }
68 } else {
69 Realloc(ulist->list[id].last_positions, VECTOR3D, (size_t)nb_rec_pos);
70 if (!ulist->list[id].last_positions) {
71 n_log(LOG_ERR, "could not resize to %d VECTOR3D", nb_rec_pos);
72 }
73 ulist->list[id].nb_rec_pos = 1;
74 }
75 __n_assert(ulist->list[id].last_positions, unlock(ulist->user_rwbolt); return FALSE);
76 unlock(ulist->user_rwbolt);
77
78 return TRUE;
79} /* userlist_set_position_behavior() */
80
88 __n_assert(ulist, return -1);
89 __n_assert(netw, return -1);
90
91 int it = -1;
92 write_lock(ulist->user_rwbolt);
93 do {
94 it++;
95 } while (it < ulist->max && ulist->list[it].state != 0);
96 if (it < ulist->max) {
97 ulist->list[it].state = 1;
98 ulist->list[it].netw = netw;
99 if (it > ulist->highter)
100 ulist->highter = it;
101 unlock(ulist->user_rwbolt);
102 return it;
103 }
104 unlock(ulist->user_rwbolt);
105 return -1;
106} /* userlist_add_user() */
107
114int userlist_del_user(N_USERLIST* ulist, int id) {
115 __n_assert(ulist, return FALSE);
116 __n_assert(id >= 0, return FALSE);
117
118 write_lock(ulist->user_rwbolt);
119 if (id > ulist->max) {
120 unlock(ulist->user_rwbolt);
121 return FALSE;
122 }
123 if (ulist->list[id].state == 0) {
124 unlock(ulist->user_rwbolt);
125 return FALSE;
126 }
127 ulist->list[id].state = 0;
128 ulist->list[id].nb_rec_pos = 1;
129 ulist->list[id].only_last_pos = 1;
130 ulist->list[id].id = -1;
131 Realloc(ulist->list[id].last_positions, VECTOR3D, 1);
132 if (!ulist->list[id].last_positions) {
133 n_log(LOG_ERR, "couldn't resize to 1 element");
134 }
135 list_empty(ulist->list[id].netw_waitlist);
136 memset(ulist->list[id].position, 0, 3 * sizeof(double));
137 ulist->list[id].netw = NULL;
138 memset(ulist->list[id].name, 0, 1024);
139
140 if (id >= ulist->highter) {
141 int it = id;
142 while (it >= 0) {
143 if (ulist->list[it].state == 1) {
144 ulist->highter = it;
145 break;
146 }
147 it--;
148 }
149 }
150 unlock(ulist->user_rwbolt);
151 return TRUE;
152} /* userlist_del_user() */
153
162int userlist_add_msg_to_ex(N_USERLIST* ulist, N_STR* msg, int mode, int id) {
163 __n_assert(ulist, return FALSE);
164 __n_assert(msg, return FALSE);
165
166 switch (mode) {
167 case (USERLIST_ALL):
168 read_lock(ulist->user_rwbolt);
169 for (int it = 0; it <= ulist->highter; it++) {
170 if (ulist->list[it].state == 1)
171 netw_add_msg(ulist->list[it].netw, nstrdup(msg));
172 }
173 unlock(ulist->user_rwbolt);
174 break;
175 case (USERLIST_ALL_EXCEPT):
176 __n_assert(id >= 0, return FALSE);
177 read_lock(ulist->user_rwbolt);
178 for (int it = 0; it <= ulist->highter; it++) {
179 if (it == id)
180 continue;
181 if (ulist->list[it].state == 1)
182 netw_add_msg(ulist->list[it].netw, nstrdup(msg));
183 }
184 unlock(ulist->user_rwbolt);
185 break;
186 default:
187 case (USERLIST_ONE):
188 __n_assert(id >= 0, return FALSE);
189
190 read_lock(ulist->user_rwbolt);
191 netw_add_msg(ulist->list[id].netw, msg);
192 unlock(ulist->user_rwbolt);
193 break;
194 }
195 return TRUE;
196} /* userlist_add_msg_to_ex() */
197
205int userlist_add_msg_to(N_USERLIST* ulist, N_STR* msg, int id) {
206 return userlist_add_msg_to_ex(ulist, msg, USERLIST_ONE, id);
207} /* userlist_add_msg_to() */
208
216 return userlist_add_msg_to_ex(ulist, msg, USERLIST_ALL, -1);
217} /* userlist_add_msg_to_all() */
218
227 return userlist_add_msg_to_ex(ulist, msg, USERLIST_ALL_EXCEPT, id);
228} /* userlist_add_msg_to_all_except() */
229
236 __n_assert(ulist && (*ulist), return FALSE);
237
238 write_lock((*ulist)->user_rwbolt);
239 for (int it = 0; it < (*ulist)->max; it++) {
240 Free((*ulist)->list[it].last_positions);
241 list_destroy(&(*ulist)->list[it].netw_waitlist);
242 }
243 Free((*ulist)->list);
244 unlock((*ulist)->user_rwbolt);
245
246 pthread_rwlock_destroy(&(*ulist)->user_rwbolt);
247 Free((*ulist));
248
249 return TRUE;
250} /* userlist_destroy() */
251
259int userlist_user_add_waiting_msg(N_USERLIST* ulist, int id, N_STR* netmsg) {
260 __n_assert(ulist, return FALSE);
261 __n_assert(netmsg, return FALSE);
262 __n_assert(id >= 0, return FALSE);
263
264 int ret = FALSE;
265
266 read_lock(ulist->user_rwbolt);
267 if (id <= ulist->highter) {
268 if (ulist->list[id].state == 1) {
269 ret = list_push(ulist->list[id].netw_waitlist, netmsg, NULL);
270 }
271 }
272 unlock(ulist->user_rwbolt);
273 return ret;
274} /* userlist_user_add_waiting_msg() */
275
283 __n_assert(ulist, return FALSE);
284 __n_assert(id >= 0, return FALSE);
285
286 read_lock(ulist->user_rwbolt);
287 if (id <= ulist->highter) {
288 if (ulist->list[id].state == 1) {
289 list_foreach(node, ulist->list[id].netw_waitlist) {
290 N_STR* netmsg = (N_STR*)node->ptr;
291 netw_add_msg(ulist->list[id].netw, netmsg);
292 }
293 list_empty(ulist->list[id].netw_waitlist);
294 }
295 }
296 unlock(ulist->user_rwbolt);
297 return TRUE;
298} /* userlist_user_send_waiting_msgs() */
299
306 __n_assert(ulist, return FALSE);
307
308 read_lock(ulist->user_rwbolt);
309 for (int id = 0; id <= ulist->highter; id++) {
310 if (ulist->list[id].state == 1) {
311 list_foreach(node, ulist->list[id].netw_waitlist) {
312 N_STR* netmsg = (N_STR*)node->ptr;
313 netw_add_msg(ulist->list[id].netw, netmsg);
314 }
315 list_empty(ulist->list[id].netw_waitlist);
316 }
317 }
318 unlock(ulist->user_rwbolt);
319 return TRUE;
320} /* userlist_send_waiting_msgs() */
#define init_lock(__rwlock_mutex)
Macro for initializing a rwlock.
Definition n_common.h:331
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:187
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:258
#define unlock(__rwlock_mutex)
Macro for releasing read/write lock a rwlock mutex.
Definition n_common.h:377
#define write_lock(__rwlock_mutex)
Macro for acquiring a write lock on a rwlock mutex.
Definition n_common.h:363
#define Realloc(__ptr, __struct, __size)
Realloc Handler to get errors.
Definition n_common.h:213
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:242
#define read_lock(__rwlock_mutex)
Macro for acquiring a read lock on a rwlock mutex.
Definition n_common.h:349
int list_empty(LIST *list)
Empty a LIST list of pointers.
Definition n_list.c:471
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition n_list.c:199
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
Definition n_list.h:65
int list_destroy(LIST **list)
Empty and Free a list container.
Definition n_list.c:518
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
Definition n_list.h:55
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:69
#define LOG_ERR
error conditions
Definition n_log.h:56
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
Definition n_str.c:670
A box including a string and his lenght.
Definition n_str.h:39
char name[1024]
User Name.
Definition n_user.h:37
VECTOR3D * last_positions
Last nb_rec_pos position messages, for a better dead reckoning / lag simulation.
Definition n_user.h:52
int only_last_pos
1 => keep only_last_position in waitlist , 0 => send all the positions, default: 1
Definition n_user.h:47
int max
Maximum of user inside the list.
Definition n_user.h:67
LIST * netw_waitlist
N_STR *messages waiting to be sent.
Definition n_user.h:57
pthread_rwlock_t user_rwbolt
Mutex for thread safe user management.
Definition n_user.h:72
int state
State of the current user.
Definition n_user.h:43
VECTOR3D position
actual position
Definition n_user.h:54
NETWORK * netw
Associated NETWORK.
Definition n_user.h:40
int highter
Position of the highter user inside the list.
Definition n_user.h:69
int id
Unique world ident.
Definition n_user.h:49
int nb_rec_pos
Number of saved positions , default: 10.
Definition n_user.h:45
N_USER * list
Pointer to the allocated list of user.
Definition n_user.h:64
int userlist_del_user(N_USERLIST *ulist, int id)
delete an user from the list
Definition n_user.c:114
int userlist_add_msg_to(N_USERLIST *ulist, N_STR *msg, int id)
add a N_STR *message to user list (USERLIST_ONE)
Definition n_user.c:205
int userlist_add_msg_to_ex(N_USERLIST *ulist, N_STR *msg, int mode, int id)
add a N_STR *message to user list
Definition n_user.c:162
#define USERLIST_ONE
flag to target one user in the list
Definition n_user.h:32
int userlist_user_send_waiting_msgs(N_USERLIST *ulist, int id)
send all waiting messages in user 'id' waiting list
Definition n_user.c:282
#define USERLIST_ALL_EXCEPT
flag to target all users in the list except one
Definition n_user.h:30
N_USERLIST * userlist_new(int max)
create a new N_USERLIST user list with 'max' users
Definition n_user.c:14
#define USERLIST_ALL
flag to target all users in the list
Definition n_user.h:28
int userlist_add_msg_to_all(N_USERLIST *ulist, N_STR *msg)
add a N_STR *message to user list (USERLIST_ALL)
Definition n_user.c:215
int userlist_send_waiting_msgs(N_USERLIST *ulist)
send all waiting messages ofr each user of the lsit
Definition n_user.c:305
int userlist_set_position_behavior(N_USERLIST *ulist, int id, int nb_rec_pos, int only_last_pos)
set the position parameters for trajectory processing for user 'id'
Definition n_user.c:51
int userlist_add_user(N_USERLIST *ulist, NETWORK *netw)
add an user to the list
Definition n_user.c:87
int userlist_add_msg_to_all_except(N_USERLIST *ulist, N_STR *msg, int id)
add a N_STR *message to user list except user 'id' (USERLIST_ALL_EXCEPT)
Definition n_user.c:226
int userlist_destroy(N_USERLIST **ulist)
destroy and free a N_USERLIST *userlist
Definition n_user.c:235
int userlist_user_add_waiting_msg(N_USERLIST *ulist, int id, N_STR *netmsg)
add a newtork message to specified user 'id'
Definition n_user.c:259
USER management cell.
Definition n_user.h:35
USER list.
Definition n_user.h:62
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
Definition n_network.c:1928
Structure of a NETWORK.
Definition n_network.h:236
double VECTOR3D[3]
struct of a point
Definition n_3d.h:39
USERS handling for tiny game apps.