static inline tick_super_object(struct map *m,struct aoi_object *o) { uint32_t now = GetCurrentMs(); if(now - o->last_update_tick >= UPDATE_INTERVAL) { //remove out of view object first uint32_t i = 0; for( ; i < MAX_BITS; ++i) { if(o->self_view_objs.bits[i] > 0) { uint32_t j = 0; for( ; j < sizeof(uint32_t); ++j) { if(o->self_view_objs.bits[i] & (1 << j)) { uint32_t aoi_object_id = i*sizeof(uint32_t) + j; if(aoi_object_id != o->aoi_object_id) { struct aoi_object *other = m->all_aoi_objects[aoi_object_id]; if(other->is_leave_map) leave_me(m,o,other); else { uint64_t distance = cal_distance_2D(&o->current_pos,&other->current_pos); if(distance > o->view_radius) leave_me(m,o,other); } } } } } } //process enter view uint32_t x1,y1,x2,y2; cal_blocks(m,&o->current_pos,o->view_radius,&x1,&y1,&x2,&y2); uint32_t y = y1; uint32_t x; for( ; y <= y2; ++y) { for( x=x1; x <= x2; ++x) { 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) { if(is_set(&o->self_view_objs,cur->aoi_object_id) == 0) { uint64_t distance = cal_distance_2D(&o->current_pos,&cur->current_pos); if(o->view_radius >= distance) enter_me(m,o,cur); } cur = (struct aoi_object *)cur->block_node.next; } } } o->last_update_tick = now; } }
int32_t enter_map(struct map *m,struct aoi_object *o) { struct map_block *block = get_block_by_point(m,&o->current_pos); if(!block) return -1; double_link_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; double_link_push(&m->super_aoi_objs,&o->super_node); } uint32_t x1,y1,x2,y2; 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 = GetCurrentMs(); o->is_leave_map = 0; }
static inline void sche_next(sche_t s,coro_t co,uint8_t status) { co->status = status; uint32_t tick = GetCurrentMs(); if(tick >= s->next_check_timeout) check_time_out(s,tick); _sche_next(s,co); }
int32_t connection_send(struct connection *c,wpacket_t w,packet_send_finish callback) { st_io *O; if(w) { w->send_tick = GetCurrentMs(); w->_packet_send_finish = callback; LINK_LIST_PUSH_BACK(c->send_list,w); } if(!c->send_overlap.isUsed) { O = prepare_send(c); if(O) { c->send_overlap.isUsed = 1; return Post_Send(c->socket,O); } } return 0; }
void sche_schedule(sche_t s) { uint32_t now = GetCurrentMs(); if(now >= s->next_check_timeout) check_time_out(s,now); if(link_list_is_empty(s->active_list_1) && link_list_is_empty(s->active_list_2)) { if(s->idel) s->idel(s->idel_arg); else sleepms(50); } else { coro_t co = _sche_next(s,s->co); if(co->status == CORO_DIE && co->_heapele.index == 0) { coro_destroy(&co); printf("a coro destroy\n"); } } }
void coro_sleep(coro_t co,int32_t ms) { co->timeout = GetCurrentMs() + ms; sche_add_timeout(co->_sche,co); }
//将o移动到new_pos,并计算视野变化 void move_to(struct map *m,struct aoi_object *o,struct point2D *new_pos) { 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) double_link_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; 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; 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); 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); 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) double_link_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 = GetCurrentMs(); }
void RecvFinish(int32_t bytestransfer,st_io *io) { struct OVERLAPCONTEXT *OVERLAP = (struct OVERLAPCONTEXT *)io; struct connection *c = OVERLAP->c; uint32_t recv_size; uint32_t free_buffer_size; buffer_t buf; uint32_t pos; int32_t i = 0; uint32_t err_code = io->err_code; for(;;) { if(bytestransfer == 0 || (bytestransfer < 0 && err_code != EAGAIN)) { printf("recv close\n"); c->recv_overlap.isUsed = 0; c->is_close = 1; if(!c->send_overlap.isUsed) { //-1,passive close c->_on_disconnect(c,-1); } break; } else if(bytestransfer < 0 && err_code == EAGAIN) { break; } else { int32_t total_size = 0; while(bytestransfer > 0) { c->last_recv = GetCurrentMs(); //total_size += bytestransfer; update_next_recv_pos(c,bytestransfer); c->unpack_size += bytestransfer; total_size += bytestransfer; unpack(c); buf = c->next_recv_buf; pos = c->next_recv_pos; recv_size = BUFFER_SIZE; i = 0; while(recv_size) { free_buffer_size = buf->capacity - pos; free_buffer_size = recv_size > free_buffer_size ? free_buffer_size:recv_size; c->wrecvbuf[i].iov_len = free_buffer_size; c->wrecvbuf[i].iov_base = buf->buf + pos; recv_size -= free_buffer_size; pos += free_buffer_size; if(recv_size && pos >= buf->capacity) { pos = 0; if(!buf->next) buf->next = buffer_create_and_acquire(c->mt,NULL,BUFFER_SIZE); buf = buf->next; } ++i; } c->recv_overlap.isUsed = 1; c->recv_overlap.m_super.iovec_count = i; c->recv_overlap.m_super.iovec = c->wrecvbuf; if(total_size > 65536) { Post_Recv(c->socket,&c->recv_overlap.m_super); return; } else bytestransfer = Recv(c->socket,&c->recv_overlap.m_super,&err_code); } } } }