2023-02-15 04:02:07 +00:00
package resolv
2022-09-20 15:50:01 +00:00
2022-12-24 05:57:32 +00:00
const (
2023-03-02 02:22:27 +00:00
// Declare type "int32" explicitly to prevent go2cs from transpiling them to "var"
RING_BUFF_CONSECUTIVE_SET int32 = 0
RING_BUFF_NON_CONSECUTIVE_SET int32 = 1
RING_BUFF_FAILED_TO_SET int32 = 2
2022-12-24 05:57:32 +00:00
)
2023-03-01 10:20:54 +00:00
type AnyObj interface { }
2022-09-20 15:50:01 +00:00
type RingBuffer struct {
2022-09-24 04:01:50 +00:00
Ed int32 // write index, open index
St int32 // read index, closed index
2022-09-20 15:50:01 +00:00
EdFrameId int32
StFrameId int32
N int32
Cnt int32 // the count of valid elements in the buffer, used mainly to distinguish what "st == ed" means for "Pop" and "Get" methods
2023-03-01 10:20:54 +00:00
Eles [ ] AnyObj
2022-09-20 15:50:01 +00:00
}
func NewRingBuffer ( n int32 ) * RingBuffer {
2023-03-01 10:20:54 +00:00
ret := & RingBuffer { }
ret . Ed = 0
ret . St = 0
ret . EdFrameId = 0
ret . StFrameId = 0
ret . N = n
ret . Cnt = 0
ret . Eles = make ( [ ] AnyObj , n )
return ret
2022-09-20 15:50:01 +00:00
}
2023-02-17 10:54:51 +00:00
func ( rb * RingBuffer ) DryPut ( ) {
for 0 < rb . Cnt && rb . Cnt >= rb . N {
// Make room for the new element
rb . Pop ( )
}
rb . EdFrameId ++
rb . Cnt ++
rb . Ed ++
if rb . Ed >= rb . N {
rb . Ed -= rb . N // Deliberately not using "%" operator for performance concern
}
}
2023-03-01 10:20:54 +00:00
func ( rb * RingBuffer ) Put ( pItem AnyObj ) {
2022-12-02 02:20:58 +00:00
for 0 < rb . Cnt && rb . Cnt >= rb . N {
2022-11-29 13:32:18 +00:00
// Make room for the new element
rb . Pop ( )
}
2022-09-20 15:50:01 +00:00
rb . Eles [ rb . Ed ] = pItem
rb . EdFrameId ++
rb . Cnt ++
rb . Ed ++
if rb . Ed >= rb . N {
rb . Ed -= rb . N // Deliberately not using "%" operator for performance concern
}
}
2023-03-01 10:20:54 +00:00
func ( rb * RingBuffer ) Pop ( ) AnyObj {
2022-09-20 15:50:01 +00:00
if 0 == rb . Cnt {
return nil
}
pItem := rb . Eles [ rb . St ]
rb . StFrameId ++
rb . Cnt --
rb . St ++
if rb . St >= rb . N {
rb . St -= rb . N
}
return pItem
}
2022-12-24 05:57:32 +00:00
func ( rb * RingBuffer ) GetArrIdxByOffset ( offsetFromSt int32 ) int32 {
if 0 == rb . Cnt || 0 > offsetFromSt {
return - 1
2022-09-20 15:50:01 +00:00
}
arrIdx := rb . St + offsetFromSt
if rb . St < rb . Ed {
// case#1: 0...st...ed...N-1
if rb . St <= arrIdx && arrIdx < rb . Ed {
2022-12-24 05:57:32 +00:00
return arrIdx
2022-09-20 15:50:01 +00:00
}
} else {
// if rb.St >= rb.Ed
// case#2: 0...ed...st...N-1
if arrIdx >= rb . N {
arrIdx -= rb . N
}
if arrIdx >= rb . St || arrIdx < rb . Ed {
2022-12-24 05:57:32 +00:00
return arrIdx
2022-09-20 15:50:01 +00:00
}
}
2022-12-24 05:57:32 +00:00
return - 1
}
2023-03-01 10:20:54 +00:00
func ( rb * RingBuffer ) GetByOffset ( offsetFromSt int32 ) AnyObj {
2022-12-24 05:57:32 +00:00
arrIdx := rb . GetArrIdxByOffset ( offsetFromSt )
if - 1 == arrIdx {
return nil
}
return rb . Eles [ arrIdx ]
2022-09-20 15:50:01 +00:00
}
2023-03-01 10:20:54 +00:00
func ( rb * RingBuffer ) GetByFrameId ( frameId int32 ) AnyObj {
2022-12-02 02:20:58 +00:00
if frameId >= rb . EdFrameId || frameId < rb . StFrameId {
2022-11-29 13:32:18 +00:00
return nil
}
2022-09-20 15:50:01 +00:00
return rb . GetByOffset ( frameId - rb . StFrameId )
}
2022-12-24 05:57:32 +00:00
// [WARNING] During a battle, frontend could receive non-consecutive frames (either renderFrame or inputFrame) due to resync, the buffer should handle these frames properly.
2023-03-01 10:20:54 +00:00
func ( rb * RingBuffer ) SetByFrameId ( pItem AnyObj , frameId int32 ) ( int32 , int32 , int32 ) {
2022-12-24 05:57:32 +00:00
oldStFrameId , oldEdFrameId := rb . StFrameId , rb . EdFrameId
if frameId < oldStFrameId {
return RING_BUFF_FAILED_TO_SET , oldStFrameId , oldEdFrameId
}
// By now "rb.StFrameId <= frameId"
if oldEdFrameId > frameId {
arrIdx := rb . GetArrIdxByOffset ( frameId - rb . StFrameId )
if - 1 != arrIdx {
rb . Eles [ arrIdx ] = pItem
return RING_BUFF_CONSECUTIVE_SET , oldStFrameId , oldEdFrameId
}
}
// By now "rb.EdFrameId <= frameId"
ret := RING_BUFF_CONSECUTIVE_SET
if oldEdFrameId < frameId {
rb . St , rb . Ed = 0 , 0
rb . StFrameId , rb . EdFrameId = frameId , frameId
rb . Cnt = 0
ret = RING_BUFF_NON_CONSECUTIVE_SET
}
// By now "rb.EdFrameId == frameId"
rb . Put ( pItem )
return ret , oldStFrameId , oldEdFrameId
}
2023-02-15 04:02:07 +00:00
func ( rb * RingBuffer ) Clear ( ) {
for 0 < rb . Cnt {
rb . Pop ( )
}
rb . St = 0
rb . Ed = 0
rb . StFrameId = 0
rb . EdFrameId = 0
}
2023-02-16 00:17:50 +00:00
func ( rb * RingBuffer ) GetStFrameId ( ) int32 {
return rb . StFrameId
}
func ( rb * RingBuffer ) GetEdFrameId ( ) int32 {
return rb . EdFrameId
}
func ( rb * RingBuffer ) GetCnt ( ) int32 {
return rb . Cnt
}