|
|
//gcc -o aoi aoi.c utils.c
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
#include <time.h>
|
|
|
|
|
|
#include <lua.h>
|
|
|
#include <lualib.h>
|
|
|
#include <lauxlib.h>
|
|
|
|
|
|
#include "utils.h"
|
|
|
#include "aoi.h"
|
|
|
|
|
|
static int NEARBY_CEIL_OFFSETS[9][2] = {
|
|
|
{0, 0}, // center
|
|
|
{-1, 1}, // TL
|
|
|
{0, 1}, // T
|
|
|
{1, 1}, // TR
|
|
|
|
|
|
{-1, 0}, // L
|
|
|
{1, 0}, // R
|
|
|
|
|
|
{-1, -1}, // BL
|
|
|
{0, -1}, // B
|
|
|
{1, -1}, // BR
|
|
|
};
|
|
|
|
|
|
static double cost_time_in_lua = 0.0;
|
|
|
static double cost_time_in_cal = 0.0;
|
|
|
static double cost_time_in_get_event = 0.0;
|
|
|
|
|
|
static int get_grid_idx(World *w, int x, int y)
|
|
|
{
|
|
|
return (x - 1) * (w->col) + y - 1;
|
|
|
};
|
|
|
|
|
|
static void get_xy_by_grididx(World *w, int grid_idx, int *x, int *y)
|
|
|
{
|
|
|
*x = (grid_idx / w->col) + 1;
|
|
|
*y = grid_idx - ((*x) - 1) * w->col + 1;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
static int out_of_range(World *w, int grid_idx, int idx)
|
|
|
{
|
|
|
int x1, y1;
|
|
|
get_xy_by_grididx(w, grid_idx, &x1, &y1);
|
|
|
int x2, y2;
|
|
|
get_xy_by_grididx(w, idx, &x2, &y2);
|
|
|
if ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) > 2)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static HashTable *get_nearby_grids(World *w, Grid *grid)
|
|
|
{
|
|
|
int grid_num = w->row * w->col;
|
|
|
HashTable *ret = hashtbl_create();
|
|
|
|
|
|
int x, y;
|
|
|
get_xy_by_grididx(w, grid->idx, &x, &y);
|
|
|
int i, _x, _y;
|
|
|
for (i = 0; i < 9; i++)
|
|
|
{
|
|
|
_x = x + NEARBY_CEIL_OFFSETS[i][0];
|
|
|
_y = y + NEARBY_CEIL_OFFSETS[i][1];
|
|
|
if (_x >= 1 && _x <= w->row && _y >= 1 && _y <= w->col)
|
|
|
{
|
|
|
int tmp_idx = get_grid_idx(w, _x, _y);
|
|
|
Grid *grid = w->grids[tmp_idx];
|
|
|
hashtbl_upsert(ret, tmp_idx, grid);
|
|
|
//printf("get_nearby_grids %d %d\n",grid->idx,tmp_idx);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// for (int i = -1; i<=1; i++){
|
|
|
// for (int j= -1; j<=1; j++){
|
|
|
// int index = i*w->col + grid->idx + j;
|
|
|
// if(index >= 0 && index < grid_num){
|
|
|
// Grid* grid = w->grids[index];
|
|
|
// hashtbl_upsert(ret, index, grid);
|
|
|
// }
|
|
|
// }
|
|
|
// }
|
|
|
// local k = i*col + cur_grididx + j
|
|
|
// local grid = grids[k]
|
|
|
// if grid and not ret[k] then
|
|
|
// ret[k] = grid
|
|
|
// end
|
|
|
// end
|
|
|
// end
|
|
|
// return ret
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static void print_event(int grid_idx, char flag, HashTable *events)
|
|
|
{
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(events, &iter))
|
|
|
{
|
|
|
Event *e = (Event *)(iter.node->value);
|
|
|
printf("flag:%c grid_idx:%d event:%c,id:%d,x:%d,y:%d\n", flag, grid_idx, e->e, e->id, e->x, e->y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void get_grid_add_event(Grid *grid, lua_State *L)
|
|
|
{ //你进入某个格子,要知道该格子的事情
|
|
|
int idx_grid_info = lua_gettop(L); //2
|
|
|
lua_rawgeti(L, idx_grid_info, grid->idx);
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_info, grid->idx);
|
|
|
}
|
|
|
int idx_grid_detail = lua_gettop(L); //3
|
|
|
lua_rawgeti(L, idx_grid_detail, 1); //key_idx==1
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_detail, 1);
|
|
|
}
|
|
|
int idx_grid_add_del_update = lua_gettop(L); //4
|
|
|
size_t tbl_len = lua_rawlen(L, idx_grid_add_del_update);
|
|
|
if (tbl_len == 0)
|
|
|
{
|
|
|
int len = 1;
|
|
|
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(grid->caches, &iter))
|
|
|
{
|
|
|
Cache *cache = (Cache *)(iter.node->value);
|
|
|
if (cache->e == 'A' || cache->e == 'U')
|
|
|
{
|
|
|
lua_newtable(L);
|
|
|
lua_pushinteger(L, 1); //'A'
|
|
|
lua_rawseti(L, -2, 1);
|
|
|
lua_pushinteger(L, cache->id);
|
|
|
lua_rawseti(L, -2, 2);
|
|
|
lua_pushinteger(L, cache->x);
|
|
|
lua_rawseti(L, -2, 3);
|
|
|
lua_pushinteger(L, cache->y);
|
|
|
lua_rawseti(L, -2, 4);
|
|
|
|
|
|
lua_rawseti(L, idx_grid_add_del_update, len);
|
|
|
len = len + 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(grid->makers, &iter))
|
|
|
{
|
|
|
Obj *obj = (Obj *)(iter.node->value);
|
|
|
if (!hashtbl_get(grid->caches, obj->id))
|
|
|
{ //如果在cache中且没进入event_adds,说明e是D
|
|
|
lua_newtable(L);
|
|
|
lua_pushinteger(L, 1); //'A'
|
|
|
lua_rawseti(L, -2, 1);
|
|
|
lua_pushinteger(L, obj->id);
|
|
|
lua_rawseti(L, -2, 2);
|
|
|
lua_pushinteger(L, obj->x);
|
|
|
lua_rawseti(L, -2, 3);
|
|
|
lua_pushinteger(L, obj->y);
|
|
|
lua_rawseti(L, -2, 4);
|
|
|
|
|
|
lua_rawseti(L, idx_grid_add_del_update, len);
|
|
|
len = len + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void get_grid_del_event(Grid *grid, lua_State *L)
|
|
|
{ //你离开某个格子,要知道该格子的事情
|
|
|
int idx_grid_info = lua_gettop(L); //2
|
|
|
lua_rawgeti(L, idx_grid_info, grid->idx);
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_info, grid->idx);
|
|
|
}
|
|
|
int idx_grid_detail = lua_gettop(L); //3
|
|
|
lua_rawgeti(L, idx_grid_detail, 2); //key_idx==2
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_detail, 2);
|
|
|
}
|
|
|
int idx_grid_add_del_update = lua_gettop(L); //4
|
|
|
size_t tbl_len = lua_rawlen(L, idx_grid_add_del_update);
|
|
|
if (tbl_len == 0)
|
|
|
{
|
|
|
int len = 1;
|
|
|
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
//cache中还没加进makers的就不管了
|
|
|
while (hashtbl_iter(grid->makers, &iter))
|
|
|
{
|
|
|
Obj *obj = (Obj *)(iter.node->value);
|
|
|
lua_newtable(L);
|
|
|
|
|
|
lua_pushinteger(L, 2); //'D'
|
|
|
lua_rawseti(L, -2, 1);
|
|
|
lua_pushinteger(L, obj->id);
|
|
|
lua_rawseti(L, -2, 2);
|
|
|
lua_pushinteger(L, obj->x);
|
|
|
lua_rawseti(L, -2, 3);
|
|
|
lua_pushinteger(L, obj->y);
|
|
|
lua_rawseti(L, -2, 4);
|
|
|
|
|
|
lua_rawseti(L, idx_grid_add_del_update, len);
|
|
|
len = len + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void get_grid_update_event(Grid *grid, lua_State *L)
|
|
|
{ //你在某个格子附近晃,要知道该格子的事情
|
|
|
int idx_grid_info = lua_gettop(L); //2
|
|
|
lua_rawgeti(L, idx_grid_info, grid->idx);
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_info, grid->idx);
|
|
|
}
|
|
|
int idx_grid_detail = lua_gettop(L); //3
|
|
|
lua_rawgeti(L, idx_grid_detail, 3); //key_idx==3
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_grid_detail, 3);
|
|
|
}
|
|
|
int idx_grid_add_del_update = lua_gettop(L); //4
|
|
|
size_t tbl_len = lua_rawlen(L, idx_grid_add_del_update);
|
|
|
if (tbl_len == 0)
|
|
|
{
|
|
|
int len = 1;
|
|
|
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(grid->caches, &iter))
|
|
|
{
|
|
|
Cache *cache = (Cache *)(iter.node->value);
|
|
|
lua_newtable(L);
|
|
|
if (cache->e == 'A')
|
|
|
{
|
|
|
lua_pushinteger(L, 1); //'A'
|
|
|
}
|
|
|
else if (cache->e == 'D')
|
|
|
{
|
|
|
lua_pushinteger(L, 2);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
lua_pushinteger(L, 3);
|
|
|
}
|
|
|
lua_rawseti(L, -2, 1);
|
|
|
lua_pushinteger(L, cache->id);
|
|
|
lua_rawseti(L, -2, 2);
|
|
|
lua_pushinteger(L, cache->x);
|
|
|
lua_rawseti(L, -2, 3);
|
|
|
lua_pushinteger(L, cache->y);
|
|
|
lua_rawseti(L, -2, 4);
|
|
|
|
|
|
lua_rawseti(L, idx_grid_add_del_update, len);
|
|
|
len = len + 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//结果处理
|
|
|
static void add_grid_events_to_watchers(Grid *grid, char e, int id, lua_State *L)
|
|
|
{
|
|
|
//printf("add_grid_events_to_watchers %d %c %d\n", grid->idx, e, id);
|
|
|
//clock_t t1 = clock();
|
|
|
//HashTable* events;
|
|
|
int key_idx;
|
|
|
if (e == 'U')
|
|
|
{ //3
|
|
|
get_grid_update_event(grid, L);
|
|
|
key_idx = 3;
|
|
|
}
|
|
|
else if (e == 'A')
|
|
|
{ //1
|
|
|
get_grid_add_event(grid, L);
|
|
|
key_idx = 1;
|
|
|
}
|
|
|
else if (e == 'D')
|
|
|
{ //2
|
|
|
get_grid_del_event(grid, L);
|
|
|
key_idx = 2;
|
|
|
}
|
|
|
//clock_t t2 = clock();
|
|
|
//double t3 = (double)(t2-t1)/CLOCKS_PER_SEC;
|
|
|
//cost_time_in_get_event += t3;
|
|
|
|
|
|
//clock_t time_begin = clock();
|
|
|
//不copy,直接用引用
|
|
|
int idx_ret = 1;
|
|
|
//将events upsert进L
|
|
|
//printf("upsert events succ %d\n",idx_grid_add_del_update);
|
|
|
|
|
|
lua_rawgeti(L, idx_ret, id);
|
|
|
if (lua_isnil(L, -1))
|
|
|
{
|
|
|
lua_pop(L, 1);
|
|
|
lua_newtable(L);
|
|
|
lua_pushvalue(L, -1);
|
|
|
lua_rawseti(L, idx_ret, id);
|
|
|
}
|
|
|
int idx_watcher_ret = lua_gettop(L); //5
|
|
|
size_t tbl_len = lua_rawlen(L, idx_watcher_ret);
|
|
|
lua_pushvalue(L, 4);
|
|
|
lua_rawseti(L, idx_watcher_ret, tbl_len + 1);
|
|
|
lua_pop(L, 3);
|
|
|
|
|
|
// lua_rawgeti(L, idx_watcher_ret, grid->idx);
|
|
|
// if(lua_isnil(L,-1)){
|
|
|
// lua_pop(L,1);
|
|
|
// lua_newtable(L);
|
|
|
// lua_pushvalue(L,-1);
|
|
|
// lua_rawseti(L, idx_watcher_ret, grid->idx);
|
|
|
// }
|
|
|
// int idx_watcher_grid_ret = lua_gettop(L);//6
|
|
|
// lua_pushvalue(L, 4);//引用,idx_grid_add_del_update==4
|
|
|
// lua_rawseti(L, idx_watcher_grid_ret, key_idx);
|
|
|
// lua_pop(L,4);
|
|
|
//clock_t time_end = clock();
|
|
|
//double time_cost = (double)(time_end-time_begin)/CLOCKS_PER_SEC;
|
|
|
//cost_time_in_lua += time_cost;
|
|
|
//printf("===cost_time_in_lua:%f====\n", cost_time_in_lua);
|
|
|
}
|
|
|
|
|
|
//watcher到了grid
|
|
|
static void resolve_change_watcher(World *w, Grid *grid, HashTable *right_grid_map, int pre_idx, int id, lua_State *L)
|
|
|
{
|
|
|
//printf("resolve_change_watcher id:%d grid_idx:%d pre_idx:%d\n",id, grid->idx, pre_idx);
|
|
|
HashTableIter iter;
|
|
|
HashTable *left_grid_map;
|
|
|
if (pre_idx != -1)
|
|
|
{
|
|
|
// int x,y;
|
|
|
// get_xy_by_grididx(w,pre_idx,&x,&y);
|
|
|
// int i, _x, _y;
|
|
|
// for(i=0; i<9; i++) {
|
|
|
// _x = x + NEARBY_CEIL_OFFSETS[i][0];
|
|
|
// _y = y + NEARBY_CEIL_OFFSETS[i][1];
|
|
|
// if (!(_x>=1&&_x<=w->row&&_y>=1&&_y<=w->col)){
|
|
|
// continue;
|
|
|
// }
|
|
|
// int tmp_idx = get_grid_idx(w, _x, _y);
|
|
|
// Grid* tmp_grid = w->grids[tmp_idx];
|
|
|
|
|
|
// if(out_of_range(w, grid->idx, tmp_idx)){
|
|
|
// add_grid_events_to_watchers(tmp_grid, 'D', id, L);
|
|
|
// }
|
|
|
// else{
|
|
|
// add_grid_events_to_watchers(tmp_grid, 'U', id, L);
|
|
|
// }
|
|
|
// }
|
|
|
Grid *old_grid = w->grids[pre_idx];
|
|
|
left_grid_map = get_nearby_grids(w, old_grid);
|
|
|
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(left_grid_map, &iter))
|
|
|
{
|
|
|
Grid *tmp_grid = (Grid *)(iter.node->value);
|
|
|
if (hashtbl_get(right_grid_map, tmp_grid->idx))
|
|
|
{
|
|
|
add_grid_events_to_watchers(tmp_grid, 'U', id, L);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
add_grid_events_to_watchers(tmp_grid, 'D', id, L);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(right_grid_map, &iter))
|
|
|
{
|
|
|
Grid *tmp_grid = (Grid *)(iter.node->value);
|
|
|
if (pre_idx == -1 || !hashtbl_get(left_grid_map, tmp_grid->idx))
|
|
|
{
|
|
|
add_grid_events_to_watchers(tmp_grid, 'A', id, L);
|
|
|
}
|
|
|
}
|
|
|
if (pre_idx != -1)
|
|
|
{
|
|
|
hashtbl_destroy(left_grid_map);
|
|
|
}
|
|
|
// for (int i = 0; i<9;i++){
|
|
|
// Grid* tmp_grid = grid_list[i];
|
|
|
// if(!tmp_grid){
|
|
|
// continue;
|
|
|
// }
|
|
|
// if(pre_idx!=-1 && !out_of_range(w, pre_idx, tmp_grid->idx)){
|
|
|
// continue;//之前已经get 'U'过了
|
|
|
// }
|
|
|
// add_grid_events_to_watchers(tmp_grid, 'A', id, L);
|
|
|
// }
|
|
|
}
|
|
|
static int grid_add_obj(World *w, Grid *grid, int id, int x, int y, int is_maker, int is_watcher)
|
|
|
{
|
|
|
if (is_maker)
|
|
|
{
|
|
|
if (hashtbl_get(grid->caches, id))
|
|
|
{
|
|
|
//之前可能有D 在里面
|
|
|
Cache *old_cache = (Cache *)hashtbl_get(grid->caches, id);
|
|
|
skynet_free(old_cache);
|
|
|
hashtbl_remove(grid->caches, id);
|
|
|
old_cache = NULL;
|
|
|
//printf("old cache id:%d e:%c x:%d y:%d \n", old_cache->id, old_cache->e, old_cache->x, old_cache->y);
|
|
|
}
|
|
|
Cache *cache = (Cache *)skynet_malloc(sizeof(Cache));
|
|
|
cache->id = id;
|
|
|
cache->x = x;
|
|
|
cache->y = y;
|
|
|
cache->e = 'A';
|
|
|
hashtbl_insert(grid->caches, id, cache);
|
|
|
}
|
|
|
if (is_watcher)
|
|
|
{
|
|
|
Obj *obj = (Obj *)skynet_malloc(sizeof(Obj));
|
|
|
obj->id = id;
|
|
|
obj->x = x;
|
|
|
obj->y = y;
|
|
|
obj->is_maker = is_maker;
|
|
|
obj->is_watcher = is_watcher;
|
|
|
hashtbl_insert(grid->watchers, obj->id, obj);
|
|
|
hashtbl_upsert(w->watcher_grids, grid->idx, NULL);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int grid_del_obj(World *w, Grid *grid, int id)
|
|
|
{
|
|
|
if (hashtbl_get(grid->makers, id))
|
|
|
{ //已经落地了
|
|
|
//旧的cache清除
|
|
|
if (hashtbl_get(grid->caches, id))
|
|
|
{
|
|
|
Cache *old_cache = (Cache *)hashtbl_get(grid->caches, id);
|
|
|
skynet_free(old_cache);
|
|
|
hashtbl_remove(grid->caches, id);
|
|
|
old_cache = NULL;
|
|
|
}
|
|
|
//添加新的
|
|
|
Obj *obj = (Obj *)hashtbl_get(grid->makers, id);
|
|
|
Cache *cache = (Cache *)skynet_malloc(sizeof(Cache));
|
|
|
cache->id = obj->id;
|
|
|
cache->x = obj->x;
|
|
|
cache->y = obj->y;
|
|
|
cache->e = 'D';
|
|
|
hashtbl_insert(grid->caches, obj->id, cache);
|
|
|
}
|
|
|
else if (hashtbl_get(grid->caches, id))
|
|
|
{ //只是存在cache中
|
|
|
//当你从来没有出现过
|
|
|
//printf("grid_del_obj remove_caches %d\n", id);
|
|
|
Cache *cache = (Cache *)hashtbl_get(grid->caches, id);
|
|
|
skynet_free(cache);
|
|
|
hashtbl_remove(grid->caches, id);
|
|
|
cache = NULL;
|
|
|
}
|
|
|
|
|
|
if (hashtbl_get(grid->watchers, id))
|
|
|
{
|
|
|
//printf("grid_del_obj remove_watchers %d\n", id);
|
|
|
Obj *obj = (Obj *)hashtbl_get(grid->watchers, id);
|
|
|
hashtbl_remove(grid->watchers, id);
|
|
|
if (!obj->is_maker)
|
|
|
{
|
|
|
//如果只是watcher的话,释放对象
|
|
|
skynet_free(obj);
|
|
|
obj = NULL;
|
|
|
}
|
|
|
if (grid->watchers->count == 0)
|
|
|
{
|
|
|
hashtbl_remove(w->watcher_grids, grid->idx);
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static void grid_update_obj(Grid *grid, int id)
|
|
|
{
|
|
|
//watcher不需要update
|
|
|
if (hashtbl_get(grid->makers, id) && !hashtbl_get(grid->caches, id))
|
|
|
{
|
|
|
//之前已经在的且没有caches的才需要添加cache
|
|
|
Obj *obj = (Obj *)hashtbl_get(grid->makers, id);
|
|
|
Cache *cache = (Cache *)skynet_malloc(sizeof(Cache));
|
|
|
cache->id = obj->id;
|
|
|
cache->x = obj->x;
|
|
|
cache->y = obj->y;
|
|
|
cache->e = 'U';
|
|
|
hashtbl_insert(grid->caches, obj->id, cache);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void handle_cache(Grid *grid)
|
|
|
{
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(grid->caches, &iter))
|
|
|
{
|
|
|
Cache *cache = (Cache *)(iter.node->value);
|
|
|
iter.node->value = NULL;
|
|
|
if (cache->e == 'A' && !hashtbl_get(grid->makers, cache->id))
|
|
|
{ //之前在makers,D了再A,就会重复,无须处理
|
|
|
//先D了去了其他格子,再回来,就不需要add_makers了
|
|
|
Obj *obj;
|
|
|
if (hashtbl_get(grid->watchers, cache->id))
|
|
|
{
|
|
|
obj = (Obj *)hashtbl_get(grid->watchers, cache->id);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
obj = (Obj *)skynet_malloc(sizeof(Obj));
|
|
|
obj->id = cache->id;
|
|
|
obj->x = cache->x;
|
|
|
obj->y = cache->y;
|
|
|
obj->is_maker = 1;
|
|
|
obj->is_watcher = 0;
|
|
|
}
|
|
|
hashtbl_insert(grid->makers, obj->id, obj);
|
|
|
}
|
|
|
else if (cache->e == 'D')
|
|
|
{
|
|
|
Obj *obj = (Obj *)hashtbl_get(grid->makers, cache->id);
|
|
|
hashtbl_remove(grid->makers, cache->id);
|
|
|
skynet_free(obj);
|
|
|
obj = NULL;
|
|
|
}
|
|
|
skynet_free(cache);
|
|
|
cache = NULL;
|
|
|
}
|
|
|
hashtbl_destroy(grid->caches);
|
|
|
grid->caches = hashtbl_create();
|
|
|
}
|
|
|
|
|
|
static void handle_aoi(World *w, Grid *grid, lua_State *L)
|
|
|
{
|
|
|
|
|
|
HashTable *grid_map = get_nearby_grids(w, grid);
|
|
|
HashTableIter iter2;
|
|
|
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
//Grid** grid_list = get_nearby_grids(w, grid);
|
|
|
while (hashtbl_iter(grid->watchers, &iter))
|
|
|
{
|
|
|
Obj *watcher = (Obj *)(iter.node->value);
|
|
|
int pre_idx = -1;
|
|
|
int id = watcher->id;
|
|
|
//printf("handle_aoi %d %d\n",grid->idx, id);
|
|
|
if (hashtbl_get(w->pre_where_is, id))
|
|
|
{
|
|
|
int *p_idx = (int *)hashtbl_get(w->pre_where_is, id);
|
|
|
pre_idx = *p_idx;
|
|
|
}
|
|
|
if (pre_idx == grid->idx)
|
|
|
{
|
|
|
|
|
|
hashtbl_iter_reset(&iter2);
|
|
|
while (hashtbl_iter(grid_map, &iter2))
|
|
|
{
|
|
|
Grid *tmp_grid = (Grid *)(iter2.node->value);
|
|
|
// if(id==6) {
|
|
|
// printf("tmp_grid %d\n",tmp_grid->idx);
|
|
|
// }
|
|
|
add_grid_events_to_watchers(tmp_grid, 'U', id, L);
|
|
|
}
|
|
|
// for (int i = 0; i<9;i++){
|
|
|
// Grid* tmp_grid = grid_list[i];
|
|
|
// if(!tmp_grid){
|
|
|
// continue;
|
|
|
// }
|
|
|
// add_grid_events_to_watchers(tmp_grid, 'U', id, L);
|
|
|
// }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
resolve_change_watcher(w, grid, grid_map, pre_idx, id, L);
|
|
|
if (hashtbl_get(w->pre_where_is, id))
|
|
|
{
|
|
|
int *p_idx = (int *)hashtbl_get(w->pre_where_is, id);
|
|
|
*p_idx = grid->idx;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
int *p_idx = (int *)skynet_malloc(sizeof(int));
|
|
|
*p_idx = grid->idx;
|
|
|
hashtbl_insert(w->pre_where_is, id, p_idx);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
hashtbl_destroy(grid_map);
|
|
|
}
|
|
|
|
|
|
World *aoi_create_world(int row, int col)
|
|
|
{
|
|
|
//printf("aoi_create_world %d %d\n",row, col);
|
|
|
World *w = (World *)skynet_malloc(sizeof(World));
|
|
|
w->row = row;
|
|
|
w->col = col;
|
|
|
|
|
|
int grid_num = w->row * w->col;
|
|
|
w->grids = (Grid **)skynet_malloc(grid_num * sizeof(Grid *));
|
|
|
for (int i = 0; i < grid_num; i++)
|
|
|
{
|
|
|
Grid *grid = (Grid *)skynet_malloc(sizeof(Grid));
|
|
|
grid->idx = i;
|
|
|
grid->watchers = hashtbl_create();
|
|
|
grid->makers = hashtbl_create();
|
|
|
grid->caches = hashtbl_create();
|
|
|
|
|
|
w->grids[i] = grid;
|
|
|
}
|
|
|
w->where_is = hashtbl_create();
|
|
|
w->pre_where_is = hashtbl_create();
|
|
|
w->watcher_grids = hashtbl_create();
|
|
|
return w;
|
|
|
}
|
|
|
|
|
|
void aoi_get_cost_time(void *l)
|
|
|
{
|
|
|
lua_State *L = (lua_State *)l;
|
|
|
lua_pushnumber(L, cost_time_in_get_event);
|
|
|
lua_pushnumber(L, cost_time_in_lua);
|
|
|
lua_pushnumber(L, cost_time_in_cal);
|
|
|
cost_time_in_get_event = 0.0;
|
|
|
cost_time_in_lua = 0.0;
|
|
|
cost_time_in_cal = 0.0;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
void aoi_update_aoi(World *w, void *l)
|
|
|
{
|
|
|
//clock_t time_begin = clock();
|
|
|
lua_State *L = (lua_State *)l;
|
|
|
//printf("=========start update_aoi=========\n");
|
|
|
int grid_num = w->row * w->col;
|
|
|
//抛出事件
|
|
|
|
|
|
//for(int i=0;i<grid_num;i++){
|
|
|
// Grid* grid = w->grids[i];
|
|
|
// handle_aoi(w, grid, L);
|
|
|
//}
|
|
|
HashTableIter iter;
|
|
|
hashtbl_iter_reset(&iter);
|
|
|
while (hashtbl_iter(w->watcher_grids, &iter))
|
|
|
{
|
|
|
int grid_idx = (iter.node->key);
|
|
|
//printf("handle_aoi grid_idx %d\n", grid_idx);
|
|
|
Grid *grid = w->grids[grid_idx];
|
|
|
handle_aoi(w, grid, L);
|
|
|
}
|
|
|
//clock_t time_end = clock();
|
|
|
//处理cache
|
|
|
//printf("handle_cache\n");
|
|
|
for (int i = 0; i < grid_num; i++)
|
|
|
{
|
|
|
Grid *grid = w->grids[i];
|
|
|
handle_cache(grid);
|
|
|
}
|
|
|
|
|
|
//清空每个格子的events 通过lua_state自己清
|
|
|
//printf("clean all grids events\n");
|
|
|
|
|
|
//printf("=========end update_aoi=========\n");
|
|
|
//clock_t time_end = clock();
|
|
|
//double time_cost = (double)(time_end-time_begin)/CLOCKS_PER_SEC;
|
|
|
//cost_time_in_cal += time_cost;
|
|
|
//printf("===time_cost:%f====\n",cost_time_in_cal);
|
|
|
}
|
|
|
|
|
|
int aoi_add_obj(World *w, int id, int x, int y, int is_maker, int is_watcher)
|
|
|
{
|
|
|
int idx = get_grid_idx(w, x, y); //函数结束会释放idx的,不能hashtbl_insert(&idx)
|
|
|
Grid *grid = w->grids[idx];
|
|
|
|
|
|
if (hashtbl_get(w->where_is, id) || hashtbl_get(grid->caches, id) || hashtbl_get(grid->watchers, id) || hashtbl_get(grid->makers, id))
|
|
|
{
|
|
|
printf("add_obj duplicated %d\n", id);
|
|
|
return 1;
|
|
|
}
|
|
|
if (!is_maker && !is_watcher)
|
|
|
{
|
|
|
printf("add_obj no watcher_and_maker %d\n", id);
|
|
|
return 2;
|
|
|
}
|
|
|
int *p_idx = (int *)skynet_malloc(sizeof(int));
|
|
|
*p_idx = idx; //不同于p_idx=&idx
|
|
|
hashtbl_insert(w->where_is, id, p_idx);
|
|
|
grid_add_obj(w, grid, id, x, y, is_maker, is_watcher);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int aoi_del_obj(World *w, int id)
|
|
|
{
|
|
|
int *p_idx = (int *)hashtbl_get(w->where_is, id);
|
|
|
if (!p_idx)
|
|
|
{
|
|
|
printf("del_obj not_exist %d\n", id);
|
|
|
return 1;
|
|
|
}
|
|
|
Grid *grid = w->grids[*p_idx];
|
|
|
grid_del_obj(w, grid, id);
|
|
|
|
|
|
hashtbl_remove(w->where_is, id);
|
|
|
skynet_free(p_idx);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int aoi_set_obj(World *w, int id, int x, int y)
|
|
|
{
|
|
|
int *p_idx = (int *)hashtbl_get(w->where_is, id);
|
|
|
if (!p_idx)
|
|
|
{
|
|
|
printf("set_obj not_exist %d\n", id);
|
|
|
return 1;
|
|
|
}
|
|
|
int idx = get_grid_idx(w, x, y);
|
|
|
if (idx == *p_idx)
|
|
|
{
|
|
|
Grid *grid = w->grids[idx];
|
|
|
grid_update_obj(grid, id);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Grid *old_grid = w->grids[*p_idx];
|
|
|
Grid *new_grid = w->grids[idx];
|
|
|
int is_maker = 0;
|
|
|
int is_watcher = 0;
|
|
|
if (hashtbl_get(old_grid->makers, id) || hashtbl_get(old_grid->caches, id))
|
|
|
{
|
|
|
is_maker = 1;
|
|
|
}
|
|
|
if (hashtbl_get(old_grid->watchers, id))
|
|
|
{
|
|
|
is_watcher = 1;
|
|
|
}
|
|
|
grid_del_obj(w, old_grid, id);
|
|
|
grid_add_obj(w, new_grid, id, x, y, is_maker, is_watcher);
|
|
|
|
|
|
*p_idx = idx;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
// int main() {
|
|
|
// // World* w = aoi_create_world(3,3);
|
|
|
// // aoi_add_obj(w,7,2,2,1,1);
|
|
|
// // aoi_add_obj(w,1,2,2,1,1);
|
|
|
// // aoi_add_obj(w,6,3,3,1,1);
|
|
|
// // //aoi_update_aoi(w);
|
|
|
// // //aoi_update_aoi(w);
|
|
|
// // aoi_set_obj(w,7,2,3);
|
|
|
// // //aoi_update_aoi(w);
|
|
|
// // aoi_add_obj(w,2,1,1,1,1);
|
|
|
// // aoi_set_obj(w,2,1,2);
|
|
|
// // //aoi_update_aoi(w);
|
|
|
// // //先加再删,等于从来没出现过
|
|
|
// // aoi_add_obj(w,3,2,2,1,1);
|
|
|
// // aoi_del_obj(w,3);
|
|
|
// // //aoi_update_aoi(w);
|
|
|
|
|
|
// // aoi_set_obj(w,2,3,3);
|
|
|
// // aoi_set_obj(w,7,1,1);
|
|
|
// //aoi_update_aoi(w);
|
|
|
// // update_aoi(w);
|
|
|
// // printf("======\n");
|
|
|
// // del_obj(w,7);
|
|
|
// // update_aoi(w);
|
|
|
// // printf("=======\n");
|
|
|
// // int grid_idx = get_grid_idx(w,1,2);
|
|
|
// // int x,y;
|
|
|
// // get_xy_by_grididx(w,grid_idx,&x,&y);
|
|
|
// // printf("x:%d y:%d\n", x, y);
|
|
|
// // add_obj(w,2,5,5,1,1);
|
|
|
// // show_world(w);
|
|
|
// // set_obj(w,1,6,6);
|
|
|
// // show_world(w);
|
|
|
// // del_obj(w,1);
|
|
|
// // show_world(w);
|
|
|
|
|
|
// // World* w = aoi_create_world(3,3);
|
|
|
// // for(int i=1;i<=10000;i++)
|
|
|
// // {
|
|
|
// // aoi_add_obj(w,i,1,1,1,1);
|
|
|
// // }
|
|
|
// // HashTable* aoi_results = hashtbl_create();
|
|
|
// // aoi_update_aoi(w, aoi_results);
|
|
|
// // //打印aoi_results
|
|
|
// // HashTableIter iter;
|
|
|
// // hashtbl_iter_reset(&iter);
|
|
|
// // int i = 0;
|
|
|
// // while(hashtbl_iter(aoi_results, &iter)){
|
|
|
// // Result* re=(Result*)(iter.node->value);
|
|
|
|
|
|
// // printf("watcher:%ld\n", iter.node->key);
|
|
|
// // int watcher_id = (int)iter.node->key;
|
|
|
// // HashTableIter tmp_iter;
|
|
|
// // hashtbl_iter_reset(&tmp_iter);
|
|
|
// // while(hashtbl_iter(re->add_results, &tmp_iter)){
|
|
|
// // Event* e=(Event*)(tmp_iter.node->value);
|
|
|
// // //printf("event:%c,id:%d,x:%d,y:%d\n",e->e,e->id,e->x,e->y);
|
|
|
// // i=i+1;
|
|
|
// // printf("i is %d\n",i);
|
|
|
// // }
|
|
|
// // // hashtbl_iter_reset(&tmp_iter);
|
|
|
// // // while(hashtbl_iter(re->del_results, &tmp_iter)){
|
|
|
// // // Event* e=(Event*)(tmp_iter.node->value);
|
|
|
// // // //printf("event:%c,id:%d,x:%d,y:%d\n",e->e,e->id,e->x,e->y);
|
|
|
// // // }
|
|
|
// // // hashtbl_iter_reset(&tmp_iter);
|
|
|
// // // while(hashtbl_iter(re->update_results, &tmp_iter)){
|
|
|
// // // Event* e=(Event*)(tmp_iter.node->value);
|
|
|
// // // //printf("event:%c,id:%d,x:%d,y:%d\n",e->e,e->id,e->x,e->y);
|
|
|
// // // }
|
|
|
|
|
|
// // hashtbl_destroy(re->add_results);
|
|
|
// // hashtbl_destroy(re->del_results);
|
|
|
// // hashtbl_destroy(re->update_results);
|
|
|
// // }
|
|
|
// // printf("clean aoi_results\n");
|
|
|
// // //todo清空aoi_results
|
|
|
// // hashtbl_destroy(aoi_results);
|
|
|
// return 0;
|
|
|
// }
|