Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

158 řádky
3.2KB

  1. package template
  2. import (
  3. "errors"
  4. "git.wtrh.nl/patterns/gopatterns/pkg/util"
  5. "git.wtrh.nl/patterns/gopatterns/pkg/path"
  6. "git.wtrh.nl/patterns/gopatterns/pkg/pattern"
  7. "git.wtrh.nl/patterns/gopatterns/pkg/point"
  8. )
  9. var ErrLineNotFound = errors.New("required path not found")
  10. // Lines contain named lines.
  11. type Lines map[util.ID]Line
  12. // Line describes a pattern line.
  13. type Line struct {
  14. Through []util.ID `yaml:"through"`
  15. Curve *Curve `yaml:"curve,omitempty"`
  16. Style *Style `yaml:"style,omitempty"`
  17. }
  18. type Style struct {
  19. Thickness *float64 `yaml:"thickness,omitempty"`
  20. }
  21. // Curve describes if a Line curves and if it has start and end constraints.
  22. type Curve struct {
  23. Start util.ID `yaml:"start,omitempty"`
  24. End util.ID `yaml:"end,omitempty"`
  25. }
  26. func (t Template) templateLine(panelName string, id util.ID) (Line, error) {
  27. if id.Panel() != "" {
  28. panelName = id.Panel()
  29. }
  30. panel, err := t.Panel(panelName)
  31. if !errors.Is(err, ErrPanelNotFound) {
  32. l, ok := panel.Lines[id.Deref()]
  33. if ok {
  34. return l, nil
  35. }
  36. }
  37. line, ok := t.Lines[id.Deref()]
  38. if !ok {
  39. return Line{}, ErrLineNotFound
  40. }
  41. return line, nil
  42. }
  43. func (t Template) getOrCreateLine(id util.ID, req request, depth int) (path.Path, error) {
  44. l, ok := req.lines[id]
  45. if ok {
  46. return l, nil
  47. }
  48. newLine, err := t.createLine(id, req, depth+1)
  49. if err != nil {
  50. return nil, err
  51. }
  52. req.lines[util.ID(id)] = newLine
  53. return newLine, nil
  54. }
  55. func (t Template) createLine(id util.ID, req request, depth int) (path.Path, error) {
  56. line, err := t.templateLine(req.name, id)
  57. if err != nil {
  58. return nil, err
  59. }
  60. throughPoints, err := t.getOrCreatePoints(line.Through, req, depth+1)
  61. if err != nil {
  62. return nil, err
  63. }
  64. style := path.NewDefaultStyle()
  65. if line.Style != nil && line.Style.Thickness != nil {
  66. style.Thickness = *line.Style.Thickness
  67. }
  68. switch {
  69. case line.Curve != nil:
  70. var start, end point.Point
  71. if line.Curve.Start != "" {
  72. start, err = t.getOrCreatePoint(line.Curve.Start, req, depth+1)
  73. if err != nil {
  74. return nil, err
  75. }
  76. }
  77. if line.Curve.End != "" {
  78. end, err = t.getOrCreatePoint(line.Curve.End, req, depth+1)
  79. if err != nil {
  80. return nil, err
  81. }
  82. }
  83. return path.NewSpline(path.SplineOpts{
  84. Start: start,
  85. End: end,
  86. Points: throughPoints,
  87. Style: style,
  88. ID: util.ID(id),
  89. }), nil
  90. default:
  91. return path.NewPolygon(throughPoints, style, util.ID(id)), nil
  92. }
  93. }
  94. // Build adds the line to the provided [pattern.Pattern].
  95. func (l Line) Build(pat *pattern.Pattern) error {
  96. points := pat.GetPoints(l.Through)
  97. for _, p := range points {
  98. p.SetDraw()
  99. }
  100. style := path.NewDefaultStyle()
  101. if l.Style != nil && l.Style.Thickness != nil {
  102. style.Thickness = *l.Style.Thickness
  103. }
  104. switch {
  105. case l.Curve != nil:
  106. pat.AddLine(
  107. path.NewSpline(path.SplineOpts{
  108. Start: pat.GetPoint(l.Curve.Start),
  109. End: pat.GetPoint(l.Curve.End),
  110. Points: points,
  111. Style: style,
  112. }),
  113. )
  114. default:
  115. pat.AddLine(path.NewPolygon(points, style, ""))
  116. }
  117. return nil
  118. }
  119. // Build adds all the lines to the provided [pattern.Pattern].
  120. func (l Lines) Build(pat *pattern.Pattern) error {
  121. for _, line := range l {
  122. err := line.Build(pat)
  123. if err != nil {
  124. return err
  125. }
  126. }
  127. return nil
  128. }