Lightgraph
C++17 light-graph engine API reference
Loading...
Searching...
No Matches
drawing_presentation.hpp
Go to the documentation of this file.
1#ifndef LIGHTGRAPH_INTEGRATION_DRAWING_PRESENTATION_HPP
2#define LIGHTGRAPH_INTEGRATION_DRAWING_PRESENTATION_HPP
3
4#pragma once
5#include "drawing.hpp"
6
8
9// Serialized by the runtime's owner. Owns handles, never scene/image storage.
11 public:
12 static constexpr std::size_t capacity = 3;
17
18 void bind(DrawingRuntime& runtime) {
19 const auto generation = runtime.status().generation;
20 if (runtime_ != &runtime || lifetime_.expired() || generation_ != generation) {
21 reset();
22 runtime_ = &runtime;
23 lifetime_ = runtime.lifetime();
24 generation_ = generation;
25 }
26 }
27
28 bool enqueue(const DrawingHandle& handle) {
29 if (!synchronize() || !runtime_->validQueued(handle))
30 return false;
31 for (std::size_t i = 0; i < count_; ++i) {
32 const auto& entry = handles_[i];
33 if (entry.kind == handle.kind && entry.slot == handle.slot &&
34 entry.slotGeneration == handle.slotGeneration &&
35 entry.runtimeGeneration == handle.runtimeGeneration)
36 return true;
37 }
38 if (count_ == capacity) {
39 runtime_->releaseQueued(handle);
40 runtime_->reject("performance_queue_full");
41 return false;
42 }
43 handles_[count_++] = handle;
44 if (!blocked_)
45 drain();
46 return true;
47 }
48
49 // Call once per owner-loop iteration. Busy keeps FIFO ownership for retry.
50 DrawingResult poll() {
51 if (!synchronize())
52 return DrawingResult::Stale;
53 blocked_ = false;
54 return drain();
55 }
56
57 void reset() {
58 if (runtime_ && !lifetime_.expired()) {
59 for (std::size_t i = 0; i < count_; ++i)
60 runtime_->releaseQueued(handles_[i]);
61 }
62 count_ = 0;
63 blocked_ = false;
64 runtime_ = nullptr;
65 lifetime_.reset();
66 generation_ = {};
67 }
68 std::size_t size() const { return count_; }
69
70 private:
71 DrawingResult drain() {
72 DrawingResult result = DrawingResult::NoChange;
73 while (count_ != 0) {
74 result = runtime_->applyQueued(handles_[0]);
75 if (result == DrawingResult::Busy) {
76 blocked_ = true;
77 return result;
78 }
79 if (result != DrawingResult::Applied && result != DrawingResult::NoChange)
80 runtime_->releaseQueued(handles_[0]);
81 for (std::size_t i = 1; i < count_; ++i)
82 handles_[i - 1] = handles_[i];
83 --count_;
84 }
85 return result;
86 }
87
88 bool synchronize() {
89 if (!runtime_ || lifetime_.expired()) {
90 reset();
91 return false;
92 }
93 if (runtime_->status().generation != generation_) {
94 reset();
95 return false;
96 }
97 // Core fallback or explicit release can retire slots without changing generation.
98 std::size_t live = 0;
99 for (std::size_t i = 0; i < count_; ++i) {
100 if (runtime_->validQueued(handles_[i]))
101 handles_[live++] = handles_[i];
102 }
103 count_ = live;
104 if (count_ == 0)
105 blocked_ = false;
106 return true;
107 }
108 DrawingRuntime* runtime_ = nullptr;
109 DrawingRuntime::Lifetime lifetime_;
110 std::array<char, 17> generation_{};
111 std::array<DrawingHandle, capacity> handles_{};
112 std::size_t count_ = 0;
113 bool blocked_ = false;
114};
115
116} // namespace lightgraph::integration
117#endif
PendingDrawingPresentation & operator=(const PendingDrawingPresentation &)=delete
PendingDrawingPresentation(const PendingDrawingPresentation &)=delete