diff --git a/strutils.go b/strutils.go index 0605362..d22c7e3 100644 --- a/strutils.go +++ b/strutils.go @@ -79,8 +79,23 @@ func StrContains(s string, substr string) bool { func ConvertUpperCamelCase(name string) string { newName := "" + preIs_ := false for i := 0; i < len(name); i++ { - newName += name[i:i] + if i == 0 { + newName += strings.ToUpper(name[i:i +1]) + preIs_ = name[i] == '_' + } else { + if preIs_ { + if name[i] != '_' { + newName += strings.ToUpper(name[i:i +1]) + } + } else { + if name[i] != '_' { + newName += name[i:i +1] + } + } + preIs_ = name[i] == '_' + } } return newName } diff --git a/timer.go b/timer.go index bb2e267..ccc4b76 100644 --- a/timer.go +++ b/timer.go @@ -9,18 +9,21 @@ const TVN_MASK = TVN_SIZE - 1 const TVR_MASK = TVR_SIZE - 1 const ( - DEADLINE_TIMER = 0 - REPEAT_TIMER = iota - FIXED_TIMER = iota + TIMEOUT_TIMER = 0 + INTERVAL_TIMER = iota ) -type Timer struct { +type XTimerDestoryHandleNode struct { + entry ListHead + cb func() +} + +type XTimer struct { freeTimerNum int32 freeTimerList ListHead - runningTimer *TimerList + runningTimer *XTimerList timerTick int64 getTickCount func (interface{}) int64 - getFixedTimerExpires func (interface{}, bool, int32, int64) int64 context interface{} cacheTimerNum int32 tv1 [TVR_SIZE]ListHead @@ -30,9 +33,8 @@ type Timer struct { tv5 [TVN_SIZE]ListHead } -func (this *Timer) Init( +func (this *XTimer) Init( getTickCount func (interface{}) int64, - getFixedTimerExpires func (interface{}, bool, int32, int64) int64, context interface{}, gcTime int32, cacheTimerNum int32) { @@ -49,25 +51,19 @@ func (this *Timer) Init( this.timerTick = getTickCount(context) this.context = context this.getTickCount = getTickCount - this.getFixedTimerExpires = getFixedTimerExpires this.cacheTimerNum = cacheTimerNum - this.AddRepeatTimer( - gcTime, - func (params *XParams) { - - }, - this.gcTimerFunc) + this.SetInterval(gcTime, this.gcTimerFunc) } -func (this *Timer) UnInit() { +func (this *XTimer) UnInit() { this.clear() } -func (this *Timer) clear() { +func (this *XTimer) clear() { freeTimerFunc := func (data interface{}) { head := data.(*ListHead) for !head.Empty() { - timerList := head.FirstEntry().(*TimerList) + timerList := head.FirstEntry().(*XTimerList) this.detachTimer(timerList) if !timerList.attachEntry.Empty() { timerList.attachEntry.DelInit() @@ -82,7 +78,7 @@ func (this *Timer) clear() { TraverseArray(&this.tv5, freeTimerFunc) } -func (this *Timer) Update() { +func (this *XTimer) Update() { for this.getTickCount(this.context) >= this.timerTick { index := uint32(this.timerTick & TVR_MASK) @@ -97,21 +93,15 @@ func (this *Timer) Update() { var workList ListHead this.tv1[index].ReplaceInit(&workList) for !workList.Empty() { - timerList := workList.FirstEntry().(*TimerList) - this.runningTimer = timerList - if timerList.timerFunc != nil { - timerList.timerFunc(&timerList.params) - } - if timerList.timerAfterFunc != nil { - timerList.timerAfterFunc(&timerList.params) - } + timer := workList.FirstEntry().(*XTimerList) + this.runningTimer = timer + timer.cb(TIMER_EXEC_EVENT, nil) if this.runningTimer != nil { switch this.runningTimer.timerType { - case REPEAT_TIMER, FIXED_TIMER: - this.modifyTimerEx(timerList, timerList.milliSeconds, false) - case DEADLINE_TIMER: - this.detachTimer(timerList) - this.addToFreeList(timerList) + case TIMEOUT_TIMER: + this.internalDelete(timer, false, true) + case INTERVAL_TIMER: + this.internalModifyTime(timer, timer.expireTime) } } } @@ -119,143 +109,106 @@ func (this *Timer) Update() { this.runningTimer = nil } -func (this *Timer) NewTimerAttacher() *TimerAttacher { - attacher := new(TimerAttacher) +func (this *XTimer) NewTimerAttacher() *XTimerAttacher { + attacher := new(XTimerAttacher) attacher.timer = this attacher.timers.Init(nil) return attacher } -func (this *Timer) AddDeadLineTimer( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams)) *TimerList { - return this.AddDeadLineTimerEx(milli_seconds, init_func, timer_func, nil) +func (this *XTimer) SetTimeout(expireTime int32, cb TimerCb) { + this.internalSetTimeout(expireTime, cb, nil, nil) } -func (this *Timer) AddSimpleDeadLineTimer( - milli_seconds int32, - timer_func func (params* XParams)) *TimerList { - return this.AddDeadLineTimer(milli_seconds, nil, timer_func); +func (this *XTimer) SetTimeoutEx(expireTime int32, cb TimerCb, attacher *XTimerAttacher) { + this.internalSetTimeout(expireTime, cb, attacher, nil) } -func (this *Timer) AddDeadLineTimerEx( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams), - install_func func (timerList *TimerList, params* XParams)) *TimerList { - timerList := this.newTimerList() - timerList.params.Reset() - if init_func != nil { - init_func(&timerList.params) +func (this *XTimer) SetTimeoutWp(expireTime int32, cb TimerCb) *XTimerWp { + var wp *XTimerWp + this.internalSetTimeout(expireTime, cb, nil, &wp) + return wp +} + +func (this *XTimer) SetTimeoutExWp(expireTime int32, cb TimerCb, attacher *XTimerAttacher) *XTimerWp { + var wp *XTimerWp + this.internalSetTimeout(expireTime, cb, attacher, &wp) + return wp +} + +func (this *XTimer) SetInterval(expireTime int32, cb TimerCb) { + this.internalSetInterval(expireTime, cb, nil, nil) +} + +func (this *XTimer) SetIntervalEx(expireTime int32, cb TimerCb, attacher *XTimerAttacher) { + this.internalSetInterval(expireTime, cb, attacher, nil) +} + +func (this *XTimer) SetIntervalWp(expireTime int32, cb TimerCb) *XTimerWp { + var wp *XTimerWp + this.internalSetInterval(expireTime, cb, nil, &wp) + return wp +} + +func (this *XTimer) SetIntervalExWp(expireTime int32, cb TimerCb, attacher *XTimerAttacher) *XTimerWp { + var wp *XTimerWp + this.internalSetInterval(expireTime, cb, attacher, &wp) + return wp +} + +func (this *XTimer) internalSetTimeout(expireTime int32, cb TimerCb, attacher *XTimerAttacher, wpPp**XTimerWp) { + timer := this.newTimerList() + timer.initTimerList(this, TIMEOUT_TIMER, expireTime, cb) + if attacher != nil { + attacher.timers.AddTail(&timer.attachEntry) } - timerList.initTimerList(this, DEADLINE_TIMER, milli_seconds, timer_func) - if install_func != nil { - install_func(timerList, &timerList.params) + this.internalModifyTime(timer, expireTime) + if wpPp != nil { + timer.wp = &XTimerWp{ + timer: timer, + } + *wpPp = timer.wp } - this.ModifyTimer(timerList, milli_seconds) - return timerList } -func (this *Timer) AddRepeatTimer( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams)) *TimerList { - return this.AddRepeatTimerEx(milli_seconds, init_func, timer_func, nil) +func (this *XTimer) internalSetInterval(expireTime int32, cb TimerCb, attacher *XTimerAttacher, wpPp**XTimerWp) { + timer := this.newTimerList() + timer.initTimerList(this, INTERVAL_TIMER, expireTime, cb) + if attacher != nil { + attacher.timers.AddTail(&timer.attachEntry) + } + this.internalModifyTime(timer, expireTime) + if wpPp != nil { + timer.wp = &XTimerWp{ + timer: timer, + } + *wpPp = timer.wp + } } -func (this *Timer) AddSimpleRepeatTimer( - milli_seconds int32, - timer_func func (params* XParams)) *TimerList { - return this.AddRepeatTimer(milli_seconds, nil, timer_func) +func (this *XTimer) ModifyTimer(timerWp *XTimerWp, expireTime int32) { + if timerWp.Expired() { + panic("Xtimer ModifyTimer expired timer") + } + this.internalModifyTime(timerWp.timer, expireTime) } -func (this *Timer) AddRepeatTimerEx( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams), - install_func func (timer_list *TimerList, params* XParams)) *TimerList { - timerList := this.newTimerList() - if init_func != nil { - init_func(&timerList.params) +func (this *XTimer) Delete(timerWp *XTimerWp) { + if timerWp.Expired() { + panic("Xtimer Delete expired timer") } - timerList.initTimerList(this, REPEAT_TIMER, milli_seconds, timer_func) - if install_func != nil { - install_func(timerList, &timerList.params) - } - this.ModifyTimer(timerList, milli_seconds) - return timerList + this.internalDelete(timerWp.timer, false, true) } -func (this *Timer) AddFixedTimer( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams)) *TimerList { - return this.AddFixedTimerEx(milli_seconds, init_func, timer_func, nil) +func (this *XTimer) GetRemainTime(timerWp *XTimerWp) int64 { + if timerWp.Expired() { + panic("Xtimer GetRemainTime expired timer") + } + return this.internalGetRemainTime(timerWp.timer) } -func (this *Timer) AddSimpleFixedTimer( - milli_seconds int32, - timer_func func (params* XParams)) *TimerList { - return this.AddFixedTimer(milli_seconds, nil, timer_func) -} - -func (this *Timer) AddFixedTimerEx( - milli_seconds int32, - init_func func (params* XParams), - timer_func func (params* XParams), - install_func func (timer_list *TimerList, params* XParams)) *TimerList { - timerList := this.newTimerList() - if init_func != nil { - init_func(&timerList.params) - } - timerList.initTimerList(this, FIXED_TIMER, milli_seconds, timer_func) - if install_func != nil { - install_func(timerList, &timerList.params) - } - this.ModifyTimer(timerList, milli_seconds) - return timerList -} - -func (this *Timer) ModifyTimer(timerList *TimerList, milliSeconds int32) { - this.modifyTimerEx(timerList, milliSeconds, true) -} - -func (this *Timer) modifyTimerEx(timerList *TimerList, milliSeconds int32, isFirstAdd bool) { - this.detachTimer(timerList) - timerList.milliSeconds = milliSeconds - if timerList.timerType == FIXED_TIMER { - tick := this.getTickCount(this.context) - timerList.expires = this.getFixedTimerExpires( - this.context, - isFirstAdd, - milliSeconds, - tick) - } else { - timerList.expires = this.getTickCount(this.context) + int64(milliSeconds) - } - this.internalAddTimer(timerList) -} - -func (this *Timer) DeleteTimer(timerList *TimerList) { - if timerList == nil { - return - } - if this.runningTimer == timerList { - this.runningTimer = nil - } - if timerList.timerAfterFunc != nil { - timerList.timerAfterFunc(&timerList.params) - } - this.detachTimer(timerList) - this.addToFreeList(timerList) -} - -func (this *Timer) GetRemainTime(timerList *TimerList) int64 { - if timerList == nil { - return 0 - } - remainTime := timerList.expires - this.getTickCount(this.context) +func (this *XTimer) internalGetRemainTime(timer *XTimerList) int64 { + remainTime := timer.expires - this.getTickCount(this.context) if remainTime < 0 { return 0 } else { @@ -263,11 +216,7 @@ func (this *Timer) GetRemainTime(timerList *TimerList) int64 { } } -func (this *Timer) GetRunningTimer() *TimerList { - return this.runningTimer -} - -func (this *Timer) GetIdleTime() int64 { +func (this *XTimer) GetIdleTime() int64 { var idleTime int64 = 1 for i := (this.timerTick & TVR_MASK); i < TVR_SIZE; i++ { if !this.tv1[i].Empty() { @@ -278,19 +227,19 @@ func (this *Timer) GetIdleTime() int64 { return idleTime } -func (this *Timer) detachTimer(timerList *TimerList) { +func (this *XTimer) detachTimer(timerList *XTimerList) { if !timerList.entry.Empty() { timerList.entry.DelInit() } } -func (this *Timer) addToFreeList(timerList *TimerList) { +func (this *XTimer) addToFreeList(timerList *XTimerList) { timerList.reset() this.freeTimerList.AddTail(&timerList.entry) this.freeTimerNum++ } -func (this *Timer) cascade(tv *[TVN_SIZE]ListHead, index uint32) uint32 { +func (this *XTimer) cascade(tv *[TVN_SIZE]ListHead, index uint32) uint32 { var cascadeList ListHead tv[index].ReplaceInit(&cascadeList) @@ -298,7 +247,7 @@ func (this *Timer) cascade(tv *[TVN_SIZE]ListHead, index uint32) uint32 { pos := cascadeList.next next := pos.next for pos != &cascadeList { - this.internalAddTimer(pos.data.(*TimerList)) + this.internalAddTimer(pos.data.(*XTimerList)) pos = next next = pos.next } @@ -306,7 +255,7 @@ func (this *Timer) cascade(tv *[TVN_SIZE]ListHead, index uint32) uint32 { return index } -func (this *Timer) internalAddTimer(timerList *TimerList) { +func (this *XTimer) internalAddTimer(timerList *XTimerList) { timerList.entry.data = timerList expires := timerList.expires idx := expires - this.timerTick @@ -335,31 +284,80 @@ func (this *Timer) internalAddTimer(timerList *TimerList) { vec.AddTail(&timerList.entry) } -func (this *Timer) getTimerIndex(index uint32) uint32 { +func (this *XTimer) getTimerIndex(index uint32) uint32 { return (uint32)((this.timerTick >> (TVR_BITS + index * TVN_BITS)) & TVN_MASK); } -func (this *Timer) newTimerList() *TimerList { +func (this *XTimer) newTimerList() *XTimerList { if !this.freeTimerList.Empty() { - timerList := this.freeTimerList.FirstEntry().(*TimerList) + timerList := this.freeTimerList.FirstEntry().(*XTimerList) this.freeTimerNum-- return timerList } else { - timerList := new(TimerList) + timerList := new(XTimerList) timerList.init() return timerList } } -func (this *Timer) gcTimerFunc(params *XParams) { - count := 0 - for ; !this.freeTimerList.Empty() && this.freeTimerNum > this.cacheTimerNum; { - timerList := this.freeTimerList.FirstEntry().(*TimerList) - timerList.entry.DelInit() - this.freeTimerNum-- - count++ - if count > 1000 { - break +func (this *XTimer) gcTimerFunc(ev int32, args *Args) { + if ev == TIMER_EXEC_EVENT { + count := 0 + for ; !this.freeTimerList.Empty() && this.freeTimerNum > this.cacheTimerNum; { + timerList := this.freeTimerList.FirstEntry().(*XTimerList) + timerList.entry.DelInit() + this.freeTimerNum-- + count++ + if count > 1000 { + break + } } } } + +func (this *XTimer) internalDelete(timer *XTimerList, isDestory bool, toFreeList bool) { + if timer == nil { + panic("Xtimer.internalDelete error") + } + if this.runningTimer == timer { + this.runningTimer = nil + } + this.detachTimer(timer) + if !timer.attachEntry.Empty() { + timer.attachEntry.DelInit() + } + if isDestory { + timer.cb(TIMER_DESTORY_EVENT, nil) + } else { + timer.cb(TIMER_DELETE_EVENT, nil) + } + timer.cb = nil + if timer.wp != nil { + timer.wp.timer = nil + timer.wp = nil + } + for !timer.destoryHandleList.Empty() { + handle := timer.destoryHandleList.FirstEntry().(XTimerDestoryHandleNode) + handle.entry.DelInit() + handle.cb() + } + if toFreeList { + this.addToFreeList(timer) + } +} + +func (this *XTimer) internalModifyTime(timer *XTimerList, expireTime int32) { + this.detachTimer(timer) + timer.expireTime = expireTime + timer.expires = this.getTickCount(this.context) + int64(expireTime) + this.internalAddTimer(timer) +} + +func (this *XTimer) clearAttacher(attacher* XTimerAttacher) { + var workList ListHead + attacher.timers.ReplaceInit(&workList) + for !workList.Empty() { + timer := workList.FirstEntry().(*XTimerList) + this.internalDelete(timer, false, true) + } +} diff --git a/timerlist.go b/timerlist.go index 5d21577..e3c69b9 100644 --- a/timerlist.go +++ b/timerlist.go @@ -1,62 +1,59 @@ package q5 -type TimerAttacher struct { - timer *Timer +type XTimerWp struct { + timer *XTimerList +} + +type XTimerAttacher struct { + timer *XTimer timers ListHead } -func (this *TimerAttacher) ClearTimers() { - var workList ListHead - this.timers.ReplaceInit(&workList) - for !workList.Empty() { - timerList := workList.FirstEntry().(*TimerList) - this.timer.DeleteTimer(timerList) - } +func (this *XTimerAttacher) ClearTimers() { + this.timer.clearAttacher(this) } -type TimerList struct { +type XTimerList struct { + destoryHandleList ListHead entry ListHead attachEntry ListHead timerType int8 - milliSeconds int32 + expireTime int32 expires int64 - timerFunc func (params *XParams) - timerAfterFunc func (params *XParams) - params XParams + cb TimerCb + wp *XTimerWp } -func (this *TimerList) initTimerList( +func (this *XTimerWp) Expired() bool { + return this.timer == nil +} + +func (this *XTimerList) initTimerList( timer interface{}, timerType int8, - millSeconds int32, - timerFunc func (params *XParams)) { + expireTime int32, + cb TimerCb) { this.timerType = timerType - this.milliSeconds = millSeconds - this.timerFunc = timerFunc + this.expireTime = expireTime + this.cb = cb } -func (this *TimerList) reset() { +func (this *XTimerList) reset() { if !this.entry.Empty() { this.entry.DelInit() } if !this.attachEntry.Empty() { this.attachEntry.DelInit() } - this.timerFunc = nil - this.timerAfterFunc = nil - this.params.Reset() + this.cb = nil } -func (this *TimerList) init() { +func (this *XTimerList) init() { this.entry.Init(this) this.attachEntry.Init(this) } -func (this *TimerList) SetTimerAfterFunc(timerAfterFunc func(*XParams)) { - this.timerAfterFunc = timerAfterFunc -} - -func (this *TimerList) Attach(timerAttacher *TimerAttacher) { +func (this *XTimerList) Attach(timerAttacher *XTimerAttacher) { timerAttacher.timers.AddTail(&this.attachEntry) } diff --git a/types.go b/types.go index 10a210f..b580bfd 100644 --- a/types.go +++ b/types.go @@ -1 +1,8 @@ package q5 + +type TimerCb func (int32, *Args) +type Args []interface{} + +const TIMER_EXEC_EVENT = 1 +const TIMER_DELETE_EVENT = 2 +const TIMER_DESTORY_EVENT = 3 diff --git a/xparams.go b/xparams.go deleted file mode 100644 index 08d6f4a..0000000 --- a/xparams.go +++ /dev/null @@ -1,21 +0,0 @@ -package q5 - -type XParams struct { - Sender XValue - Param1 XValue - Param2 XValue - Param3 XValue -} - -func (this *XParams) Reset() *XParams { - this.Sender.Reset() - this.Param1.Reset() - this.Param2.Reset() - this.Param3.Reset() - return this -} - -func (this *XParams) Init(initFunc func (*XParams)) *XParams { - initFunc(this) - return this -}