table.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package stats
  2. import (
  3. "fmt"
  4. "runtime"
  5. "time"
  6. "github.com/g3n/engine/gls"
  7. "github.com/g3n/engine/gui"
  8. )
  9. type StatsTable struct {
  10. *gui.Table // embedded table
  11. fields []*field // array of fields
  12. prev gls.Stats
  13. frames int
  14. cgocalls int64
  15. last time.Time
  16. }
  17. type field struct {
  18. id string
  19. row int
  20. }
  21. func NewStatsTable(width, height float32) *StatsTable {
  22. s := new(StatsTable)
  23. t, err := gui.NewTable(width, height, []gui.TableColumn{
  24. {Id: "f", Header: "Stat", Width: 50, Minwidth: 32, Align: gui.AlignRight, Format: "%s", Resize: true, Expand: 1.5},
  25. {Id: "v", Header: "Value", Width: 50, Minwidth: 32, Align: gui.AlignRight, Format: "%d", Resize: false, Expand: 1},
  26. })
  27. if err != nil {
  28. panic(err)
  29. }
  30. s.Table = t
  31. s.ShowHeader(false)
  32. s.addRow("shaders", "Shaders:")
  33. s.addRow("vaos", "Vaos:")
  34. s.addRow("vbos", "Vbos:")
  35. s.addRow("textures", "Textures:")
  36. s.addRow("unisets", "Uniforms/frame:")
  37. s.addRow("cgocalls", "CGO calls/frame:")
  38. s.last = time.Now()
  39. s.cgocalls = runtime.NumCgoCall()
  40. return s
  41. }
  42. func (s *StatsTable) Update(gs *gls.GLS, d time.Duration) {
  43. now := time.Now()
  44. s.frames++
  45. if s.last.Add(d).After(now) {
  46. return
  47. }
  48. s.update(gs)
  49. s.last = now
  50. s.frames = 0
  51. }
  52. func (s *StatsTable) update(gs *gls.GLS) {
  53. var stats gls.Stats
  54. gs.Stats(&stats)
  55. for i := 0; i < len(s.fields); i++ {
  56. f := s.fields[i]
  57. switch f.id {
  58. case "shaders":
  59. if stats.Shaders != s.prev.Shaders {
  60. s.Table.SetCell(f.row, "v", stats.Shaders)
  61. fmt.Println("update")
  62. }
  63. case "vaos":
  64. if stats.Vaos != s.prev.Vaos {
  65. s.Table.SetCell(f.row, "v", stats.Vaos)
  66. fmt.Println("update")
  67. }
  68. case "vbos":
  69. if stats.Vbos != s.prev.Vbos {
  70. s.Table.SetCell(f.row, "v", stats.Vbos)
  71. fmt.Println("update")
  72. }
  73. case "textures":
  74. if stats.Textures != s.prev.Textures {
  75. s.Table.SetCell(f.row, "v", stats.Textures)
  76. fmt.Println("update")
  77. }
  78. case "cgocalls":
  79. current := runtime.NumCgoCall()
  80. calls := current - s.cgocalls
  81. s.Table.SetCell(f.row, "v", int(float64(calls)/float64(s.frames)))
  82. s.cgocalls = current
  83. }
  84. }
  85. s.prev = stats
  86. }
  87. func (s *StatsTable) addRow(id, label string) {
  88. f := new(field)
  89. f.id = id
  90. f.row = s.Table.RowCount()
  91. s.Table.AddRow(map[string]interface{}{"f": label, "v": 0})
  92. s.fields = append(s.fields, f)
  93. }