예제 #1
0
파일: aoi.c 프로젝트: archyyu/kendylib
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;	
	}
	
}
예제 #2
0
파일: aoi.c 프로젝트: archyyu/kendylib
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;
	
}
예제 #3
0
파일: co_sche.c 프로젝트: archyyu/kendylib
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);
}
예제 #4
0
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;
}
예제 #5
0
파일: co_sche.c 프로젝트: archyyu/kendylib
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");
		}
	}
}
예제 #6
0
파일: co_sche.c 프로젝트: archyyu/kendylib
void coro_sleep(coro_t co,int32_t ms)
{
	co->timeout = GetCurrentMs() + ms;
	sche_add_timeout(co->_sche,co);
}
예제 #7
0
파일: aoi.c 프로젝트: archyyu/kendylib
//将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();
}
예제 #8
0
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);
			}
		}
	}
}