| // Copyright 2023 Google LLC | |
| // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | |
| #ifndef EventQueue_DEFINED | |
| #define EventQueue_DEFINED | |
| #include "include/core/SkSpan.h" | |
| #include "modules/bentleyottmann/include/EventQueueInterface.h" | |
| #include "modules/bentleyottmann/include/Point.h" | |
| #include "modules/bentleyottmann/include/Segment.h" | |
| #include <optional> | |
| #include <set> | |
| #include <tuple> | |
| #include <variant> | |
| #include <vector> | |
| namespace bentleyottmann { | |
| struct Lower { | |
| // All Lowers are equal. | |
| friend bool operator< (const Lower&, const Lower&) { | |
| return false; | |
| } | |
| }; | |
| struct Upper { | |
| Segment s; | |
| // Arbitrary comparison for queue uniqueness. | |
| friend bool operator< (const Upper& u0, const Upper& u1) { | |
| return std::tie(u0.s.p0, u0.s.p1) < std::tie(u1.s.p0, u1.s.p1); | |
| } | |
| }; | |
| struct Cross { | |
| Segment s0; | |
| Segment s1; | |
| // Arbitrary comparison for queue uniqueness. | |
| friend bool operator< (const Cross& c0, const Cross& c1) { | |
| return std::tie(c0.s0.p0, c0.s0.p1, c0.s1.p0, c0.s1.p1) < | |
| std::tie(c1.s0.p0, c1.s0.p1, c1.s1.p0, c1.s1.p1); | |
| } | |
| }; | |
| using EventType = std::variant<Lower, Cross, Upper>; | |
| struct Event { | |
| Point where; | |
| EventType type; | |
| friend bool operator< (const Event& e0, const Event& e1) { | |
| return std::tie(e0.where, e0.type) < std::tie(e1.where, e1.type); | |
| } | |
| }; | |
| class EventQueue : public EventQueueInterface { | |
| public: | |
| // Queue ordered by Event where the point is the most important followed by type and then | |
| // contents of the event. The ordering of the contents of the event is arbitrary but need to | |
| // enforce uniqueness of the events in the queue. | |
| using Queue = std::set<Event>; | |
| static std::optional<EventQueue> Make(SkSpan<const Segment> segments); | |
| explicit EventQueue(Queue&& queue); | |
| EventQueue() = default; | |
| void addCrossing(Point crossingPoint, const Segment& s0, const Segment& s1) override; | |
| bool hasMoreEvents() const; | |
| void handleNextEventPoint(SweepLineInterface* handler); | |
| std::vector<Crossing> crossings(); | |
| private: | |
| friend class EventQueueTestingPeer; | |
| Point fLastEventPoint = Point::Smallest(); | |
| void add(const Event& e); | |
| DeletionSegmentSet fDeletionSet; | |
| InsertionSegmentSet fInsertionSet; | |
| Queue fQueue; | |
| std::vector<Crossing> fCrossings; | |
| }; | |
| } // namespace bentleyottmann | |
| #endif // EventQueue_DEFINED |