blob: 92f41fa90f7c10bb1112503bcaeb6f84798e89b5 [file] [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.
#include "modules/bentleyottmann/include/EventQueue.h"
namespace bentleyottmann {
// -- EventQueue -----------------------------------------------------------------------------------
std::optional<EventQueue> EventQueue::Make(SkSpan<const Segment> segments) {
Queue queue;
int32_t left = Point::Largest().x,
top = Point::Largest().y,
right = Point::Smallest().x,
bottom = Point::Smallest().y;
for(const Segment& s : segments) {
auto [l, t, r, b] = s.bounds();
left = std::min(l, left);
top = std::min(t, top);
right = std::max(r, right);
bottom = std::max(b, bottom);
queue.insert(Event{s.upper(), Upper{s}});
}
// If min max difference is too large, fail.
if (Point::DifferenceTooBig(Point{left, top}, Point{right, bottom})) {
return std::nullopt;
}
return EventQueue{std::move(queue)};
}
EventQueue::EventQueue(EventQueue::Queue&& queue) : fQueue{std::move(queue)} { }
void EventQueue::add(const Event& event) {
// New events must be up stream from the current event.
SkASSERT(!fQueue.empty() && fQueue.begin()->where < event.where);
auto [_, success] = fQueue.insert(event);
SkASSERT_RELEASE(success);
}
bool EventQueue::hasMoreEvents() const {
return !fQueue.empty();
}
Event EventQueue::nextEvent() {
SkASSERT(this->hasMoreEvents());
auto firstElement = fQueue.begin();
// Extract event at the beginning of the queue.
Event event = *firstElement;
// Remove the beginning element from the queue.
fQueue.erase(firstElement);
return event;
}
} // namespace bentleyottmann