int find_path(AStar_t astar,int x,int y,int x1,int y1,kn_dlist *path){ AStarNode *from = get_node(astar,x,y); AStarNode *to = get_node(astar,x1,y1); if(!from || !to || from == to || to->block) return 0; minheap_insert(astar->open_list,&from->heap); AStarNode *current_node = NULL; while(1){ struct heapele *e = minheap_popmin(astar->open_list); if(!e){ reset(astar); return 0; } current_node = (AStarNode*)((int8_t*)e-sizeof(kn_dlist_node)); if(current_node == to){ while(current_node) { kn_dlist_remove((kn_dlist_node*)current_node);//可能在close_list中,需要删除 if(current_node != from)//当前点无需加入到路径点中 kn_dlist_push_front(path,(kn_dlist_node*)current_node); AStarNode *t = current_node; current_node = current_node->parent; t->parent = NULL; t->F = t->G = t->H = 0; t->heap.index = 0; } reset(astar); return 1; } //current插入到close表 kn_dlist_push(&astar->close_list,(kn_dlist_node*)current_node); //获取current的相邻节点 kn_dlist *neighbors = get_neighbors(astar,current_node); if(neighbors) { AStarNode *n; while((n = (AStarNode*)kn_dlist_pop(neighbors))){ if(n->heap.index)//在openlist中 { float new_G = current_node->G + cost_2_neighbor(current_node,n); if(new_G < n->G) { //经过当前neighbor路径更佳,更新路径 n->G = new_G; n->F = n->G + n->H; n->parent = current_node; minheap_change(astar->open_list,&n->heap); } continue; } n->parent = current_node; n->G = current_node->G + cost_2_neighbor(current_node,n); n->H = cost_2_goal(n,to); n->F = n->G + n->H; minheap_insert(astar->open_list,&n->heap); } neighbors = NULL; } } }
static inline void reset(AStar_t astar){ //清理close list AStarNode *n = NULL; while((n = (AStarNode*)kn_dlist_pop(&astar->close_list))){ n->G = n->H = n->F = 0; } //清理open list minheap_clear(astar->open_list,_clear); }
void kn_CURLM_cleanup(kn_CURLM_t cm){ if(cm->timer) kn_del_timer(cm->timer); kn_CURL_t curl; while((curl = (kn_CURL_t)kn_dlist_pop(&cm->curls))) kn_curl_easy_cleanup(curl); curl_multi_cleanup(cm->c_handle); free(cm); return; }
void kn_close_msgque(kn_msgque_t _msgque){ kn_msgque *msgque = (kn_msgque*)cast2refobj(_msgque); if(msgque){ kn_mutex_lock(msgque->mtx); do{ if(msgque->closing) break; msgque->closing = 1; //唤醒waits kn_msgque_reader_t reader; while((reader = (kn_msgque_reader_t)kn_dlist_pop(&msgque->waits))) kn_condition_signal(reader->cond); }while(0); kn_mutex_lock(msgque->mtx); refobj_dec((refobj*)msgque); } }
static inline int write_nobuff(kn_msgque* msgque,struct msg *msg){ int ret = 0; errno = 0; kn_mutex_lock(msgque->mtx); do{ kn_list_pushback(&msgque->shareque,(kn_list_node*)msg); if(msgque->closing){ errno = MSGQUE_CLOSE; ret = -1; break; } //检查是否有wait的线程 kn_msgque_reader_t reader = (kn_msgque_reader_t)kn_dlist_pop(&msgque->waits); if(reader) kn_condition_signal(reader->cond); }while(0); kn_mutex_unlock(msgque->mtx); return ret; }
int32_t kn_epoll_loop(kn_proactor_t p,int32_t ms) { uint64_t sleep_ms; uint64_t timeout = kn_systemms64() + (uint64_t)ms; uint64_t current_tick; int32_t nfds; int32_t i; uint64_t l_now; kn_dlist* actived; kn_fd_t s; kn_epoll* ep = (kn_epoll*)p; if(ms < 0) ms = 0; do{ if(!kn_dlist_empty(&p->connecting)){ l_now = kn_systemms64(); kn_dlist_check_remove(&p->connecting,check_connect_timeout,(void*)&l_now); } actived = kn_proactor_activelist(p); if(!kn_dlist_empty(actived)){ p->actived_index = (p->actived_index+1)%2; while((s = (kn_fd_t)kn_dlist_pop(actived)) != NULL){ if(s->process(s)) kn_procator_putin_active(p,s); } } current_tick = kn_systemms64(); actived = kn_proactor_activelist(p); if(kn_dlist_empty(actived)) sleep_ms = timeout > current_tick ? timeout - current_tick:0; else sleep_ms = 0; nfds = _epoll_wait(ep->epfd,ep->events,ep->eventsize,(uint32_t)sleep_ms); if(nfds < 0) return -1; for(i=0; i < nfds ; ++i) { s = (kn_fd_t)ep->events[i].data.ptr; s->on_active(s,ep->events[i].events); } current_tick = kn_systemms64(); }while(timeout > current_tick); return 0; }
static inline int msgque_flush(kn_msgque_writer_t writer){ int ret = 0; errno = 0; kn_msgque* msgque = writer->msgque; kn_mutex_lock(msgque->mtx); do{ if(msgque->closing){ errno = MSGQUE_CLOSE; ret = -1; break; } kn_list_swap(&msgque->shareque,&writer->writebuff); //检查是否有wait的线程 kn_msgque_reader_t reader = (kn_msgque_reader_t)kn_dlist_pop(&msgque->waits); if(reader) kn_condition_signal(reader->cond); }while(0); kn_mutex_unlock(msgque->mtx); return ret; }
static int lua_findpath(lua_State *L){ AStar_t astar = lua_touserdata(L,1); int x1 = lua_tonumber(L,2); int y1 = lua_tonumber(L,3); int x2 = lua_tonumber(L,4); int y2 = lua_tonumber(L,5); kn_dlist path;kn_dlist_init(&path); if(find_path(astar,x1,y1,x2,y2,&path)){ int i = 1; lua_newtable(L); AStarNode *n; while((n = (AStarNode*)kn_dlist_pop(&path))){ lua_newtable(L); lua_pushinteger(L,n->x); lua_rawseti(L,-2,1); lua_pushinteger(L,n->y); lua_rawseti(L,-2,2); lua_rawseti(L,-2,i++); } }else lua_pushnil(L); return 1; }
static inline void clear_neighbors(AStar_t astar){ while(!kn_dlist_empty(&astar->neighbors)) kn_dlist_pop(&astar->neighbors); }