50a72e7a83
The idea is to use a Layered Asset File-system (modules/assetfs/layered.go) For example: when there are 2 layers: "custom", "builtin", when access to asset "my/page.tmpl", the Layered Asset File-system will first try to use "custom" assets, if not found, then use "builtin" assets. This approach will hugely simplify a lot of code, make them testable. Other changes: * Simplify the AssetsHandlerFunc code * Simplify the `gitea embedded` sub-command code --------- Co-authored-by: Jason Song <i@wolfogre.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
48 lines
769 B
Go
48 lines
769 B
Go
// Copyright 2020 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package util
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// StopTimer is a utility function to safely stop a time.Timer and clean its channel
|
|
func StopTimer(t *time.Timer) bool {
|
|
stopped := t.Stop()
|
|
if !stopped {
|
|
select {
|
|
case <-t.C:
|
|
default:
|
|
}
|
|
}
|
|
return stopped
|
|
}
|
|
|
|
func Debounce(d time.Duration) func(f func()) {
|
|
type debouncer struct {
|
|
mu sync.Mutex
|
|
t *time.Timer
|
|
}
|
|
db := &debouncer{}
|
|
|
|
return func(f func()) {
|
|
db.mu.Lock()
|
|
defer db.mu.Unlock()
|
|
|
|
if db.t != nil {
|
|
db.t.Stop()
|
|
}
|
|
var trigger *time.Timer
|
|
trigger = time.AfterFunc(d, func() {
|
|
db.mu.Lock()
|
|
defer db.mu.Unlock()
|
|
if trigger == db.t {
|
|
f()
|
|
db.t = nil
|
|
}
|
|
})
|
|
db.t = trigger
|
|
}
|
|
}
|