log.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package gdnative
  2. /*
  3. #include <gdnative/string.h>
  4. #include <gdnative/gdnative.h>
  5. #include "gdnative.gen.h"
  6. */
  7. import "C"
  8. import (
  9. "bytes"
  10. "fmt"
  11. "runtime"
  12. "strings"
  13. wchar "github.com/vitaminwater/cgo.wchar"
  14. )
  15. // Log is used to log messages to Godot, and makes them viewable inside the
  16. // Godot debugger.
  17. var Log = &Logger{StackNum: 2}
  18. // Logger is a native Go structure for logging in Godot.
  19. type Logger struct {
  20. // StackNum is how far up the stack logs should show up as.
  21. StackNum int
  22. }
  23. // Println will print the given message to the Godot debugger and console.
  24. func (l *Logger) Println(message ...interface{}) {
  25. GDNative.checkInit()
  26. // Convert our message into a Go string.
  27. goString := fmt.Sprint(message...)
  28. // Convert the go string into a godot string
  29. gdString := stringAsGodotString(goString)
  30. // Print our string.
  31. C.go_godot_print(GDNative.api, gdString)
  32. // Free the string from memory.
  33. C.go_godot_string_destroy(GDNative.api, gdString)
  34. }
  35. // Warning will print a warning message to the Godot debugger and console.
  36. func (l *Logger) Warning(message ...interface{}) {
  37. GDNative.checkInit()
  38. l.log(false, message...)
  39. }
  40. // Error will print an error message to the Godot debugger and console.
  41. func (l *Logger) Error(message ...interface{}) {
  42. GDNative.checkInit()
  43. l.log(true, message...)
  44. }
  45. // Write will call Logger.Println from the given bytes, to implement the io.Writer
  46. // interface.
  47. func (l *Logger) Write(data []byte) (int, error) {
  48. GDNative.checkInit()
  49. buffer := bytes.NewBuffer(data)
  50. line := strings.TrimRight(buffer.String(), "\n")
  51. l.Println(line)
  52. return len(data), nil
  53. }
  54. // log is a helper function that will log either Warnings or Errors in Godot.
  55. func (l *Logger) log(isError bool, message ...interface{}) {
  56. // Convert the messages into a Go string.
  57. goDescription := fmt.Sprint(message...)
  58. // Get the caller filename and line number.
  59. pc, file, no, ok := runtime.Caller(l.StackNum)
  60. if !ok {
  61. fmt.Println("Unable to get caller!")
  62. return
  63. }
  64. // Get the function name.
  65. funcName := "unknown"
  66. details := runtime.FuncForPC(pc)
  67. if details != nil {
  68. funcName = details.Name()
  69. }
  70. // Convert the go string into a C string
  71. cDescription := C.CString(goDescription)
  72. cFuncName := C.CString(funcName)
  73. cFile := C.CString(file)
  74. cLine := C.int(no)
  75. if isError {
  76. C.go_godot_print_error(GDNative.api, cDescription, cFuncName, cFile, cLine)
  77. return
  78. }
  79. C.go_godot_print_warning(GDNative.api, cDescription, cFuncName, cFile, cLine)
  80. }
  81. func stringAsGodotString(value string) *C.godot_string {
  82. var godotString C.godot_string
  83. if value == "" {
  84. C.go_godot_string_new(GDNative.api, &godotString)
  85. return &godotString
  86. }
  87. // Convert the Go string into a wchar
  88. wcharString, err := wchar.FromGoString(value)
  89. if err != nil {
  90. fmt.Println("Error decoding string '"+value+"': ", err)
  91. C.go_godot_string_new(GDNative.api, &godotString)
  92. return &godotString
  93. }
  94. // Build the Godot string with the wchar
  95. C.go_godot_string_new_with_wide_string(
  96. GDNative.api,
  97. &godotString,
  98. (*C.wchar_t)(wcharString.Pointer()),
  99. C.int(len(value)),
  100. )
  101. return &godotString
  102. }