// Copyright 2020 The Ebiten Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //go:build ebitenginedebug || ebitendebug package debug import ( "fmt" "sync" ) const IsDebug = true var theLogger = &logger{} var flushM sync.Mutex // Logf calls the current global logger's Logf. // Logf buffers the arguments and doesn't dump the log immediately. // You can dump logs by calling SwitchLogger and Flush. // // Logf is not concurrent safe. func Logf(format string, args ...any) { theLogger.Logf(format, args...) } // SwitchLogger sets a new logger as the current logger and returns the original global logger. // The new global logger and the returned logger have separate statuses, so you can use them for different goroutines. // // SwitchLogger and a returned Logger are not concurrent safe. func SwitchLogger() Logger { current := theLogger theLogger = &logger{} return current } type logger struct { items []logItem } type logItem struct { format string args []any } func (l *logger) Logf(format string, args ...any) { l.items = append(l.items, logItem{ format: format, args: args, }) } func (l *logger) Flush() { // Flushing is protected by a mutex not to mix another logger's logs. flushM.Lock() defer flushM.Unlock() for i, item := range l.items { fmt.Printf(item.format, item.args...) l.items[i] = logItem{} } l.items = l.items[:0] }