int32_t enter_map(struct map *m,struct aoi_object *o,int32_t _x,int32_t _y) { o->current_pos.x = _x; o->current_pos.y = _y; struct map_block *block = get_block_by_point(m,&o->current_pos); if(!block) return -1; dlist_push(&block->aoi_objs,&o->block_node); m->all_aoi_objects[o->aoi_object_id] = o; uint32_t radius = STAND_RADIUS; if(o->view_radius > STAND_RADIUS) { radius = o->view_radius; dlist_push(&m->super_aoi_objs,&o->super_node); } uint32_t x1,y1,x2,y2; x1 = y1 = x2 = y2 = 0; cal_blocks(m,&o->current_pos,radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for(x=x1 ; x <= x2; ++x) { block_process_enter(m,get_block(m,y,x),o); } } o->last_update_tick = GetSystemMs64(); o->is_leave_map = 0; return 0; }
dstrlist* dsplit_on_cs(const dstring* text, const char* on, size_t max) { dstrlist* result = dlist_new(); int slen = strlen(on); unsigned int i, j, k = 0; if (max == 1) { dlist_add(result, text); return result; } else if (max <= 0) { max = text->len; } j = 0; i = dposcs(text, on, 0); while(i != -1) { dlist_push(result, dsub(text, j, i - j)); k++; j = i + slen; if (k + 1 == max) { dlist_push(result, dsub(text, j, text->len - j)); return result; } i = dposcs(text, on, j); } dlist_push(result, dsub(text, j, text->len - j)); return result; }
static inline int8_t _put(msgque_t que,lnode *msg,uint8_t type) { ptq_t ptq = get_per_thread_que(que,MSGQ_WRITE); if(ptq->mode == MSGQ_READ && msg) { msgque_sync_pop(ptq,0); LLIST_PUSH_BACK(&ptq->local_que,msg); return 0; }else if(ptq->mode == MSGQ_WRITE) { ptq->write_que.flag = 1; pts_t pts = get_per_thread_struct(); dlist_push(&pts->per_thread_que,&ptq->write_que.pnode); if(msg)LLIST_PUSH_BACK(&ptq->local_que,msg); if(type == 1) msgque_sync_push(ptq); else if(type == 2){ if(ptq->write_que.flag == 2 || llist_size(&ptq->local_que) >= que->syn_size) msgque_sync_push(ptq); } ptq->write_que.flag = 0; return 0; } return -1; }
static inline void msgque_sync_pop(ptq_t ptq,int32_t timeout) { msgque_t que = ptq->que; mutex_lock(que->mtx); if(timeout > 0){ if(llist_is_empty(&que->share_que) && timeout){ uint64_t end = GetSystemMs64() + (uint64_t)timeout; dlist_push(&que->blocks,&ptq->read_que.bnode); do{ if(0 != condition_timedwait(ptq->cond,que->mtx,timeout)){ //timeout dlist_remove(&ptq->read_que.bnode); break; } uint64_t l_now = GetSystemMs64(); if(l_now < end) timeout = end - l_now; else break;//timeout }while(llist_is_empty(&que->share_que)); } } /*else if(llist_is_empty(&que->share_que)) { dlist_push(&que->blocks,&ptq->read_que.bnode); do{ condition_wait(ptq->cond,que->mtx); }while(llist_is_empty(&que->share_que)); }*/ if(!llist_is_empty(&que->share_que)) llist_swap(&ptq->local_que,&que->share_que); mutex_unlock(que->mtx); }
void _hashtable_rehash(HASHTABLE *t, size_t newsize) { ARRAY table; DLIST *bucket; size_t i, j, hash; DLIST_ITER it, end; array_init(&table, sizeof(DLIST)); array_resize(&table, newsize); for (i = 0; i != newsize; ++i) { dlist_init((DLIST*)array_at(&table, i), t->element_size); } j = array_size(&t->table); for (i = 0; i != j; ++i) { bucket = (DLIST*)array_at(&t->table, i); if (dlist_size(bucket)) { end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { hash = _hashtable_hash(t, dlist_at(it)) % newsize; dlist_push((DLIST*)array_at(&table, hash), dlist_at(it)); } } } array_destroy(&t->table); memcpy(&t->table, &table, sizeof(ARRAY)); }
void msgque_putinterrupt(msgque_t que,void *ud,interrupt_function callback) { mutex_lock(que->mtx); ptq_t ptq = get_per_thread_que(que,MSGQ_READ); ptq->read_que.ud = ud; ptq->read_que.notify_function = callback; dlist_push(&que->can_interrupt,&ptq->read_que.bnode); mutex_unlock(que->mtx); }
void line_list_push(line_t *line, line_list_t *list) { dlink_t *link; assert(line); assert(list); line_inc_ref(line); link = dlink_new(), link->object = (void *)line; dlist_push(link, (dlist_t *)list); }
void point_list_push(point_t *p, point_list_t *list) { dlink_t *link; assert(p); assert(list); point_inc_ref(p); link = dlink_new(); link->object = (void *)p; dlist_push(link, list); }
static inline pts_t get_per_thread_struct() { pts_t pts = (pts_t)pthread_getspecific(g_msg_que_key); if(!pts){ pts = calloc(1,sizeof(*pts)); dlist_init(&pts->per_thread_que); pthread_setspecific(g_msg_que_key,(void*)pts); pts->thread_id = pthread_self(); #ifdef MQ_HEART_BEAT //关联到heart_beat中 hb_t hb = get_heart_beat(); mutex_lock(hb->mtx); dlist_push(&hb->thread_structs,&pts->hnode); mutex_unlock(hb->mtx); #endif } return pts; }
int32_t epoll_register(poller_t e, socket_t s) { assert(e);assert(s); int32_t ret = -1; struct epoll_event ev; ev.data.ptr = s; if(s->socket_type == DATA) ev.events = EV_IN | EV_OUT | EV_ET | EPOLLRDHUP; else if(s->socket_type == LISTEN) ev.events = EV_IN; else if(s->socket_type == CONNECT){ ev.events = EV_IN | EV_OUT | EV_ET; dlist_push(&e->connecting,(struct dnode*)s); }else return -1; TEMP_FAILURE_RETRY(ret = epoll_ctl(e->poller_fd,EPOLL_CTL_ADD,s->fd,&ev)); return ret; }
void hashtable_insert(HASHTABLE *t, const void *key) { size_t size, hash; DLIST *bucket; DLIST_ITER it, end; size = array_size(&t->table); if ((long double)t->size / size >= 0.77) { _hashtable_rehash(t, size*2); } size = array_size(&t->table); hash = _hashtable_hash(t, key) % size; bucket = (DLIST*)array_at(&t->table, hash); end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { if (t->compare(key, dlist_at(it)) == 0) { memcpy(dlist_at(it), key, t->element_size); return; } } dlist_push(bucket, key); ++t->size; }
/* some problem is occurred due to co-linear pixels, * so it need to be check the maximum distance within same minimum angle * comment : if break statement in the Right chain growth routine is converted * from "if (ycoord[imin] < ycoord[i-1]) break;" * to "if (ycoord[imin] <= ycoord[i-1]) break;" * , then some problem is removed. * However, if an point exits * such that is resemble to "ycoord" of the extreme point * and has the minimum angle * then the convex hull that we want don't be created. */ static int jarvismarch(polygon_t *chull, point_list_t *points) { real_t ang, dist, ymin; real_t amin, dmax, dx, dy; dlink_t *x, *y, *ax, *bx; point_t *p, *q; assert(chull); assert(points); assert(point_list_get_count(points) >= 3); // Preparing the polygon, and // Find the point with minimum value of y-coordinate for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; y = dlink_new(); point_inc_ref(p); y->object = (void *)p; dlist_insert(y, chull); if (ax == NULL || point_get_y(p) < ymin) { ax = y; ymin = point_get_y(p); } } dlink_cutoff(ax); dlist_dec_count(chull); dlist_push(ax, chull); point_dump((point_t *)ax->object); // Scan right chain for (ax = chull->tail->next; ax->next != chull->head; ax = ax->next) { p = (point_t *)ax->object; for (bx = NULL, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(q) - point_get_x(p); dy = point_get_y(q) - point_get_y(p); ang = arctan2r(dy, dx); dist = sqrt(sqr(dx) + sqr(dy)); // Find another vertex with min-angle and max-distance if (bx == NULL || ang < amin) { bx = x; amin = ang; dmax = dist; } else if (ang == amin && dist > dmax) { bx = x; dmax = dist; } } q = (point_t *)bx->object; // Right chain complete ? if (point_get_y(q) < point_get_y(p)) break; // Swapping (coordinations and mark) dlink_cutoff(bx); dlink_append(bx, ax); point_dump((point_t *)bx->object); } //printf("n: %d\n", convexhull->count); // Scan left chain for (; ax->next != chull->head; ax = ax->next) { p = (point_t *)ax->object; for (bx = NULL, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(p) - point_get_x(q); dy = point_get_y(p) - point_get_y(q); ang = arctan2r(dy, dx); dist = sqrt(sqr(dx) + sqr(dy)); if (bx == NULL || ang < amin) { bx = x; amin = ang; dmax = dist; } else if (ang == amin && dist > dmax) { bx = x; dmax = dist; } } y = chull->tail->next; q = (point_t *)y->object; dx = point_get_x(p) - point_get_x(q); dy = point_get_y(p) - point_get_y(q); ang = arctan2r(dy, dx); // Convexhull complete ? if (ang < amin) break; // Swapping dlink_cutoff(bx); dlink_append(bx, ax); point_dump((point_t *)bx->object); } //printf("n: %d\n", convexhull->count); while (ax->next != chull->head) { x = ax->next; dlink_cutoff(x); dlist_dec_count(chull); point_destroy((point_t *)x->object); dlink_destroy(x); } return dlist_get_count(chull); }
/* Graham's Scan * Given a set of points on the plane, Graham's scan computes their convex hull. * The algorithm works in three phases: * 1. Find an extreme point. * This point will be the pivot, is guaranteed to be on the hull, * and is chosen to be the point with largest y coordinate. * 2. Sort the points in order of increasing angle about the pivot. * We end up with a star-shaped polygon (one in which one special point, * in this case the pivot, can "see" the whole polygon). * 3. Build the hull, by marching around the star-shaped poly, adding edges * when we make a left turn, and back-tracking when we make a right turn. */ static int grahamscan(polygon_t *chull, point_list_t *points) { int i; real_t dx, dy, ymin; real_t *ang; point_t *p, *q; point_t *v1, *v2, *v3; dlink_t *ax, *bx, *cx, *x, *y, *tmp; assert(chull); assert(points); assert(point_list_get_count(points) >= 3); ang = (real_t *)malloc(point_list_get_count(points) * sizeof(real_t)); assert(ang); // Find an extreme point // Preparing the polygon, and // Find the point with minimum value of y-coordinate for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; y = dlink_new(); point_inc_ref(p); y->object = (void *)p; dlist_insert(y, chull); if (ax == NULL || point_get_y(p) < ymin) { ax = y; ymin = point_get_y(p); } } dlink_cutoff(ax); dlist_dec_count(chull); dlist_push(ax, chull); // Sort the points in order of increasing angle about the pivot. p = (point_t *)ax->object; //point_dump(p); for (i = 0, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(q) - point_get_x(p); dy = point_get_y(q) - point_get_y(p); ang[i] = arctan2r(dy, dx); x->spare = (void *)&(ang[i]); i++; //point_dump(q); //printf("ang: %lf\n", ang[i-1]); } for (x = ax->next; x->next != chull->head; x = x->next) { for (y = x->next; y != chull->head; y = y->next) { if (*((real_t *)y->spare) < *((real_t *)x->spare)) { dlink_exchange(x, y); tmp = x, x = y, y = tmp; } } } //point_dump((point_t *)c->object); v1 = point_new(); v2 = point_new(); v3 = point_new(); cx = chull->tail->next->next->next; while (cx != chull->head) { bx = cx->prev; ax = bx->prev; point_subtract(v1, (point_t *)ax->object, (point_t *)bx->object); point_subtract(v2, (point_t *)cx->object, (point_t *)bx->object); point_xproduct(v3, v1, v2); // Convex ? if (point_get_z(v3) < 0) { cx = cx->next; } else { dlink_cutoff(bx); dlist_dec_count(chull); point_destroy((point_t *)bx->object); dlink_destroy(bx); } } for (x = chull->tail->next; x != chull->head; x = x->next) x->spare = NULL; point_destroy(v3); point_destroy(v2); point_destroy(v1); free(ang); return dlist_get_count(chull); }
//��o�ƶ���new_pos,��������Ұ�仯 void move_to(struct map *m,struct aoi_object *o,int32_t _x,int32_t _y) { struct point2D new_pos = {_x,_y}; struct point2D old_pos = o->current_pos; o->current_pos = new_pos; struct map_block *old_block = get_block_by_point(m,&old_pos); struct map_block *new_block = get_block_by_point(m,&new_pos); if(old_block != new_block) dlist_remove(&o->block_node); uint32_t radius = STAND_RADIUS; if(o->view_radius > STAND_RADIUS) radius = o->view_radius; //�����¾ɹ������� uint32_t n_x1,n_y1,n_x2,n_y2; uint32_t o_x1,o_y1,o_x2,o_y2; n_x1 = n_y1 = n_x2 = n_y2 = 0; o_x1 = o_y1 = o_x2 = o_y2 = 0; cal_blocks(m,&old_pos,radius,&o_x1,&o_y1,&o_x2,&o_y2); cal_blocks(m,&new_pos,radius,&n_x1,&n_y1,&n_x2,&n_y2); uint32_t y = n_y1; uint32_t x = 0; for( ; y <= n_y2; ++y) { for( x = n_x1; x <= n_x2; ++x) { if(x >= o_x1 && x <= o_x2 && y >= o_y1 && y <= o_y2) { //�ޱ仯���� struct map_block *bl = get_block(m,y,x); struct aoi_object *cur = (struct aoi_object*)bl->aoi_objs.head.next; while(cur != (struct aoi_object*)&bl->aoi_objs.tail) { uint64_t distance = cal_distance_2D(&new_pos,&cur->current_pos); if(o != cur) { if(o->view_radius >= distance && !is_set(&o->self_view_objs,cur->aoi_object_id)) enter_me(m,o,cur); else if(o->view_radius < distance && is_set(&o->self_view_objs,cur->aoi_object_id)) leave_me(m,o,cur); if(cur->view_radius >= distance && !is_set(&cur->self_view_objs,o->aoi_object_id)) enter_me(m,cur,o); else if(cur->view_radius < distance && is_set(&cur->self_view_objs,o->aoi_object_id)) leave_me(m,cur,o); } cur = (struct aoi_object *)cur->block_node.next; } } else { //�½�������� block_process_enter(m,get_block(m,y,x),o); } } } if(old_block != new_block) dlist_push(&new_block->aoi_objs,&o->block_node); y = o_y1; for( ; y <= o_y2; ++y) { for(x = o_x1; x <= o_x2; ++x) { if(x >= n_x1 && x <= n_x2 && y >= n_y1 && y <= n_y2) continue;//���ﲻ�����ޱ仯���� block_process_leave(m,get_block(m,y,x),o,0); } } o->last_update_tick = GetSystemMs64(); }