马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 Rubbish 于 2021-12-20 23:57 编辑
没什么好说的
直接上代码吧
-
- library CenterTimer requires RemoveSystem
-
- globals
- private integer ExpiredTimer = 0
- endglobals
-
- module Alloc
- private static integer instanceCount = 0
- private thistype recycle
-
- static method allocate takes nothing returns thistype
- local thistype this
-
- if (thistype(0).recycle == 0) then
- if (instanceCount == JASS_MAX_ARRAY_SIZE) then
- call BJDebugMsg( "Alloc ERROR: Attempted to allocate too many instances!" )
- return 0
- endif
- set instanceCount = instanceCount + 1
- set this = instanceCount
- else
- set this = thistype(0).recycle
- set thistype(0).recycle = thistype(0).recycle.recycle
- endif
-
- debug set this.recycle = -1
-
- return this
- endmethod
-
- method deallocate takes nothing returns nothing
- if (this.recycle != -1) then
- call BJDebugMsg( "Alloc ERROR: Attempted to deallocate an invalid instance at [" + I2S(this) + "]!" )
- return
- endif
-
- set this.recycle = thistype(0).recycle
- set thistype(0).recycle = this
- endmethod
- endmodule
-
- module LinkedList
- readonly thistype next
- readonly thistype prev
-
- method init takes nothing returns thistype
- set .next = this
- set .prev = this
-
- return this
- endmethod
-
- method pushBack takes thistype node returns thistype
- set node.prev = prev
- set node.next = this
- set prev.next = node
- set prev = node
-
- return node
- endmethod
-
- method pushFront takes thistype node returns thistype
- set node.prev = this
- set node.next = next
- set next.prev = node
- set next = node
-
- return node
- endmethod
-
- method pop takes nothing returns nothing
- set prev.next = next
- set next.prev = prev
- endmethod
- endmodule
-
- private struct Group extends array
- implement LinkedList
- implement Alloc
-
- TimerSystem timer
-
- method remove takes nothing returns nothing
- call .pop()
- call .deallocate()
- endmethod
-
- method insert takes TimerSystem m returns thistype
- local thistype node = .pushBack( allocate( ) )
- set node.timer = m
-
- return node
- endmethod
-
- static method create takes nothing returns thistype
- return thistype(allocate()).init()
- endmethod
- endstruct
-
- private struct TGroup
- Group group
- integer size
- integer time
-
- private static constant hashtable ht = InitHashtable( )
-
- method destroy takes nothing returns nothing
- call RemoveSavedInteger( thistype.ht , <?=StringHash( 'record' )?> , .time )
- call .group.deallocate()
- call .deallocate()
- endmethod
-
- method insert takes TimerSystem time returns nothing
- set .size = .size + 1
- call .group.insert( time )
- endmethod
-
- static method create takes integer time returns thistype
- local thistype this = 0
- if HaveSavedInteger( thistype.ht , <?=StringHash( 'record' )?> , time ) then
- set this = LoadInteger( thistype.ht , <?=StringHash( 'record' )?> , time )
- else
- set this = thistype.allocate( )
- set .group = Group.create( )
- set .size = 0
- set .time = time
- call SaveInteger( thistype.ht , <?=StringHash( 'record' )?> , time , this )
- endif
- return this
- endmethod
-
- static method have takes integer time returns boolean
- return HaveSavedInteger( thistype.ht , <?=StringHash( 'record' )?> , time )
- endmethod
-
- endstruct
-
- struct TimerSystem
- private integer timerout
- private boolean is_loop
- private trigger trig
- private boolean removed
- private boolean paused
- private integer remaing
- private integer cur_index
- integer userDataI
-
- static integer cur_frame = 0
- static integer max_frame = 0
- private static constant timer time = CreateTimer( )
- private static constant real times = 0.01 / 10
-
- method destroy takes nothing returns nothing
- call DestroyTrigger( .trig )
- set .timerout = 0
- set .is_loop = false
- set .trig = null
- set .removed = false
- set .paused = false
- set .cur_index = 0
- set .remaing = 0
- set .userDataI = 0
- call .deallocate( )
- endmethod
-
- method wake_up takes nothing returns nothing
- local integer time = thistype.cur_frame + this.timerout
- local TGroup data = 0
- if .removed or .paused then
- if .removed then
- call .destroy( )
- endif
- return
- endif
- set ExpiredTimer = this
- call TriggerEvaluate( this.trig )
- if this.is_loop then
- set data = TGroup.create( time )
- set .cur_index = time
- call data.insert( this )
- else
- call .destroy( )
- endif
- endmethod
-
- method get_remaining takes nothing returns integer
- if .removed then
- return 0
- elseif .paused then
- return .remaing
- elseif .cur_index == thistype.cur_frame then
- if .is_loop then
- return timerout
- else
- return 0
- endif
- endif
- return .cur_index - thistype.cur_frame
- endmethod
-
- method get_timerout takes nothing returns integer
- return .timerout
- endmethod
-
- method remove takes nothing returns nothing
- if not .removed then
- set .removed = true
- endif
- endmethod
-
- method pause takes nothing returns nothing
- if not .paused then
- set .remaing = .get_remaining( )
- set .paused = true
- endif
- endmethod
-
- method resume takes nothing returns nothing
- local integer time = 0
- local TGroup data = 0
- if .paused then
- set .paused = true
- set time = thistype.cur_frame + .remaing
- set .cur_index = time
- set data = TGroup.create( time )
- call data.insert( this )
- endif
- endmethod
-
- static method Actions takes nothing returns nothing
- local thistype this = 0
- local TGroup data = 0
- local Group node = 0
- set thistype.max_frame = thistype.max_frame + R2I( thistype.times * 1000 )
- loop
- exitwhen thistype.cur_frame >= thistype.max_frame
- if TGroup.have( thistype.cur_frame ) then
- set data = TGroup.create( thistype.cur_frame )
- if data.size > 0 then
- set node = data.group.next
- loop
- exitwhen node == data.group
- call node.timer.wake_up( )
- call node.remove( )
- set node = node.next
- endloop
- endif
- call data.destroy( )
- endif
- set thistype.cur_frame = thistype.cur_frame + 1
- endloop
- endmethod
-
- static method create takes integer t , boolean periodic , code handlerFunc returns thistype
- local integer time = thistype.cur_frame + t
- local TGroup data = TGroup.create( time )
- local boolexpr filter = Filter( handlerFunc )
- local thistype this = thistype.allocate( )
- call data.insert( this )
- set .trig = CreateTrigger( )
- set .timerout = t
- set .is_loop = periodic
- set .removed = false
- set .paused = false
- set .cur_index = time
- set .remaing = 0
- set .userDataI = 0
- call TriggerAddCondition( .trig , filter )
- return this
- endmethod
-
- static method onInit takes nothing returns nothing
- call TimerStart( thistype.time , thistype.times , true , function thistype.Actions )
- endmethod
-
- endstruct
-
- //获取到期中心计时器序号
- function EXGetExpiredTimer takes nothing returns TimerSystem
- return ExpiredTimer
- endfunction
-
- //删除中心计时器
- function EXDestroyTimer takes TimerSystem this returns nothing
- call this.remove( )
- endfunction
-
- //创建中心计时器
- function EXTimerStart takes real timeout , boolean periodic , code handlerFunc returns integer
- return TimerSystem.create( R2I( timeout * 1000 ) , periodic , handlerFunc )
- endfunction
-
- //暂停中心计时器
- function EXPauseTimer takes TimerSystem this returns nothing
- call this.pause( )
- endfunction
-
- //恢复中心计时器
- function EXResumeTimer takes TimerSystem this returns nothing
- call this.pause( )
- endfunction
-
- //获取剩余时间
- function EXGetTimerRemaining takes TimerSystem this returns real
- return I2R( this.get_remaining( ) ) / 1000
- endfunction
-
- //获取设置时间
- function EXGetTimerTimerout takes TimerSystem this returns real
- return I2R( this.get_timerout( ) ) / 1000
- endfunction
-
- endlibrary
复制代码
|