#1 Fix panic on evaluate functions

Birleştirildi
wouter 1 yıl önce fix-panic-on-evaluate-functions içindeki 1 işleme master ile birleştirdi
  1. +42
    -32
      pkg/pattern/template/point.go

+ 42
- 32
pkg/pattern/template/point.go Dosyayı Görüntüle

@@ -19,6 +19,8 @@ var (

// ErrRelativePointRecursion is returned when a points are relative to itself.
ErrRelativePointRecursion = errors.New("point cannot be relative to itself")

ErrInvalidArguments = errors.New("invalid arguments to call function")
)

// Points contains a map with points.
@@ -40,52 +42,50 @@ var ErrInvalidPointID = errors.New("type cannot be converted to a PointID")
func (p Points) Functions(pat *pattern.Pattern) map[string]govaluate.ExpressionFunction {
return map[string]govaluate.ExpressionFunction{
"DistanceBetween": func(args ...interface{}) (interface{}, error) {
id0, err := toPointID(args[0])
if err != nil {
return nil, fmt.Errorf("parsing args[0] to pointID: %w", err)
}

id1, err := toPointID(args[1])
if err != nil {
return nil, fmt.Errorf("parsing args[0] to pointID: %w", err)
}

p0, err := p.getOrCreate(id0, pat, 0)
if err != nil {
return nil, fmt.Errorf("get or create point %q: %w", id0, err)
if len(args) != 2 {
return nil, fmt.Errorf("function DistanceBetween() requires 2 arguments: %w",
ErrInvalidArguments)
}

p1, err := p.getOrCreate(id1, pat, 0)
points, err := p.getOrCreateFromArgs(pat, args...)
if err != nil {
return nil, fmt.Errorf("get or create point %q: %w", id1, err)
return nil, err
}

return p0.Position().Distance(p1.Position()), nil
return points[0].Position().Distance(points[1].Position()), nil
},
"AngleBetween": func(args ...interface{}) (interface{}, error) {
id0, err := toPointID(args[0])
if err != nil {
return nil, fmt.Errorf("parsing args[0] to pointID: %w", err)
if len(args) != 2 {
return nil, fmt.Errorf("function AngleBetween() requires 2 arguments: %w",
ErrInvalidArguments)
}

id1, err := toPointID(args[1])
points, err := p.getOrCreateFromArgs(pat, args...)
if err != nil {
return nil, fmt.Errorf("parsing args[0] to pointID: %w", err)
return nil, err
}

p0, err := p.getOrCreate(id0, pat, 0)
if err != nil {
return nil, fmt.Errorf("get or create point %q: %w", id0, err)
}
return points[0].Vector().AngleBetween(points[1].Vector()), nil
},
}
}

p1, err := p.getOrCreate(id1, pat, 0)
if err != nil {
return nil, fmt.Errorf("get or create point %q: %w", id1, err)
}
func (p Points) getOrCreateFromArgs(pat *pattern.Pattern, args ...interface{}) ([]point.Point, error) {
points := make([]point.Point, 0, len(args))
for i, arg := range args {
id, err := toPointID(arg)
if err != nil {
return nil, fmt.Errorf("parsing args[%d] to pointID: %w", i, err)
}

return p0.Vector().AngleBetween(p1.Vector()), nil
},
newPoint, err := p.getOrCreate(id, pat, 0)
if err != nil {
return nil, fmt.Errorf("get or create point %q: %w", id, err)
}

points = append(points, newPoint)
}

return points, nil
}

func toPointID(arg interface{}) (point.ID, error) {
@@ -111,9 +111,19 @@ type BetweenPoint struct {
func (p Points) evaluationFunctions() map[string]govaluate.ExpressionFunction {
return map[string]govaluate.ExpressionFunction{
"acos": func(args ...interface{}) (interface{}, error) {
if len(args) != 1 {
return nil, fmt.Errorf("function acos() requires 1 argument: %w",
ErrInvalidArguments)
}

return math.Acos(args[0].(float64)), nil
},
"atan2": func(args ...interface{}) (interface{}, error) {
if len(args) != 2 {
return nil, fmt.Errorf("function atan2() requires 2 arguments: %w",
ErrInvalidArguments)
}

return math.Atan2(args[0].(float64), args[1].(float64)), nil
},
}


Yükleniyor…
İptal
Kaydet