Merge branch 'pr_2'
This commit is contained in:
commit
36916785d6
|
@ -147,6 +147,7 @@
|
|||
<ProjectReference Include="..\..\dep\hidapi\hidapi.vcxproj" />
|
||||
<ProjectReference Include="..\..\dep\main\main.vcxproj" />
|
||||
<ProjectReference Include="..\..\lib\cjson\cjson.vcxproj" />
|
||||
<ProjectReference Include="..\..\lib\gastar\gastar.vcxproj" />
|
||||
<ProjectReference Include="..\..\lib\ghpsocket\ghpsocket.vcxproj" />
|
||||
<ProjectReference Include="..\..\lib\gimgui\gimgui.vcxproj" />
|
||||
<ProjectReference Include="..\..\lib\gsdl2\gsdl2.vcxproj" />
|
||||
|
|
|
@ -34,6 +34,16 @@
|
|||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\Astart.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\lua.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\memorypool.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\lua\lua.vcxproj">
|
||||
<Project>{8481f772-bc91-4032-8682-09809ef70942}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{f50f8b73-4bd2-4b79-b21e-f1aed6dbe6c2}</ProjectGuid>
|
||||
<Keyword>Android</Keyword>
|
||||
|
@ -130,27 +140,51 @@
|
|||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..\..\source\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\Astart.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\lua.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\memorypool.c" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -185,10 +185,12 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\Astart.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\lua.cpp" />
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\memorypool.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\Astart.h" />
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\双向链表.h" />
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\DLinkList.h" />
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\memorypool.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\lua\lua.vcxproj">
|
||||
|
|
|
@ -21,12 +21,18 @@
|
|||
<ClCompile Include="..\..\..\..\source\lib\gastar\lua.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\source\lib\gastar\memorypool.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\Astart.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\双向链表.h">
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\DLinkList.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\..\source\lib\gastar\memorypool.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -15,7 +15,8 @@ LOCAL_C_INCLUDES += $(LUA_PATH)
|
|||
LOCAL_C_INCLUDES += $(LOCAL_PATH)
|
||||
|
||||
LOCAL_SRC_FILES := Astart.cpp \
|
||||
lua.cpp
|
||||
lua.cpp \
|
||||
memorypool.c
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := lua
|
||||
|
||||
|
|
|
@ -1,218 +1,203 @@
|
|||
|
||||
|
||||
#include "Astart.h"
|
||||
#include "双向链表.h"
|
||||
|
||||
|
||||
DWORD 测距(
|
||||
POINT 坐标1,
|
||||
POINT 坐标2)
|
||||
#include "DLinkList.h"
|
||||
#include <string.h>
|
||||
//CalcDistance
|
||||
unsigned int CalcDistance(POINT p1, POINT p2)
|
||||
{
|
||||
DWORD x,y;
|
||||
x = (坐标1.x>坐标2.x) ? 坐标1.x-坐标2.x:坐标2.x-坐标1.x;
|
||||
y = (坐标1.y>坐标2.y) ? 坐标1.y-坐标2.y:坐标2.y-坐标1.y;
|
||||
unsigned int x, y;
|
||||
x = (p1.x > p2.x) ? p1.x - p2.x : p2.x - p1.x;
|
||||
y = (p1.y > p2.y) ? p1.y - p2.y : p2.y - p1.y;
|
||||
|
||||
return (x+y)*10;
|
||||
return (x + y) * 10;
|
||||
}
|
||||
|
||||
地图结构* WINAPI MapCreate(
|
||||
DWORD 宽度,
|
||||
DWORD 高度,
|
||||
BYTE* 点阵数据)
|
||||
Map* WINAPI MapCreate(unsigned int width, unsigned int height, unsigned char* data)
|
||||
{
|
||||
地图结构* 地图 = (地图结构*)分配内存(sizeof(地图结构));
|
||||
if (!地图)
|
||||
Map* map = (Map*)calloc(1, sizeof(Map));
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
地图->宽度 = 宽度;
|
||||
地图->高度 = 高度;
|
||||
地图->数据 = 点阵数据;
|
||||
地图->大小 = 宽度*高度;
|
||||
if (!(地图->节点 = (节点结构*)分配内存(地图->大小*sizeof(节点结构))))
|
||||
map->width = width;
|
||||
map->height = height;
|
||||
map->data = data;
|
||||
map->size = width * height;
|
||||
if (!(map->node = (GRID_NODE*)calloc(map->size, sizeof(GRID_NODE))))
|
||||
{
|
||||
释放内存(地图);
|
||||
地图 = NULL;
|
||||
free(map);
|
||||
map = NULL;
|
||||
}
|
||||
|
||||
return 地图;
|
||||
return map;
|
||||
}
|
||||
|
||||
VOID WINAPI MapDestroy(
|
||||
地图结构* 地图)
|
||||
void WINAPI MapDestroy(Map* map)
|
||||
{
|
||||
释放内存(地图->节点);
|
||||
释放内存(地图);
|
||||
free(map->node);
|
||||
free(map);
|
||||
}
|
||||
地图结构* WINAPI MapCreate2(
|
||||
地图结构* 地图,
|
||||
DWORD 宽度,
|
||||
DWORD 高度,
|
||||
BYTE* 点阵数据)
|
||||
{
|
||||
|
||||
地图->宽度 = 宽度;
|
||||
地图->高度 = 高度;
|
||||
地图->数据 = 点阵数据;
|
||||
地图->大小 = 宽度*高度;
|
||||
if (!(地图->节点 = (节点结构*)分配内存(地图->大小*sizeof(节点结构))))
|
||||
Map* WINAPI MapCreate2(Map* map, unsigned int width, unsigned int height, unsigned char* data)
|
||||
{
|
||||
map->width = width;
|
||||
map->height = height;
|
||||
map->data = data;
|
||||
map->size = width * height;
|
||||
if (!(map->node = (GRID_NODE*)calloc(map->size, sizeof(GRID_NODE))))
|
||||
return NULL;
|
||||
|
||||
return 地图;
|
||||
return map;
|
||||
}
|
||||
|
||||
VOID WINAPI MapDestroy2(
|
||||
地图结构* 地图)
|
||||
void WINAPI MapDestroy2(Map* map)
|
||||
{
|
||||
释放内存(地图->节点);
|
||||
free(map->node);
|
||||
}
|
||||
BOOL WINAPI FindPath(
|
||||
地图结构* 地图数据,
|
||||
POINT* 起点坐标,
|
||||
POINT* 终点坐标,
|
||||
BOOL 搜索模式)
|
||||
|
||||
bool WINAPI FindPath(Map* map, POINT* pStart, POINT* pEnd, bool mode)
|
||||
{
|
||||
/* 终点开始查找 */
|
||||
POINT 起点 = *终点坐标;
|
||||
POINT 终点 = *起点坐标;
|
||||
/* 终点开始查找 */
|
||||
POINT start = *pEnd;
|
||||
POINT end = *pStart;
|
||||
|
||||
BYTE* 点阵数据 = 地图数据->数据;
|
||||
DWORD 地图宽度 = 地图数据->宽度;
|
||||
DWORD 地图高度 = 地图数据->高度;
|
||||
DWORD 地图大小 = 地图数据->大小;
|
||||
双向链表 待检链表(地图大小);
|
||||
unsigned char* data = map->data;
|
||||
unsigned int width = map->width;
|
||||
unsigned int height = map->height;
|
||||
unsigned int size = map->size;
|
||||
|
||||
BOOLEAN 已找到 = FALSE;
|
||||
static int x[] = {-1,-1,0,1,1,1,0,-1};
|
||||
static int y[] = {0,-1,-1,-1,0,1,1,1};
|
||||
DLinkList list(size);
|
||||
|
||||
节点结构* 地图节点 = 地图数据->节点;
|
||||
内存清零(地图节点,地图大小*sizeof(节点结构));
|
||||
bool isOK = false;
|
||||
static int x[] = { -1,-1,0,1,1,1,0,-1 };
|
||||
static int y[] = { 0,-1,-1,-1,0,1,1,1 };
|
||||
|
||||
DWORD 索引 = 地图宽度*起点.y+起点.x;
|
||||
if (索引>=地图大小)
|
||||
return FALSE;
|
||||
地图节点[索引].状态 = 待检;
|
||||
地图节点[索引].距终点 = 测距(起点,终点);
|
||||
地图节点[索引].总距离 = 地图节点[索引].距终点;
|
||||
|
||||
待检链表.插入((LPVOID)索引,地图节点[索引].总距离);
|
||||
|
||||
while (待检链表.取节点数() != 0 && 已找到 == FALSE)
|
||||
GRID_NODE* node = map->node;
|
||||
memset(node, 0, size * sizeof(GRID_NODE));
|
||||
|
||||
unsigned int index = width * start.y + start.x;
|
||||
if (index >= size)
|
||||
return false;
|
||||
|
||||
node[index].start = CHECK;
|
||||
node[index].end = CalcDistance(start, end);
|
||||
node[index].total = node[index].end;
|
||||
|
||||
list.Insert((void*)index, node[index].total);
|
||||
|
||||
while (list.Get_length() != 0 && isOK == false)
|
||||
{
|
||||
/* 在待检链表中取出 F(总距离) 最小的节点, 并将其选为当前点 */
|
||||
待检链表.到尾节点();
|
||||
DWORD 当前索引 = (DWORD)待检链表.取节点值();
|
||||
待检链表.删除();
|
||||
地图节点[当前索引].状态 = 关闭;
|
||||
/* 在待检链表中取出 F(总距离) 最小的节点, 并将其选为当前点 */
|
||||
list.Seek_tail();
|
||||
unsigned int now_index = (unsigned int)(unsigned long long)list.Get_data();
|
||||
list.Delete();
|
||||
node[now_index].state = CLOSE;
|
||||
|
||||
POINT 当前坐标 =
|
||||
POINT cur_pos =
|
||||
{
|
||||
当前索引 % 地图宽度,
|
||||
当前索引 / 地图宽度
|
||||
(long)(now_index % width),
|
||||
(long)(now_index / width)
|
||||
};
|
||||
|
||||
/* 遍历当前坐标的八个相邻坐标 */
|
||||
for (int i=0;i<8;i++)
|
||||
/* 遍历当前坐标的八个相邻坐标 */
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (搜索模式 && i%2)
|
||||
if (mode && i % 2)
|
||||
continue;
|
||||
POINT 相邻坐标 =
|
||||
POINT beside_pos =
|
||||
{
|
||||
当前坐标.x + x[i],
|
||||
当前坐标.y + y[i]
|
||||
cur_pos.x + x[i],
|
||||
cur_pos.y + y[i]
|
||||
};
|
||||
|
||||
/* 检查坐标有效性 */
|
||||
if (相邻坐标.x<0 || (DWORD)相邻坐标.x>=地图宽度
|
||||
|| 相邻坐标.y<0 || (DWORD)相邻坐标.y>=地图高度)
|
||||
/* 检查坐标有效性 */
|
||||
if (beside_pos.x < 0 || (unsigned int)beside_pos.x >= width
|
||||
|| beside_pos.y < 0 || (unsigned int)beside_pos.y >= height)
|
||||
continue;
|
||||
|
||||
DWORD 相邻索引 = 地图宽度*相邻坐标.y+相邻坐标.x;
|
||||
if (点阵数据[相邻索引] != 可通过 ||相邻索引+1>=地图大小||
|
||||
相邻索引+地图宽度>=地图大小||相邻索引-1<0||相邻索引-地图宽度<0)
|
||||
unsigned int beside_index = width * beside_pos.y + beside_pos.x;
|
||||
if (data[beside_index] != OK || beside_index + 1 >= size ||
|
||||
beside_index + width >= size || beside_index - 1 < 0 || beside_index - width < 0)
|
||||
continue;
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
if (点阵数据[相邻索引+1] != 可通过 || 点阵数据[相邻索引+地图宽度] != 可通过)
|
||||
if (data[beside_index + 1] != OK || data[beside_index + width] != OK)
|
||||
continue;
|
||||
case 3:
|
||||
if (点阵数据[相邻索引-1] != 可通过 || 点阵数据[相邻索引+地图宽度] != 可通过)
|
||||
if (data[beside_index - 1] != OK || data[beside_index + width] != OK)
|
||||
continue;
|
||||
case 5:
|
||||
if (点阵数据[相邻索引-1] != 可通过 || 点阵数据[相邻索引-地图宽度] != 可通过)
|
||||
if (data[beside_index - 1] != OK || data[beside_index - width] != OK)
|
||||
continue;
|
||||
case 7:
|
||||
if (点阵数据[相邻索引+1] != 可通过 || 点阵数据[相邻索引-地图宽度] != 可通过)
|
||||
if (data[beside_index + 1] != OK || data[beside_index - width] != OK)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 检查是否已到达终点 */
|
||||
if (相邻坐标.x == 终点.x && 相邻坐标.y == 终点.y)
|
||||
/* 检查是否已到达终点 */
|
||||
if (beside_pos.x == end.x && beside_pos.y == end.y)
|
||||
{
|
||||
已找到 = TRUE;
|
||||
地图节点[相邻索引].父坐标 = 当前坐标;
|
||||
isOK = true;
|
||||
node[beside_index].parent = cur_pos;
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD g = ((i%2) ? 14:10) + abs(点阵数据[当前索引]-点阵数据[相邻索引]);
|
||||
|
||||
|
||||
if (地图节点[相邻索引].状态 == 未知)
|
||||
{
|
||||
/* 放入待检链表中 */
|
||||
地图节点[相邻索引].状态 = 待检;
|
||||
地图节点[相邻索引].距起点 = 地图节点[当前索引].距起点 + g;
|
||||
地图节点[相邻索引].距终点 = 测距(相邻坐标,终点);
|
||||
地图节点[相邻索引].总距离 = 地图节点[相邻索引].距起点 + 地图节点[相邻索引].距终点;
|
||||
地图节点[相邻索引].父坐标 = 当前坐标;
|
||||
|
||||
DWORD 总距离 = 地图节点[相邻索引].总距离;
|
||||
if (待检链表.取节点数() == 0 )
|
||||
待检链表.插入((LPVOID)相邻索引,地图节点[相邻索引].总距离);
|
||||
unsigned int g = ((i % 2) ? 14 : 10) + abs(data[now_index] - data[beside_index]);
|
||||
|
||||
|
||||
if (node[beside_index].state == UNKNOWN)
|
||||
{
|
||||
/* 放入待检链表中 */
|
||||
node[beside_index].state = CHECK;
|
||||
node[beside_index].start = node[now_index].start + g;
|
||||
node[beside_index].end = CalcDistance(beside_pos, end);
|
||||
node[beside_index].total = node[beside_index].start + node[beside_index].end;
|
||||
node[beside_index].parent = cur_pos;
|
||||
|
||||
unsigned int total = node[beside_index].total;
|
||||
if (list.Get_length() == 0)
|
||||
list.Insert((void*)beside_index, node[beside_index].total);
|
||||
else
|
||||
{
|
||||
待检链表.到尾节点();
|
||||
while (TRUE)
|
||||
list.Seek_tail();
|
||||
while (true)
|
||||
{
|
||||
if (待检链表.取键值()>=总距离)
|
||||
if (list.Get_key() >= total)
|
||||
{
|
||||
待检链表.插入((LPVOID)相邻索引,地图节点[相邻索引].总距离);
|
||||
list.Insert((void*)beside_index, node[beside_index].total);
|
||||
break;
|
||||
}
|
||||
if (!待检链表.到父节点())
|
||||
if (!list.Seek_pre())
|
||||
{
|
||||
待检链表.插入((LPVOID)相邻索引,地图节点[相邻索引].总距离,双向链表::向前插入);
|
||||
list.Insert((void*)beside_index, node[beside_index].total, INSERT_PRE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (地图节点[相邻索引].状态 == 待检)
|
||||
else if (node[beside_index].state == CHECK)
|
||||
{
|
||||
/* 如果将当前点设为父 G(距起点) 值是否更小 */
|
||||
if (地图节点[相邻索引].距起点 > 地图节点[当前索引].距起点 + g)
|
||||
/* 如果将当前点设为父 G(距起点) 值是否更小 */
|
||||
if (node[beside_index].start > node[now_index].start + g)
|
||||
{
|
||||
地图节点[相邻索引].父坐标 = 当前坐标;
|
||||
地图节点[相邻索引].距起点 = 地图节点[当前索引].距起点 + g;
|
||||
地图节点[相邻索引].总距离 = 地图节点[相邻索引].距起点 + 地图节点[相邻索引].距终点;
|
||||
node[beside_index].parent = cur_pos;
|
||||
node[beside_index].start = node[now_index].start + g;
|
||||
node[beside_index].total = node[beside_index].start + node[beside_index].end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 已找到;
|
||||
return isOK;
|
||||
}
|
||||
|
||||
BOOL WINAPI NextPath(
|
||||
地图结构* 地图,
|
||||
POINT* 坐标)
|
||||
bool WINAPI NextPath(Map* map, POINT* pos)
|
||||
{
|
||||
DWORD 索引 = 坐标->y*地图->宽度+坐标->x;
|
||||
if (索引>=0 && 索引<地图->大小)
|
||||
unsigned int index = pos->y * map->width + pos->x;
|
||||
if (index >= 0 && index < map->size)
|
||||
{
|
||||
*坐标 = 地图->节点[索引].父坐标;
|
||||
return TRUE;
|
||||
*pos = map->node[index].parent;
|
||||
return true;
|
||||
}
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,48 @@
|
|||
#pragma once
|
||||
#ifndef _ASTART_H
|
||||
#define _ASTART_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
//#define 不可通过 1
|
||||
#define 可通过 0
|
||||
#define 未知 0
|
||||
#define 待检 1
|
||||
#define 关闭 2
|
||||
|
||||
#define 分配内存(字节数) VirtualAlloc(NULL,字节数,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE)
|
||||
#define 释放内存(内存地址) VirtualFree(内存地址,0,MEM_RELEASE)
|
||||
#define 内存清零(内存地址,字节数) SecureZeroMemory(内存地址,字节数)
|
||||
|
||||
|
||||
typedef struct _节点
|
||||
#else
|
||||
#define WINAPI
|
||||
typedef struct tag_POINT
|
||||
{
|
||||
BYTE 状态;
|
||||
DWORD 总距离;
|
||||
DWORD 距起点;
|
||||
DWORD 距终点;
|
||||
POINT 父坐标;
|
||||
}节点结构;
|
||||
long x;
|
||||
long y;
|
||||
}POINT;
|
||||
#endif // _WIN32
|
||||
|
||||
typedef struct _地图
|
||||
enum GRID_ATTR
|
||||
{
|
||||
BYTE* 数据;
|
||||
节点结构* 节点;
|
||||
DWORD 宽度;
|
||||
DWORD 高度;
|
||||
DWORD 大小;
|
||||
}地图结构;
|
||||
OK = 0,
|
||||
UNKNOWN = 0,
|
||||
CHECK,
|
||||
CLOSE
|
||||
};
|
||||
|
||||
地图结构* WINAPI MapCreate(DWORD 宽度,DWORD 高度,BYTE* 点阵数据);
|
||||
VOID WINAPI MapDestroy(地图结构* 地图);
|
||||
地图结构* WINAPI MapCreate2(地图结构* 地图,DWORD 宽度,DWORD 高度,BYTE* 点阵数据);
|
||||
VOID WINAPI MapDestroy2(地图结构* 地图);
|
||||
BOOL WINAPI FindPath(地图结构* 地图数据,POINT* 起点坐标,POINT* 终点坐标,BOOL 搜索模式=0);
|
||||
BOOL WINAPI NextPath(地图结构* 地图,POINT* 坐标);
|
||||
typedef struct tag_GRID_NODE
|
||||
{
|
||||
unsigned char state; //状态
|
||||
unsigned int total; //总距离
|
||||
unsigned int start; //距起点
|
||||
unsigned int end; //距终点
|
||||
POINT parent; //父坐标
|
||||
}GRID_NODE;
|
||||
|
||||
typedef struct _tag_Map
|
||||
{
|
||||
unsigned char* data; //数据
|
||||
GRID_NODE* node; //节点
|
||||
unsigned int width; //宽度
|
||||
unsigned int height; //高度
|
||||
unsigned int size; //大小
|
||||
}Map;
|
||||
|
||||
Map* WINAPI MapCreate(unsigned int width, unsigned int height, unsigned char* data);
|
||||
void WINAPI MapDestroy(Map* map);
|
||||
Map* WINAPI MapCreate2(Map* map, unsigned int width, unsigned int height, unsigned char* data);
|
||||
void WINAPI MapDestroy2(Map* map);
|
||||
bool WINAPI FindPath(Map* map, POINT* start, POINT* end, bool mode = 0);
|
||||
bool WINAPI NextPath(Map* map, POINT* pos);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include "memorypool.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _tag_DLinkListNode* LPDLinkListNode;
|
||||
typedef struct _tag_DLinkListNode
|
||||
{
|
||||
|
@ -27,10 +33,9 @@ enum INSER_TYPE { INSERT_PRE, INSERT_NEXT };
|
|||
class DLinkList
|
||||
{
|
||||
private:
|
||||
void* m_heap;
|
||||
MemoryPool* m_heap;
|
||||
unsigned int m_max;
|
||||
DLinkListNodeHead m_head;
|
||||
LPDLinkListNode m_freeNode;
|
||||
public:
|
||||
DLinkList(unsigned int max);
|
||||
~DLinkList();
|
||||
|
@ -53,47 +58,32 @@ public:
|
|||
// 构造函数
|
||||
DLinkList::DLinkList(unsigned int max)
|
||||
{
|
||||
m_max = max + 1;
|
||||
m_heap = calloc(m_max, sizeof(DLinkListNode));
|
||||
m_max = max;
|
||||
m_heap = MemoryPoolInit(m_max * sizeof(DLinkListNode) * 3, m_max * sizeof(DLinkListNode) * 2);
|
||||
m_head.top = NULL;
|
||||
m_head.tail = NULL;
|
||||
m_head.cur = NULL;
|
||||
m_head.length = 0;
|
||||
|
||||
m_freeNode = (LPDLinkListNode)m_heap;
|
||||
LPDLinkListNode pre = NULL;
|
||||
LPDLinkListNode cur = m_freeNode;
|
||||
for (int i = 1; i < m_max; i++)
|
||||
{
|
||||
cur->pre = pre;
|
||||
cur->next = m_freeNode + i;
|
||||
pre = cur;
|
||||
cur = m_freeNode + i;
|
||||
}
|
||||
}
|
||||
|
||||
// 析构函数
|
||||
DLinkList::~DLinkList()
|
||||
{
|
||||
if (m_heap)
|
||||
free(m_heap);
|
||||
{
|
||||
MemoryPoolClear(m_heap);
|
||||
MemoryPoolDestroy(m_heap);
|
||||
}
|
||||
}
|
||||
|
||||
bool DLinkList::Insert(void* data, unsigned int key, INSER_TYPE type)
|
||||
{
|
||||
if (!m_freeNode->next) {
|
||||
LPDLinkListNode node = (LPDLinkListNode)MemoryPoolAlloc(m_heap, sizeof(DLinkListNode));
|
||||
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LPDLinkListNode node = m_freeNode->next;
|
||||
m_freeNode->next = node->next;
|
||||
node->next->pre = m_freeNode;
|
||||
node->next = NULL;
|
||||
node->pre = NULL;
|
||||
|
||||
m_freeNode = m_freeNode->next;
|
||||
m_freeNode->pre = NULL;
|
||||
|
||||
node->data = data;
|
||||
node->key = key;
|
||||
|
||||
|
@ -105,23 +95,27 @@ bool DLinkList::Insert(void* data, unsigned int key, INSER_TYPE type)
|
|||
node->pre = m_head.cur;
|
||||
node->next = m_head.cur->next;
|
||||
m_head.cur->next = node;
|
||||
if (m_head.cur == m_head.tail) {
|
||||
if (node->next)
|
||||
node->next->pre = node;
|
||||
if (m_head.cur == m_head.tail)
|
||||
m_head.tail = node;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node->pre = m_head.cur->pre;
|
||||
node->next = m_head.cur;
|
||||
m_head.cur->pre = node;
|
||||
if (m_head.cur == m_head.top) {
|
||||
if (node->pre)
|
||||
node->pre->next = node;
|
||||
if (m_head.cur == m_head.top)
|
||||
m_head.top = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 链表是空的
|
||||
node->pre = NULL;
|
||||
node->next = NULL;
|
||||
m_head.top = node;
|
||||
m_head.tail = node;
|
||||
}
|
||||
|
@ -150,9 +144,7 @@ void DLinkList::Delete()
|
|||
{
|
||||
// 将当前节点的父与子链接起来
|
||||
if (cur->pre)
|
||||
{
|
||||
cur->pre->next = cur->next;
|
||||
}
|
||||
|
||||
if (cur->next)
|
||||
{
|
||||
|
@ -171,9 +163,7 @@ void DLinkList::Delete()
|
|||
m_head.tail = cur->pre;
|
||||
}
|
||||
|
||||
cur->next = m_freeNode->next;
|
||||
m_freeNode->next = cur;
|
||||
cur->pre = m_freeNode;
|
||||
MemoryPoolFree(m_heap, cur);
|
||||
}
|
||||
|
||||
void DLinkList::Delete(void* node)
|
||||
|
@ -189,17 +179,7 @@ void DLinkList::Clean()
|
|||
m_head.tail = NULL;
|
||||
m_head.cur = NULL;
|
||||
m_head.length = 0;
|
||||
|
||||
m_freeNode = (LPDLinkListNode)m_heap;
|
||||
LPDLinkListNode pre = NULL;
|
||||
LPDLinkListNode cur = m_freeNode;
|
||||
for (int i = 1; i < m_max; i++)
|
||||
{
|
||||
cur->pre = pre;
|
||||
cur->next = m_freeNode + i;
|
||||
pre = cur;
|
||||
cur = m_freeNode + i;
|
||||
}
|
||||
MemoryPoolClear(m_heap);
|
||||
}
|
||||
|
||||
void DLinkList::Seek(void* node)
|
||||
|
|
|
@ -1,128 +1,137 @@
|
|||
#include "lua.hpp"
|
||||
#include "lua.hpp"
|
||||
#include "Astart.h"
|
||||
#include <string.h>
|
||||
|
||||
static int astar_CheckPoint(lua_State *L)
|
||||
static int astar_CheckPoint(lua_State* L)
|
||||
{
|
||||
地图结构 *map = (地图结构*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L,2);
|
||||
int y = luaL_checkinteger(L,3);
|
||||
Map* map = (Map*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L, 2);
|
||||
int y = luaL_checkinteger(L, 3);
|
||||
|
||||
if (map->数据 && x>=0 && x<map->宽度 && y>=0 && y<map->高度){
|
||||
int n = y*map->宽度+x;
|
||||
lua_pushboolean(L,map->数据[n]==0);
|
||||
}else
|
||||
lua_pushboolean(L,0);
|
||||
if (map->data && x >= 0 && x < map->width && y >= 0 && y < map->height) {
|
||||
int n = y * map->width + x;
|
||||
lua_pushboolean(L, map->data[n] == 0);
|
||||
}
|
||||
else
|
||||
lua_pushboolean(L, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int astar_GetPoint(lua_State *L)
|
||||
static int astar_GetPoint(lua_State* L)
|
||||
{
|
||||
地图结构 *map = (地图结构*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L,2);
|
||||
int y = luaL_checkinteger(L,3);
|
||||
Map* map = (Map*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L, 2);
|
||||
int y = luaL_checkinteger(L, 3);
|
||||
|
||||
if (map->数据 && x>=0 && x<map->宽度 && y>=0 && y<map->高度){
|
||||
int n = y*map->宽度+x;
|
||||
lua_pushinteger(L,map->数据[n]);
|
||||
}else
|
||||
lua_pushinteger(L,-1);
|
||||
if (map->data && x >= 0 && x < map->width && y >= 0 && y < map->height) {
|
||||
int n = y * map->width + x;
|
||||
lua_pushinteger(L, map->data[n]);
|
||||
}
|
||||
else
|
||||
lua_pushinteger(L, -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int astar_SetPoint(lua_State *L)
|
||||
static int astar_SetPoint(lua_State* L)
|
||||
{
|
||||
地图结构 *map = (地图结构*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L,2);
|
||||
int y = luaL_checkinteger(L,3);
|
||||
int v = luaL_checkinteger(L,4);
|
||||
Map* map = (Map*)luaL_checkudata(L, 1, "gge_astar");
|
||||
int x = luaL_checkinteger(L, 2);
|
||||
int y = luaL_checkinteger(L, 3);
|
||||
int v = luaL_checkinteger(L, 4);
|
||||
|
||||
if (map->数据 && x>=0 && x<map->宽度 && y>=0 && y<map->高度)
|
||||
if (map->data && x >= 0 && x < map->width && y >= 0 && y < map->height)
|
||||
{
|
||||
int n = y*map->宽度+x;
|
||||
map->数据[n] = v;
|
||||
int n = y * map->width + x;
|
||||
map->data[n] = v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int astar_GetPath(lua_State *L)
|
||||
static int astar_GetPath(lua_State* L)
|
||||
{
|
||||
地图结构 *map = (地图结构*)luaL_checkudata(L, 1, "gge_astar");
|
||||
POINT nodeStart,nodeEnd,nodeCur;
|
||||
Map* map = (Map*)luaL_checkudata(L, 1, "gge_astar");
|
||||
POINT nodeStart, nodeEnd, nodeCur;
|
||||
nodeStart.x = luaL_checkinteger(L, 2);
|
||||
nodeStart.y = luaL_checkinteger(L, 3);
|
||||
nodeEnd.x = luaL_checkinteger(L, 4);
|
||||
nodeEnd.y = luaL_checkinteger(L, 5);
|
||||
BOOL mode = luaL_optinteger(L,6,0);
|
||||
nodeEnd.x = luaL_checkinteger(L, 4);
|
||||
nodeEnd.y = luaL_checkinteger(L, 5);
|
||||
bool mode = luaL_optinteger(L, 6, 0);
|
||||
nodeCur = nodeStart;
|
||||
|
||||
lua_newtable(L);
|
||||
if (nodeEnd.x<0 || nodeEnd.x>=map->宽度 || nodeEnd.y<0 || nodeEnd.y>=map->高度)
|
||||
if (nodeEnd.x < 0 || nodeEnd.x >= map->width || nodeEnd.y < 0 || nodeEnd.y >= map->height)
|
||||
return 1;
|
||||
if (FindPath(map, &nodeStart, &nodeEnd,mode))
|
||||
if (FindPath(map, &nodeStart, &nodeEnd, mode))
|
||||
{
|
||||
int i = 1;
|
||||
for( ;; )
|
||||
for (;; )
|
||||
{
|
||||
if (NextPath(map,&nodeCur))
|
||||
if (NextPath(map, &nodeCur))
|
||||
{
|
||||
lua_newtable(L);
|
||||
lua_pushinteger(L, nodeCur.x);
|
||||
lua_setfield(L,-2,"x");
|
||||
lua_setfield(L, -2, "x");
|
||||
lua_pushinteger(L, nodeCur.y);
|
||||
lua_setfield(L,-2,"y");
|
||||
lua_setfield(L, -2, "y");
|
||||
lua_rawseti(L, -2, i++);
|
||||
if( nodeCur.x==nodeEnd.x && nodeCur.y==nodeEnd.y ) break;
|
||||
}else
|
||||
if (nodeCur.x == nodeEnd.x && nodeCur.y == nodeEnd.y) break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int astar_new(lua_State *L)
|
||||
static int astar_new(lua_State* L)
|
||||
{
|
||||
int w,h;
|
||||
int w, h;
|
||||
char* data;
|
||||
size_t len;
|
||||
w = luaL_checkinteger(L, 1);
|
||||
h = luaL_checkinteger(L, 2);
|
||||
地图结构* map = (地图结构*)lua_newuserdata(L,sizeof(地图结构));
|
||||
MapCreate2(map,w,h,NULL);
|
||||
map->数据 = new BYTE[map->大小];
|
||||
memset(map->数据,0,map->大小);
|
||||
if (lua_isnumber(L,3) && lua_isnumber(L,4)){
|
||||
Map* map = (Map*)lua_newuserdata(L, sizeof(Map));
|
||||
MapCreate2(map, w, h, NULL);
|
||||
map->data = new unsigned char[map->size];
|
||||
memset(map->data, 0, map->size);
|
||||
if (lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
|
||||
data = (char*)luaL_checkinteger(L, 3);
|
||||
len = luaL_checkinteger(L, 4);
|
||||
if (len<=map->大小){
|
||||
memcpy(map->数据,data,len);
|
||||
}else
|
||||
luaL_error(L,"data error");
|
||||
}else if (lua_isstring(L,3)){
|
||||
data = (char*)luaL_checklstring(L,3,&len);
|
||||
if(len==map->大小)
|
||||
memcpy(map->数据,data,len);
|
||||
len = luaL_checkinteger(L, 4);
|
||||
if (len <= map->size) {
|
||||
memcpy(map->data, data, len);
|
||||
}
|
||||
else
|
||||
luaL_error(L, "data error");
|
||||
}
|
||||
else if (lua_isstring(L, 3)) {
|
||||
data = (char*)luaL_checklstring(L, 3, &len);
|
||||
if (len == map->size)
|
||||
//for (int i = 0; i < len; i++) {
|
||||
// map->data[i] = (unsigned char)(data[i] - '0');
|
||||
//}
|
||||
memcpy(map->data, data, len);
|
||||
}
|
||||
luaL_getmetatable(L, "gge_astar");
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int astar_gc(lua_State *L)
|
||||
static int astar_gc(lua_State* L)
|
||||
{
|
||||
地图结构 *map = (地图结构*)luaL_checkudata(L, 1, "gge_astar");
|
||||
if (map->数据)
|
||||
Map* map = (Map*)luaL_checkudata(L, 1, "gge_astar");
|
||||
if (map->data)
|
||||
{
|
||||
delete []map->数据;
|
||||
delete[]map->data;
|
||||
MapDestroy2(map);
|
||||
map->数据 = NULL;
|
||||
map->data = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
extern "C"
|
||||
LUALIB_API int luaopen_gastar(lua_State* L)
|
||||
LUALIB_API int luaopen_gastar(lua_State * L)
|
||||
{
|
||||
luaL_Reg methods[] = {
|
||||
{"__gc", astar_gc},
|
||||
|
@ -133,12 +142,11 @@ LUALIB_API int luaopen_gastar(lua_State* L)
|
|||
{NULL, NULL},
|
||||
};
|
||||
luaL_newmetatable(L, "gge_astar");
|
||||
luaL_setfuncs(L,methods,0);
|
||||
lua_pushvalue(L,-1);
|
||||
luaL_setfuncs(L, methods, 0);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L,1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushcfunction(L,astar_new);
|
||||
lua_pushcfunction(L, astar_new);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,378 @@
|
|||
#include "memorypool.h"
|
||||
|
||||
#define MP_CHUNKHEADER sizeof(struct _mp_chunk)
|
||||
#define MP_CHUNKEND sizeof(struct _mp_chunk*)
|
||||
|
||||
#define MP_LOCK(lockobj) \
|
||||
do { \
|
||||
pthread_mutex_lock(&lockobj->lock); \
|
||||
} while (0)
|
||||
#define MP_UNLOCK(lockobj) \
|
||||
do { \
|
||||
pthread_mutex_unlock(&lockobj->lock); \
|
||||
} while (0)
|
||||
|
||||
#define MP_ALIGN_SIZE(_n) (_n + sizeof(long) - ((sizeof(long) - 1) & _n))
|
||||
|
||||
#define MP_INIT_MEMORY_STRUCT(mm, mem_sz) \
|
||||
do { \
|
||||
mm->mem_pool_size = mem_sz; \
|
||||
mm->alloc_mem = 0; \
|
||||
mm->alloc_prog_mem = 0; \
|
||||
mm->free_list = (_MP_Chunk*) mm->start; \
|
||||
mm->free_list->is_free = 1; \
|
||||
mm->free_list->alloc_mem = mem_sz; \
|
||||
mm->free_list->prev = NULL; \
|
||||
mm->free_list->next = NULL; \
|
||||
mm->alloc_list = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define MP_DLINKLIST_INS_FRT(head, x) \
|
||||
do { \
|
||||
x->prev = NULL; \
|
||||
x->next = head; \
|
||||
if (head) head->prev = x; \
|
||||
head = x; \
|
||||
} while (0)
|
||||
|
||||
#define MP_DLINKLIST_DEL(head, x) \
|
||||
do { \
|
||||
if (!x->prev) { \
|
||||
head = x->next; \
|
||||
if (x->next) x->next->prev = NULL; \
|
||||
} else { \
|
||||
x->prev->next = x->next; \
|
||||
if (x->next) x->next->prev = x->prev; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void get_memory_list_count(MemoryPool* mp, mem_size_t* mlist_len) {
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
mem_size_t mlist_l = 0;
|
||||
_MP_Memory* mm = mp->mlist;
|
||||
while (mm) {
|
||||
mlist_l++;
|
||||
mm = mm->next;
|
||||
}
|
||||
*mlist_len = mlist_l;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void get_memory_info(MemoryPool* mp,
|
||||
_MP_Memory* mm,
|
||||
mem_size_t* free_list_len,
|
||||
mem_size_t* alloc_list_len) {
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
mem_size_t free_l = 0, alloc_l = 0;
|
||||
_MP_Chunk* p = mm->free_list;
|
||||
while (p) {
|
||||
free_l++;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
p = mm->alloc_list;
|
||||
while (p) {
|
||||
alloc_l++;
|
||||
p = p->next;
|
||||
}
|
||||
*free_list_len = free_l;
|
||||
*alloc_list_len = alloc_l;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
}
|
||||
|
||||
int get_memory_id(_MP_Memory* mm) {
|
||||
return mm->id;
|
||||
}
|
||||
|
||||
static _MP_Memory* extend_memory_list(MemoryPool* mp, mem_size_t new_mem_sz) {
|
||||
char* s = (char*) malloc(sizeof(_MP_Memory) + new_mem_sz * sizeof(char));
|
||||
if (!s) return NULL;
|
||||
|
||||
_MP_Memory* mm = (_MP_Memory*) s;
|
||||
mm->start = s + sizeof(_MP_Memory);
|
||||
|
||||
MP_INIT_MEMORY_STRUCT(mm, new_mem_sz);
|
||||
mm->id = mp->last_id++;
|
||||
mm->next = mp->mlist;
|
||||
mp->mlist = mm;
|
||||
return mm;
|
||||
}
|
||||
|
||||
static _MP_Memory* find_memory_list(MemoryPool* mp, void* p) {
|
||||
_MP_Memory* tmp = mp->mlist;
|
||||
while (tmp) {
|
||||
if (tmp->start <= (char*) p &&
|
||||
tmp->start + mp->mem_pool_size > (char*) p)
|
||||
break;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int merge_free_chunk(MemoryPool* mp, _MP_Memory* mm, _MP_Chunk* c) {
|
||||
_MP_Chunk *p0 = c, *p1 = c;
|
||||
while (p0->is_free) {
|
||||
p1 = p0;
|
||||
if ((char*) p0 - MP_CHUNKEND - MP_CHUNKHEADER <= mm->start) break;
|
||||
p0 = *(_MP_Chunk**) ((char*) p0 - MP_CHUNKEND);
|
||||
}
|
||||
|
||||
p0 = (_MP_Chunk*) ((char*) p1 + p1->alloc_mem);
|
||||
while ((char*) p0 < mm->start + mp->mem_pool_size && p0->is_free) {
|
||||
MP_DLINKLIST_DEL(mm->free_list, p0);
|
||||
p1->alloc_mem += p0->alloc_mem;
|
||||
p0 = (_MP_Chunk*) ((char*) p0 + p0->alloc_mem);
|
||||
}
|
||||
|
||||
*(_MP_Chunk**) ((char*) p1 + p1->alloc_mem - MP_CHUNKEND) = p1;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
MemoryPool* MemoryPoolInit(mem_size_t maxmempoolsize, mem_size_t mempoolsize) {
|
||||
if (mempoolsize > maxmempoolsize) {
|
||||
// printf("[MemoryPool_Init] MemPool Init ERROR! Mempoolsize is too big!
|
||||
// \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MemoryPool* mp = (MemoryPool*) malloc(sizeof(MemoryPool));
|
||||
if (!mp) return NULL;
|
||||
|
||||
mp->last_id = 0;
|
||||
if (mempoolsize < maxmempoolsize) mp->auto_extend = 1;
|
||||
mp->max_mem_pool_size = maxmempoolsize;
|
||||
mp->total_mem_pool_size = mp->mem_pool_size = mempoolsize;
|
||||
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
pthread_mutex_init(&mp->lock, NULL);
|
||||
#endif
|
||||
|
||||
char* s = (char*) malloc(sizeof(_MP_Memory) +
|
||||
sizeof(char) * mp->mem_pool_size);
|
||||
if (!s) return NULL;
|
||||
|
||||
mp->mlist = (_MP_Memory*) s;
|
||||
mp->mlist->start = s + sizeof(_MP_Memory);
|
||||
MP_INIT_MEMORY_STRUCT(mp->mlist, mp->mem_pool_size);
|
||||
mp->mlist->next = NULL;
|
||||
mp->mlist->id = mp->last_id++;
|
||||
|
||||
return mp;
|
||||
}
|
||||
|
||||
void* MemoryPoolAlloc(MemoryPool* mp, mem_size_t wantsize) {
|
||||
if (wantsize <= 0) return NULL;
|
||||
mem_size_t total_needed_size =
|
||||
MP_ALIGN_SIZE(wantsize + MP_CHUNKHEADER + MP_CHUNKEND);
|
||||
if (total_needed_size > mp->mem_pool_size) return NULL;
|
||||
|
||||
_MP_Memory *mm = NULL, *mm1 = NULL;
|
||||
_MP_Chunk *_free = NULL, *_not_free = NULL;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
FIND_FREE_CHUNK:
|
||||
mm = mp->mlist;
|
||||
while (mm) {
|
||||
if (mp->mem_pool_size - mm->alloc_mem < total_needed_size) {
|
||||
mm = mm->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
_free = mm->free_list;
|
||||
_not_free = NULL;
|
||||
|
||||
while (_free) {
|
||||
if (_free->alloc_mem >= total_needed_size) {
|
||||
// 如果free块分割后剩余内存足够大 则进行分割
|
||||
if (_free->alloc_mem - total_needed_size >
|
||||
MP_CHUNKHEADER + MP_CHUNKEND) {
|
||||
// 从free块头开始分割出alloc块
|
||||
_not_free = _free;
|
||||
|
||||
_free = (_MP_Chunk*) ((char*) _not_free +
|
||||
total_needed_size);
|
||||
*_free = *_not_free;
|
||||
_free->alloc_mem -= total_needed_size;
|
||||
*(_MP_Chunk**) ((char*) _free + _free->alloc_mem -
|
||||
MP_CHUNKEND) = _free;
|
||||
|
||||
// update free_list
|
||||
if (!_free->prev) {
|
||||
mm->free_list = _free;
|
||||
} else {
|
||||
_free->prev->next = _free;
|
||||
}
|
||||
if (_free->next) _free->next->prev = _free;
|
||||
|
||||
_not_free->is_free = 0;
|
||||
_not_free->alloc_mem = total_needed_size;
|
||||
|
||||
*(_MP_Chunk**) ((char*) _not_free + total_needed_size -
|
||||
MP_CHUNKEND) = _not_free;
|
||||
}
|
||||
// 不够 则整块分配为alloc
|
||||
else {
|
||||
_not_free = _free;
|
||||
MP_DLINKLIST_DEL(mm->free_list, _not_free);
|
||||
_not_free->is_free = 0;
|
||||
}
|
||||
MP_DLINKLIST_INS_FRT(mm->alloc_list, _not_free);
|
||||
|
||||
mm->alloc_mem += _not_free->alloc_mem;
|
||||
mm->alloc_prog_mem +=
|
||||
(_not_free->alloc_mem - MP_CHUNKHEADER - MP_CHUNKEND);
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return (void*) ((char*) _not_free + MP_CHUNKHEADER);
|
||||
}
|
||||
_free = _free->next;
|
||||
}
|
||||
|
||||
mm = mm->next;
|
||||
}
|
||||
|
||||
if (mp->auto_extend) {
|
||||
// 超过总内存限制
|
||||
if (mp->total_mem_pool_size >= mp->max_mem_pool_size) {
|
||||
goto err_out;
|
||||
}
|
||||
mem_size_t add_mem_sz = mp->max_mem_pool_size - mp->mem_pool_size;
|
||||
add_mem_sz = add_mem_sz >= mp->mem_pool_size ? mp->mem_pool_size
|
||||
: add_mem_sz;
|
||||
mm1 = extend_memory_list(mp, add_mem_sz);
|
||||
if (!mm1) {
|
||||
goto err_out;
|
||||
}
|
||||
mp->total_mem_pool_size += add_mem_sz;
|
||||
|
||||
goto FIND_FREE_CHUNK;
|
||||
}
|
||||
|
||||
err_out:
|
||||
// printf("[MemoryPool_Alloc] No enough memory! \n");
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int MemoryPoolFree(MemoryPool* mp, void* p) {
|
||||
if (p == NULL || mp == NULL) return 1;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
_MP_Memory* mm = mp->mlist;
|
||||
if (mp->auto_extend) mm = find_memory_list(mp, p);
|
||||
|
||||
_MP_Chunk* ck = (_MP_Chunk*) ((char*) p - MP_CHUNKHEADER);
|
||||
|
||||
MP_DLINKLIST_DEL(mm->alloc_list, ck);
|
||||
MP_DLINKLIST_INS_FRT(mm->free_list, ck);
|
||||
ck->is_free = 1;
|
||||
|
||||
mm->alloc_mem -= ck->alloc_mem;
|
||||
mm->alloc_prog_mem -= (ck->alloc_mem - MP_CHUNKHEADER - MP_CHUNKEND);
|
||||
|
||||
return merge_free_chunk(mp, mm, ck);
|
||||
}
|
||||
|
||||
MemoryPool* MemoryPoolClear(MemoryPool* mp) {
|
||||
if (!mp) return NULL;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
_MP_Memory* mm = mp->mlist;
|
||||
while (mm) {
|
||||
MP_INIT_MEMORY_STRUCT(mm, mm->mem_pool_size);
|
||||
mm = mm->next;
|
||||
}
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return mp;
|
||||
}
|
||||
|
||||
int MemoryPoolDestroy(MemoryPool* mp) {
|
||||
if (mp == NULL) return 1;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
_MP_Memory *mm = mp->mlist, *mm1 = NULL;
|
||||
while (mm) {
|
||||
mm1 = mm;
|
||||
mm = mm->next;
|
||||
free(mm1);
|
||||
}
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
pthread_mutex_destroy(&mp->lock);
|
||||
#endif
|
||||
free(mp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem_size_t GetTotalMemory(MemoryPool* mp) {
|
||||
return mp->total_mem_pool_size;
|
||||
}
|
||||
|
||||
mem_size_t GetUsedMemory(MemoryPool* mp) {
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
mem_size_t total_alloc = 0;
|
||||
_MP_Memory* mm = mp->mlist;
|
||||
while (mm) {
|
||||
total_alloc += mm->alloc_mem;
|
||||
mm = mm->next;
|
||||
}
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return total_alloc;
|
||||
}
|
||||
|
||||
mem_size_t GetProgMemory(MemoryPool* mp) {
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_LOCK(mp);
|
||||
#endif
|
||||
mem_size_t total_alloc_prog = 0;
|
||||
_MP_Memory* mm = mp->mlist;
|
||||
while (mm) {
|
||||
total_alloc_prog += mm->alloc_prog_mem;
|
||||
mm = mm->next;
|
||||
}
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
MP_UNLOCK(mp);
|
||||
#endif
|
||||
return total_alloc_prog;
|
||||
}
|
||||
|
||||
float MemoryPoolGetUsage(MemoryPool* mp) {
|
||||
return (float) GetUsedMemory(mp) / GetTotalMemory(mp);
|
||||
}
|
||||
|
||||
float MemoryPoolGetProgUsage(MemoryPool* mp) {
|
||||
return (float) GetProgMemory(mp) / GetTotalMemory(mp);
|
||||
}
|
||||
|
||||
#undef MP_CHUNKHEADER
|
||||
#undef MP_CHUNKEND
|
||||
#undef MP_LOCK
|
||||
#undef MP_ALIGN_SIZE
|
||||
#undef MP_INIT_MEMORY_STRUCT
|
||||
#undef MP_DLINKLIST_INS_FRT
|
||||
#undef MP_DLINKLIST_DEL
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef _Z_MEMORYPOOL_H_
|
||||
#define _Z_MEMORYPOOL_H_
|
||||
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define mem_size_t unsigned long long
|
||||
#define KB (mem_size_t)(1 << 10)
|
||||
#define MB (mem_size_t)(1 << 20)
|
||||
#define GB (mem_size_t)(1 << 30)
|
||||
|
||||
typedef struct _mp_chunk {
|
||||
mem_size_t alloc_mem;
|
||||
struct _mp_chunk *prev, *next;
|
||||
int is_free;
|
||||
} _MP_Chunk;
|
||||
|
||||
typedef struct _mp_mem_pool_list {
|
||||
char* start;
|
||||
unsigned int id;
|
||||
mem_size_t mem_pool_size;
|
||||
mem_size_t alloc_mem;
|
||||
mem_size_t alloc_prog_mem;
|
||||
_MP_Chunk *free_list, *alloc_list;
|
||||
struct _mp_mem_pool_list* next;
|
||||
} _MP_Memory;
|
||||
|
||||
typedef struct _mp_mem_pool {
|
||||
unsigned int last_id;
|
||||
int auto_extend;
|
||||
mem_size_t mem_pool_size, total_mem_pool_size, max_mem_pool_size;
|
||||
struct _mp_mem_pool_list* mlist;
|
||||
#ifdef _Z_MEMORYPOOL_THREAD_
|
||||
pthread_mutex_t lock;
|
||||
#endif
|
||||
} MemoryPool;
|
||||
|
||||
/*
|
||||
* 内部工具函数(调试用)
|
||||
*/
|
||||
|
||||
// 所有Memory的数量
|
||||
void get_memory_list_count(MemoryPool* mp, mem_size_t* mlist_len);
|
||||
// 每个Memory的统计信息
|
||||
void get_memory_info(MemoryPool* mp,
|
||||
_MP_Memory* mm,
|
||||
mem_size_t* free_list_len,
|
||||
mem_size_t* alloc_list_len);
|
||||
int get_memory_id(_MP_Memory* mm);
|
||||
|
||||
/*
|
||||
* 内存池API
|
||||
*/
|
||||
|
||||
MemoryPool* MemoryPoolInit(mem_size_t maxmempoolsize, mem_size_t mempoolsize);
|
||||
void* MemoryPoolAlloc(MemoryPool* mp, mem_size_t wantsize);
|
||||
int MemoryPoolFree(MemoryPool* mp, void* p);
|
||||
MemoryPool* MemoryPoolClear(MemoryPool* mp);
|
||||
int MemoryPoolDestroy(MemoryPool* mp);
|
||||
int MemoryPoolSetThreadSafe(MemoryPool* mp, int thread_safe);
|
||||
|
||||
/*
|
||||
* 内存池信息API
|
||||
*/
|
||||
|
||||
// 总空间
|
||||
mem_size_t GetTotalMemory(MemoryPool* mp);
|
||||
// 实际分配空间
|
||||
mem_size_t GetUsedMemory(MemoryPool* mp);
|
||||
float MemoryPoolGetUsage(MemoryPool* mp);
|
||||
// 数据占用空间
|
||||
mem_size_t GetProgMemory(MemoryPool* mp);
|
||||
float MemoryPoolGetProgUsage(MemoryPool* mp);
|
||||
|
||||
#endif // !_Z_MEMORYPOOL_H_
|
|
@ -1,232 +0,0 @@
|
|||
#pragma once
|
||||
#include <Windows.h>
|
||||
|
||||
typedef struct _双向链表_节点 *双向链表_节点指针;
|
||||
typedef struct _双向链表_节点
|
||||
{
|
||||
双向链表_节点指针 父节点;
|
||||
双向链表_节点指针 子节点;
|
||||
LPVOID 节点值;
|
||||
DWORD 键值;
|
||||
}双向链表_节点;
|
||||
|
||||
typedef struct _双向链表_表头
|
||||
{
|
||||
HANDLE 堆句柄;
|
||||
DWORD 堆大小;
|
||||
双向链表_节点指针 首节点;
|
||||
双向链表_节点指针 尾节点;
|
||||
双向链表_节点指针 当前节点;
|
||||
DWORD 节点数;
|
||||
|
||||
}双向链表_表头;
|
||||
|
||||
|
||||
|
||||
class 双向链表
|
||||
{
|
||||
private:
|
||||
双向链表_表头 表头;
|
||||
|
||||
public:
|
||||
双向链表(DWORD 最大节点数);
|
||||
~双向链表();
|
||||
|
||||
enum 插入方向{向前插入,向后插入};
|
||||
BOOL 插入(LPVOID 节点值,DWORD 键值,插入方向 方向);
|
||||
VOID 删除();
|
||||
VOID 删除(LPVOID 节点地址);
|
||||
VOID 清空();
|
||||
VOID 到某节点(LPVOID 节点地址);
|
||||
BOOL 到父节点();
|
||||
BOOL 到子节点();
|
||||
VOID 到首节点();
|
||||
VOID 到尾节点();
|
||||
LPVOID 取节点值();
|
||||
DWORD 取键值();
|
||||
LPVOID 取节点地址();
|
||||
DWORD 取节点数();
|
||||
};
|
||||
|
||||
// 构造函数
|
||||
双向链表::双向链表(DWORD 最大节点数 = 0)
|
||||
{
|
||||
表头.堆大小 = 最大节点数*sizeof(双向链表_节点);
|
||||
表头.堆句柄 = HeapCreate(HEAP_GENERATE_EXCEPTIONS,表头.堆大小,表头.堆大小);
|
||||
表头.首节点 = NULL;
|
||||
表头.尾节点 = NULL;
|
||||
表头.当前节点 = NULL;
|
||||
表头.节点数 = 0;
|
||||
}
|
||||
|
||||
// 析构函数
|
||||
双向链表::~双向链表()
|
||||
{
|
||||
if (表头.堆句柄)
|
||||
HeapDestroy(表头.堆句柄);
|
||||
}
|
||||
|
||||
BOOL 双向链表::插入(LPVOID 节点值,DWORD 键值 = 0,插入方向 方向 = 向后插入)
|
||||
{
|
||||
双向链表_节点指针 节点 = (双向链表_节点指针)HeapAlloc(表头.堆句柄,0,sizeof(双向链表_节点));
|
||||
if (!节点)
|
||||
return FALSE;
|
||||
|
||||
节点->节点值 = 节点值;
|
||||
节点->键值 = 键值;
|
||||
|
||||
// 将当前节点的父与子链接起来
|
||||
if (表头.当前节点)
|
||||
{
|
||||
if (方向 == 向后插入)
|
||||
{
|
||||
节点->父节点 = 表头.当前节点;
|
||||
节点->子节点 = 表头.当前节点->子节点;
|
||||
表头.当前节点->子节点 = 节点;
|
||||
if (节点->子节点)
|
||||
节点->子节点->父节点 = 节点;
|
||||
if (表头.当前节点 == 表头.尾节点)
|
||||
表头.尾节点 = 节点;
|
||||
}
|
||||
else
|
||||
{
|
||||
节点->父节点 = 表头.当前节点->父节点;
|
||||
节点->子节点 = 表头.当前节点;
|
||||
表头.当前节点->父节点 = 节点;
|
||||
if (节点->父节点)
|
||||
节点->父节点->子节点 = 节点;
|
||||
if (表头.当前节点 == 表头.首节点)
|
||||
表头.首节点 = 节点;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 链表是空的
|
||||
节点->父节点 = NULL;
|
||||
节点->子节点 = NULL;
|
||||
|
||||
表头.首节点 = 节点;
|
||||
表头.尾节点 = 节点;
|
||||
}
|
||||
|
||||
表头.当前节点 = 节点;
|
||||
|
||||
表头.节点数++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID 双向链表::删除()
|
||||
{
|
||||
if (!表头.当前节点)
|
||||
return;
|
||||
|
||||
双向链表_节点指针 当前 = 表头.当前节点;
|
||||
|
||||
if (--表头.节点数 == 0)
|
||||
{
|
||||
表头.首节点 = NULL;
|
||||
表头.尾节点 = NULL;
|
||||
表头.当前节点 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 将当前节点的父与子链接起来
|
||||
if (当前->父节点)
|
||||
当前->父节点->子节点 = 当前->子节点;
|
||||
|
||||
if (当前->子节点)
|
||||
{
|
||||
当前->子节点->父节点 = 当前->父节点;
|
||||
|
||||
// 更新表头
|
||||
表头.当前节点 = 当前->子节点;
|
||||
}
|
||||
else
|
||||
表头.当前节点 = 当前->父节点;
|
||||
|
||||
|
||||
if (当前 == 表头.首节点)
|
||||
表头.首节点 = 当前->子节点;
|
||||
else if (当前 == 表头.尾节点)
|
||||
表头.尾节点 = 当前->父节点;
|
||||
|
||||
}
|
||||
|
||||
HeapFree(表头.堆句柄,0,当前);
|
||||
}
|
||||
|
||||
VOID 双向链表::删除(LPVOID 节点地址)
|
||||
{
|
||||
到某节点(节点地址);
|
||||
删除();
|
||||
}
|
||||
|
||||
VOID 双向链表::清空()
|
||||
{
|
||||
双向链表::~双向链表();
|
||||
双向链表::双向链表(表头.堆大小);
|
||||
}
|
||||
|
||||
VOID 双向链表::到某节点(LPVOID 节点地址)
|
||||
{
|
||||
表头.当前节点 = (双向链表_节点指针)节点地址;
|
||||
}
|
||||
|
||||
BOOL 双向链表::到父节点()
|
||||
{
|
||||
if (表头.当前节点)
|
||||
{
|
||||
if (表头.当前节点->父节点)
|
||||
{
|
||||
表头.当前节点 = 表头.当前节点->父节点;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL 双向链表::到子节点()
|
||||
{
|
||||
if (表头.当前节点)
|
||||
{
|
||||
if (表头.当前节点->子节点)
|
||||
{
|
||||
表头.当前节点 = 表头.当前节点->子节点;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID 双向链表::到首节点()
|
||||
{
|
||||
表头.当前节点 = 表头.首节点;
|
||||
}
|
||||
|
||||
VOID 双向链表::到尾节点()
|
||||
{
|
||||
表头.当前节点 = 表头.尾节点;
|
||||
}
|
||||
|
||||
LPVOID 双向链表::取节点值()
|
||||
{
|
||||
return 表头.当前节点 ? 表头.当前节点->节点值:NULL;
|
||||
}
|
||||
|
||||
DWORD 双向链表::取键值()
|
||||
{
|
||||
return 表头.当前节点 ? 表头.当前节点->键值:0;
|
||||
}
|
||||
|
||||
LPVOID 双向链表::取节点地址()
|
||||
{
|
||||
return 表头.当前节点;
|
||||
}
|
||||
|
||||
DWORD 双向链表::取节点数()
|
||||
{
|
||||
return 表头.节点数;
|
||||
}
|
Loading…
Reference in New Issue