Fix "cross" detection on firing in some cases

Fixes #578
This commit is contained in:
tidwall 2020-09-22 16:19:49 -07:00
parent bd572b0d38
commit b47187349b
1 changed files with 38 additions and 26 deletions

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math"
"net" "net"
"os" "os"
"sort" "sort"
@ -14,7 +15,7 @@ import (
"time" "time"
"github.com/tidwall/buntdb" "github.com/tidwall/buntdb"
"github.com/tidwall/geojson" "github.com/tidwall/geojson/geometry"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/tidwall/redcon" "github.com/tidwall/redcon"
"github.com/tidwall/resp" "github.com/tidwall/resp"
@ -213,33 +214,44 @@ func (s *Server) getQueueCandidates(d *commandDetails) []*Hook {
} }
} }
// search the hook spatial tree // search the hook spatial tree
for _, obj := range []geojson.Object{d.obj, d.oldObj} { // build a rectangle that fills the old and new which will be enough to
if obj == nil { // handle "enter", "inside", "exit", and "cross" detections.
continue var rect geometry.Rect
if d.oldObj != nil {
rect = d.oldObj.Rect()
if d.obj != nil {
r2 := d.obj.Rect()
rect.Min.X = math.Min(rect.Min.X, r2.Min.X)
rect.Min.Y = math.Min(rect.Min.Y, r2.Min.Y)
rect.Max.X = math.Max(rect.Max.X, r2.Max.X)
rect.Max.Y = math.Max(rect.Max.Y, r2.Max.Y)
} }
rect := obj.Rect() } else if d.obj != nil {
s.hookTree.Search( rect = d.obj.Rect()
[2]float64{rect.Min.X, rect.Min.Y}, } else {
[2]float64{rect.Max.X, rect.Max.Y}, return candidates
func(_, _ [2]float64, value interface{}) bool {
hook := value.(*Hook)
if hook.Key != d.key {
return true
}
var found bool
for _, candidate := range candidates {
if candidate == hook {
found = true
break
}
}
if !found {
candidates = append(candidates, hook)
}
return true
},
)
} }
s.hookTree.Search(
[2]float64{rect.Min.X, rect.Min.Y},
[2]float64{rect.Max.X, rect.Max.Y},
func(_, _ [2]float64, value interface{}) bool {
hook := value.(*Hook)
if hook.Key != d.key {
return true
}
var found bool
for _, candidate := range candidates {
if candidate == hook {
found = true
break
}
}
if !found {
candidates = append(candidates, hook)
}
return true
},
)
return candidates return candidates
} }