Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Static Public Member Functions | List of all members
myers::EventQueue Class Reference

Public Member Functions

Event operator[] (size_t i) const
 
Iterator begin () const
 
Iterator end () const
 
size_t size () const
 
bool empty () const
 

Static Public Member Functions

static EventQueue Make (const SkSpan< const Segment > segments)
 

Detailed Description

Definition at line 232 of file Myers.cpp.

Member Function Documentation

◆ begin()

Iterator myers::EventQueue::begin ( ) const
inline

Definition at line 390 of file Myers.cpp.

390 {
391 return Iterator{*this, 0};
392 }

◆ empty()

bool myers::EventQueue::empty ( ) const
inline

Definition at line 402 of file Myers.cpp.

402 {
403 return fEvents.empty();
404 }

◆ end()

Iterator myers::EventQueue::end ( ) const
inline

Definition at line 394 of file Myers.cpp.

394 {
395 return Iterator{*this, fEvents.size()};
396 }

◆ Make()

static EventQueue myers::EventQueue::Make ( const SkSpan< const Segment segments)
inlinestatic

Definition at line 273 of file Myers.cpp.

273 {
274 SkASSERT(!segments.empty());
275 SkASSERT(segments.size() < INT32_MAX);
276
277 enum EventType {
278 kBegin = 0,
279 kHorizontal = 1,
280 kEnd = 2
281 };
282
283 // A vector of SetupTuple when ordered will produce the events, and all the different
284 // sets of segments (beginning, etc.).
285 struct SetupTuple {
286 // The main ordering of events.
287 int32_t yOrdering;
288
289 // Group together like event types together.
291
292 // Break ties if yOrdering is the same.
293 int32_t xTieBreaker;
294
295 // We want to sort the segments, but they are not part of the key.
296 Segment originalSegment;
297
298 bool operator==(const SetupTuple& r) const {
299 return
300 std::tie(this->yOrdering, this->type, this->xTieBreaker, this->originalSegment)
301 == std::tie(r.yOrdering, r.type, r.xTieBreaker, r.originalSegment);
302 }
303 };
304
305 std::vector<SetupTuple> eventOrdering;
306 for (const auto& s : segments) {
307
308 // Exclude zero length segments.
309 if (s.upper() == s.lower()) {
310 continue;
311 }
312
313 if (s.isHorizontal()) {
314 // Tag for the horizontal set.
315 eventOrdering.push_back(SetupTuple{s.upper().y, kHorizontal, -s.upper().x, s});
316 } else {
317 // Tag for the beginning and ending sets.
318 eventOrdering.push_back(SetupTuple{s.upper().y, kBegin, -s.upper().x, s});
319 eventOrdering.push_back(SetupTuple{s.lower().y, kEnd, -s.lower().x, s});
320 }
321 }
322
323 // Order the tuples by y, then by set type, then by x value.
324 auto eventLess = [](const SetupTuple& l, const SetupTuple& r) {
325 return std::tie(l.yOrdering, l.type, l.xTieBreaker) <
326 std::tie(r.yOrdering, r.type, r.xTieBreaker);
327 };
328
329 // Sort the events.
330 std::sort(eventOrdering.begin(), eventOrdering.end(), eventLess);
331
332 // Remove duplicate segments.
333 auto eraseFrom = std::unique(eventOrdering.begin(), eventOrdering.end());
334 eventOrdering.erase(eraseFrom, eventOrdering.end());
335
336 std::vector<CompactEvent> events;
337 std::vector<Segment> segmentStorage;
338 segmentStorage.reserve(eventOrdering.size());
339
340 int32_t currentY = eventOrdering.front().yOrdering;
341 int32_t start = 0,
342 endOfBegin = 0,
343 endOfHorizontal = 0,
344 endOfEnd = 0;
345 for (const auto& [y, type, _, s] : eventOrdering) {
346 // If this is a new y then create the compact event.
347 if (currentY != y) {
348 events.push_back(CompactEvent{currentY,
349 start,
350 endOfBegin,
351 endOfHorizontal,
352 endOfEnd});
353 start = endOfBegin = endOfHorizontal = endOfEnd = segmentStorage.size();
354 currentY = y;
355 }
356
357 segmentStorage.push_back(s);
358
359 // Increment the various set indices.
360 const size_t segmentCount = segmentStorage.size();
361 switch (type) {
362 case kBegin: endOfBegin = segmentCount;
363 [[fallthrough]];
364 case kHorizontal: endOfHorizontal = segmentCount;
365 [[fallthrough]];
366 case kEnd: endOfEnd = segmentCount;
367 }
368 }
369
370 // Store the last event.
371 events.push_back(CompactEvent{currentY,
372 start,
373 endOfBegin,
374 endOfHorizontal,
375 endOfEnd});
376
377 return EventQueue{std::move(events), std::move(segmentStorage)};
378 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
GLenum type
constexpr bool empty() const
Definition: SkSpan_impl.h:96
constexpr size_t size() const
Definition: SkSpan_impl.h:95
struct MyStruct s
double y
std::variant< Lower, Cross, Upper > EventType
Definition: EventQueue.h:47
constexpr bool operator==(const Point &p0, const Point &p1)
Definition: Myers.h:29

◆ operator[]()

Event myers::EventQueue::operator[] ( size_t  i) const
inline

Definition at line 380 of file Myers.cpp.

380 {
381 SkASSERT(i < fEvents.size());
382 auto& [y, start, endOfBegin, endOfHorizontal, endOfEnd] = fEvents[i];
383 SkSpan<const Segment> begin{&fSegmentStorage[start], endOfBegin - start};
385 horizontal{&fSegmentStorage[endOfBegin], endOfHorizontal - endOfBegin};
386 SkSpan<const Segment> end{&fSegmentStorage[endOfHorizontal], endOfEnd - endOfHorizontal};
387 return Event{y, begin, horizontal, end};
388 }
Iterator begin() const
Definition: Myers.cpp:390
Iterator end() const
Definition: Myers.cpp:394
Definition: dart.idl:641

◆ size()

size_t myers::EventQueue::size ( ) const
inline

Definition at line 398 of file Myers.cpp.

398 {
399 return fEvents.size();
400 }

The documentation for this class was generated from the following file: