找回密码
 点一下

疯人¢衰人

https://bbs.islga.org/?4487

Timer-Location

已有 190 次阅读2009-5-16 18:47

//说明:
//    这是一个通过点保存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

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 点一下

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-5-22 05:48 , Processed in 0.121216 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

返回顶部