|
[jass]
//说明:
// 这是一个通过点保存Handle,并组成链表的存储系统。存储的单元式项。每个项都可以构成一个链表以存储Handle、Integer、Real型的变量。
// 这个系统需要在初始化时建立,SetUpSystem为建立系统的过程,参数max为这个系统的最大项数,因为这个系统没有使用数组,所以这个最大值可以超过数组上限8192。
// 不过具体值请根据需要设置,过高会降低系统中某些函数的效率,过低有可能因为存储系统存满而出现问题。
// 为了通用化并减少代码,输入的参数是一个可以三种类别的值(Real、Handle、Integer三种皆可以,一般都是存储的或用于查找的变量)时,都是只写了Real型参数的函数,其他型请自行转换成Real型参数。
//
//定义:
// 英文名称的都是变量类型,也对应这种类型的变量,比如Timer指计时器变量,Location指点变量。
// 项:就是包括一个Timer,一个作为索引和辅助的Location,一个保存存储链表的第一个元素的Location,以及通过一系列Location组成的链表。
// 节点:项中的链表的存储映像,实际上就是一个Location,这个Location的X轴坐标值是下一个结点的Handle,Y轴坐标是这个结点存储的值。也就是说Location的X轴为指针域,Y轴为数据域。
// 点:特指初始化给每个项的那两个Location,即项中的辅助点和链表的第一个结点这两个Location,分别以第一点和第二点命名。
// 第一点:每一项所包含的固定内容之一,实质是一个Location,X轴坐标存储的是这一项的链表的最后一个结点的Hnadle值,Y轴坐标存储的是自定义内容,这里我作为索引项。
// 第二点,是项中链表的第一个结点,X轴坐标是第二个结点的Handle值,Y轴是存储的数据。
// 序号:项在整个系统中的序号,即在以物理地址为序的表中的位置,第二点的序号为0,其后依次增加。
// 存储上限:即系统能够存储的项的最大值,这个是初始化时自行给定的。
// Handle值:不同于Handle代表着一个Handle型变量,Handle值代表的是Handle型变量转换成的整数。
//
globals
timer udg_UseTimer = null
//当前使用的Timer
location udg_UseLocat = null
//当前使用Location
integer udg_UseAddress = 0
//正在使用的Handle值
integer udg_Maxnumber = 0
//预置的存储上限,可以大于8192
integer udg_FirstAddress = 0
//存储系统首的第一个Timer的Handle值
integer udg_NowNum = 0
//当前使用的项的序号
endglobals
function SetUpSystem takes integer max returns nothing
local integer N=1
local integer udg_UseAddress =0
local timer udg_UseTimer = null
local location udg_UseLocat = null
set udg_Maxnumber = max
//设置存储上限为参数max
set udg_UseTimer = CreateTimer()
set udg_FirstAddress = udg_UseAddress
set udg_UseLocat = Location(I2R(udg_UseAddress + 2), -1)
//第一点的X坐标是这个链表最后一个结点的handle值,Y坐标是用于判断项的索引的handle值(或integer与real,也可以保存其他内容),-1代表未使用。
set udg_UseLocat = Location(-1, -1)
//第二点的X坐标是这个链表下一个结点的handle值,Y坐标是这个节点存储的handle(或integer与real)。
//链表的每个结点都是:X轴为指针域,Y轴为数据域,指针域、数据域为-1时代表空
loop
set N = N + 1
exitwhen N > max
set udg_UseTimer = CreateTimer()
set udg_UseLocat = Location(I2R(udg_UseAddress + 2), -1)
set udg_UseLocat = Location(-1, -1)
endloop
set udg_UseTimer = null
set udg_UseLocat = null
return
endfunction
function H2I takes handle h returns integer
return h
return 0
endfunction
function R2H takes integer i returns handle
return i
return null
endfunction
function GetIndex takes nothing returns integer
//获取一个新的空白项的序号 (0~udg_Maxnumber-1)
local integer udg_UseAddress = 0
local location udg_UseLocat = null
local integer TempInt = udg_NowNum
loop
set udg_NowNum = udg_NowNum + 1
if udg_NowNum>=udg_Maxnumber then
set udg_NowNum = 0
endif
set udg_UseAddress = udg_FirstAddress + udg_NowNum * 3 + 2
exitwhen GetLocationY(udg_UseLocat) == -1
//空白项的第二个点的Y坐标为-1,默认
if udg_NowNum == TempInt then
return -1
endif
//当前所有项都在使用中返回-1
endloop
set udg_UseLocat = null
return udg_NowNum
endfunction
function InputData takes integer n ,real r returns nothing
//存储某个值。n为存储到的项的序号,r为存储内容。
local integer TempIntA = 0
local integer TempIntB = 0
local location udg_UseLocat = null
local integer udg_UseAddress = udg_FirstAddress + n * 3 + 2
if GetLocationY(udg_UseLocat) == -1 then
call MoveLocation( udg_UseLocat, GetLocationX(udg_UseLocat), r )
return
endif
//当存储在第二点(链表第一个结点)时
set udg_UseLocat = Location(-1, r)
//创建Location并记录数据
set TempIntA = udg_UseAddress
//保存刚创建的点的Handle值
set udg_UseAddress = udg_FirstAddress + n * 3 + 1
//获取序号为n的项第一点
set TempIntB = R2I(GetLocationX(udg_UseLocat))
//记录下当前的项的链表的最后一个结点的Handle值
call MoveLocation( udg_UseLocat, I2R(TempIntA), GetLocationY(udg_UseLocat) )
//修改项第一点所记录的最后一个结点的Handle值
set udg_UseAddress = TempIntB
//获得链表的最后一个结点
call MoveLocation( udg_UseLocat, I2R(TempIntA), GetLocationY(udg_UseLocat) )
//修改最后一个Location的X坐标(下一个结点的handle值),记录为存储输入数据的点的Handle值
set udg_UseLocat = null
return
endfunction
function GetTimerByIndex takes integer n returns timer
//通过序号获得对应Timer
local timer udg_UseTimer = null
local integer udg_UseAddress = udg_FirstAddress + n * 3
return udg_UseTimer
endfunction
function SetIndexHandle takes integer n ,real r returns nothing
//为项n添加索引的内容
local location udg_UseLocat = null
local integer udg_UseAddress = udg_FirstAddress + n * 3 + 1
call MoveLocation( udg_UseLocat, GetLocationX(udg_UseLocat), r )
set udg_UseLocat = null
return
endfunction
function OutputLocationByTimer takes timer t,location l returns location
//通过Timer获得对应项的第一个结点的Location ,参数中的Location是用于返回值的,使用时给为null就可以。
local location udg_UseLocat = null
local integer udg_UseAddress = 0
local timer udg_UseTimer = t
//第一个结点的handle一定是对应计时器的handle+2
set udg_UseAddress = udg_UseAddress + 2
set l = udg_UseLocat
set udg_UseLocat = null
return l
endfunction
function OutputLocationByAll takes real r,location l returns location
//通过作为索引的数据r获得第一个结点的Location。如果返回null则代表没有找到,索引内容参数中的Location是用于返回值的,使用时给为null就可以。
//这里是用项的第一点的Y轴的值作为引对象的,也可直接使用第二点的Y轴的值来索引
//为了不用为通过Integer或者Real来索引再写个函数,所以这里的参数类型 为Real,如果通过索引的是Handle或者Integer,请先转成Real再运行函数。
local integer udg_UseAddress = 0
local location udg_UseLocat = null
local integer N = udg_FirstAddress + 1
loop
if N > udg_FirstAddress+udg_Maxnumber*3 then
return null
endif
set udg_UseAddress = N
exitwhen GetLocationY(udg_UseLocat) == r
set N = N + 3
endloop
set udg_UseAddress = udg_UseAddress + 1
set l = udg_UseLocat
set udg_UseLocat = null
return l
endfunction
function OutputLocationByIndex takes integer n,location l returns location
//通过项的序号n获得对应项的第一个结点的Location ,参数中的Location是用于返回值的,使用时给为null就可以。
local location udg_UseLocat = null
local integer udg_UseAddress = udg_FirstAddress + n * 3 + 2
set l = udg_UseLocat
set udg_UseLocat = null
return l
endfunction
function OutputIndexByTimer takes timer t returns integer
//通过Timer返回使用的项的INDEX (0~udg_Maxnumber-1)
local integer udg_UseAddress = 0
local timer udg_UseTimer = t
local integer TempInt = (udg_UseAddress - udg_FirstAddress) / 3
//第一个结点的handle一定是对应计时器的handle+2
set udg_UseTimer =null
return TempInt
endfunction
function OutputIndexByAll takes real r returns integer
//通过作为索引的数据r获得Index
//这里是用项的第一点的Y轴的值作为引对象的,也可直接使用第二点的Y轴的值来索引
//为了不用为通过Integer或者Real来索引再写个函数,所以这里的参数类型 为Real,如果通过索引的是Handle或者Integer,请先转成Real再运行函数。
local integer udg_UseAddress = 0
local location udg_UseLocat = null
local integer N = udg_FirstAddress - 2
loop
set N = N + 3
if N > udg_FirstAddress + udg_Maxnumber * 3 then
return -1
//-1代表没有找到对应索引。
endif
set udg_UseAddress = N
exitwhen R2I(GetLocationY(udg_UseLocat)) == r
endloop
set N = (udg_UseAddress - udg_FirstAddress - 1 ) / 3
set udg_UseLocat = null
return N
endfunction
function OutputIndexByLocation takes location l returns integer
//通过链表的第一个结点l(Location)获得项的索引序号
local integer udg_UseAddress = 0
local integer TempInt = 0
local location udg_UseLocat = l
set TempInt = ( udg_UseAddress - udg_FirstAddress - 2 ) / 3
set udg_UseLocat = null
return TempInt
endfunction
function LoadData takes integer m,location l returns real
//通过链表的第一个结点l,返回结点序号为m(第m+1个结点)的数据域的值。
local integer udg_UseAddress = 0
local integer N = 1
local location udg_UseLocat = null
if m == 0 then
return GetLocationY(l)
endif
//如果求的是第一个结点(m为0)的数据,那么直接返回值
set udg_UseLocat = l
loop
set udg_UseAddress = R2I(GetLocationX(udg_UseLocat))
exitwhen N == m
set N = N + 1
endloop
set l = udg_UseLocat
set udg_UseLocat = null
return GetLocationY(l)
//寻找对应m的结点。
endfunction
function DestoryByIndex takes integer i returns nothing
//通过Index清空存储的项。
local location udg_UseLocat = null
local integer udg_UseAddress = udg_FirstAddress + i * 3 + 1
local integer TempIntA = R2I(GetLocationX(udg_UseLocat))
local integer TempIntB = 0
set TempIntB = udg_UseAddress + 1
call MoveLocation( udg_UseLocat, I2R(TempIntB), -1)
//获得最后一个结点的Handle,并修复第一个点
set udg_UseAddress = udg_UseAddress + 1
set TempIntB = R2I(GetLocationX(udg_UseLocat))
call MoveLocation( udg_UseLocat, -1, -1 )
//获得下一个结点的Handle,并修复第二个点
if TempIntB != -1 then
loop
set udg_UseAddress = TempIntB
set TempIntB = R2I(GetLocationX(udg_UseLocat))
//获取下一结点Handle
call RemoveLocation( udg_UseLocat )
//删除结点
exitwhen TempIntB == TempIntA
//当当前结点的Y坐标(下一个结点的Handle)等于最后一个点的Handle时结束循环
endloop
set udg_UseAddress = TempIntB
call RemoveLocation( udg_UseLocat )
set udg_UseLocat = null
endif
return
endfunction
function DestoryByTimer takes timer t returns nothing
//通过Timer清空存储的项。
local location udg_UseLocat = null
local integer udg_UseAddress = 0
local integer TempIntA = 0
local integer TempIntB = 0
local timer udg_UseTimer = t
set udg_UseAddress = udg_UseAddress + 1
//第一点
set TempIntA = R2I(GetLocationX(udg_UseLocat))
//记录最后一个结点的Handle值
call MoveLocation( udg_UseLocat, I2R(udg_UseAddress + 1), -1)
//修复第一个点
set udg_UseAddress = udg_UseAddress + 1
//第二个点
set TempIntB = R2I(GetLocationX(udg_UseLocat))
call MoveLocation( udg_UseLocat, -1, -1 )
//获得下一个结点的Handle,并修复第二个点
if TempIntB != -1 then
loop
set udg_UseAddress = TempIntB
set TempIntB = R2I(GetLocationX(udg_UseLocat))
//获取下一结点Handle
call RemoveLocation( udg_UseLocat )
//删除结点
exitwhen TempIntB == TempIntA
//当当前结点的Y坐标(下一个结点的Handle)等于最后一个点的Handle时结束循环
endloop
set udg_UseAddress = TempIntB
call RemoveLocation( udg_UseLocat )
set udg_UseLocat = null
endif
return
endfunction
function DestoryByHandle takes real r returns nothing
//通过Handle清空存储的项。
local integer TempInt = OutputIndexByAll( r )
//调用 OutputHanTakeH
call DestoryByIndex( TempInt )
//调用 DestoryByIndex
return
endfunction
function ChangeData takes integer n,integer m,real r returns nothing
//通过索引n,结点序号m(0为第一个结点),替换数据r,替换索引为n的项的链表的第m个元素的内容。
local integer udg_UseAddress = 0
local integer N = 0
local location udg_UseLocat = null
if m < 0 then
return
endif
set udg_UseAddress = udg_FirstAddress + n * 3 + 2
loop
if (GetLocationX(udg_UseLocat) == -1)and( N < m ) then
return
endif
//保证替换的元素的序号不会大于链表最大元素数
exitwhen N == m
set udg_UseAddress = R2I(GetLocationX(udg_UseLocat))
set N = N + 1
endloop
//找到要插入的位置
call MoveLocation( udg_UseLocat,GetLocationX(udg_UseLocat),r)
set udg_UseLocat = null
return
endfunction
[/jass]
注释写的很详细
需要说的只有一点
SetUpSystem这个函数因为执行上限的原因
不可能直接创建很多的项,不过我们可以使用某些函数来解决这个问题
不过具体哪个忘了……
另外这个代码没有纠错系统
如果获取空白点会跳出……
另外设计中这个存储系统是和数组变量系统配合使用的
数组变量系统 |
评分
-
查看全部评分
|