blob: aae2e0c46b4db0e49b5e277393e863324834fe47 [file] [log] [blame] [edit]
// 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);
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