FastLED 3.9.15
Loading...
Searching...
No Matches
promise.h
Go to the documentation of this file.
1#pragma once
2
27
28#include "fl/stl/function.h"
29#include "fl/stl/string.h"
30#include "fl/stl/shared_ptr.h"
31#include "fl/stl/move.h"
32#include "fl/stl/atomic.h"
33#include "fl/stl/noexcept.h"
34
35namespace fl {
36namespace task {
37
39struct Error {
41
42 Error() FL_NOEXCEPT = default;
43 Error(const fl::string& msg) FL_NOEXCEPT : message(msg) {}
44 Error(const char* msg) FL_NOEXCEPT : message(msg) {}
46 bool is_empty() const FL_NOEXCEPT { return message.empty(); }
47};
48
49// Forward declaration for implementation
50namespace detail {
51 template<typename T>
52 class PromiseImpl;
53}
54
57template<typename T>
58class Promise {
59public:
63 return Promise<T>(impl);
64 }
65
67 static Promise<T> resolve(const T& value) FL_NOEXCEPT { // okay static in header
68 auto p = create();
69 p.complete_with_value(value);
70 return p;
71 }
72
74 static Promise<T> resolve(T&& value) FL_NOEXCEPT { // okay static in header
75 auto p = create();
76 p.complete_with_value(fl::move(value));
77 return p;
78 }
79
81 static Promise<T> reject(const Error& error) FL_NOEXCEPT { // okay static in header
82 auto p = create();
83 p.complete_with_error(error);
84 return p;
85 }
86
88 static Promise<T> reject(const fl::string& error_message) FL_NOEXCEPT { // okay static in header
89 return reject(Error(error_message));
90 }
91
93 Promise() FL_NOEXCEPT : mImpl(nullptr) {}
94
96 Promise(const Promise& other) = default;
97
99 Promise(Promise&& other) FL_NOEXCEPT = default;
100
102 Promise& operator=(const Promise& other) = default;
103
106
108 bool valid() const FL_NOEXCEPT {
109 return mImpl != nullptr;
110 }
111
115 Promise& then(fl::function<void(const T&)> callback) FL_NOEXCEPT {
116 if (!valid()) return *this;
117
118 mImpl->set_then_callback(fl::move(callback));
119 return *this;
120 }
121
125 Promise& catch_(fl::function<void(const Error&)> callback) FL_NOEXCEPT {
126 if (!valid()) return *this;
127
128 mImpl->set_catch_callback(fl::move(callback));
129 return *this;
130 }
131
135 if (!valid()) return;
136 mImpl->update();
137 }
138
141 if (!valid()) return false;
142 return mImpl->is_completed();
143 }
144
147 if (!valid()) return false;
148 return mImpl->is_resolved();
149 }
150
153 if (!valid()) return false;
154 return mImpl->is_rejected();
155 }
156
158 const T& value() const FL_NOEXCEPT {
159 if (!valid()) {
160 static const T default_value{};
161 return default_value;
162 }
163 return mImpl->value();
164 }
165
167 const Error& error() const FL_NOEXCEPT {
168 if (!valid()) {
169 static const Error default_error;
170 return default_error;
171 }
172 return mImpl->error();
173 }
174
177 mImpl.reset();
178 }
179
180 // ========== PRODUCER INTERFACE (INTERNAL USE) ==========
181
184 if (!valid()) return false;
185 return mImpl->resolve(value);
186 }
187
189 if (!valid()) return false;
190 return mImpl->resolve(fl::move(value));
191 }
192
195 if (!valid()) return false;
196 return mImpl->reject(error);
197 }
198
199 bool complete_with_error(const fl::string& error_message) FL_NOEXCEPT {
200 if (!valid()) return false;
201 return mImpl->reject(Error(error_message));
202 }
203
204private:
207
210};
211
213template<typename T>
217
219template<typename T>
221 return Promise<T>::reject(Error(error_message));
222}
223
225template<typename T>
226Promise<T> make_rejected_promise(const char* error_message) FL_NOEXCEPT {
227 return Promise<T>::reject(Error(error_message));
228}
229
230// ============================================================================
231// IMPLEMENTATION DETAILS
232// ============================================================================
233
234namespace detail {
235
237enum class PromiseState_t {
238 PENDING, // Promise is still pending
239 RESOLVED, // Promise completed successfully
240 REJECTED // Promise completed with error
241};
242
244template<typename T>
246public:
248
250 void set_then_callback(fl::function<void(const T&)> callback) FL_NOEXCEPT {
251 mThenCallback = fl::move(callback);
252 // If already resolved, process callback immediately
255 }
256 }
257
259 void set_catch_callback(fl::function<void(const Error&)> callback) FL_NOEXCEPT {
260 mCatchCallback = fl::move(callback);
261 // If already rejected, process callback immediately
264 }
265 }
266
269 // Process callbacks if we're completed and haven't processed them yet
272 }
273 }
274
276 bool resolve(const T& value) FL_NOEXCEPT {
277 if (state() != PromiseState_t::PENDING) return false;
278
279 // Write value BEFORE setting state — the atomic store provides
280 // a release fence so the reader sees the value after observing
281 // the state transition.
282 mValue = value;
284
285 // Process callback immediately if we have one
288 }
289
290 return true;
291 }
292
294 if (state() != PromiseState_t::PENDING) return false;
295
298
301 }
302
303 return true;
304 }
305
308 if (state() != PromiseState_t::PENDING) return false;
309
310 mError = error;
312
315 }
316
317 return true;
318 }
319
322 return state() != PromiseState_t::PENDING;
323 }
324
328 }
329
333 }
334
336 const T& value() const FL_NOEXCEPT {
337 return mValue;
338 }
339
341 const Error& error() const FL_NOEXCEPT {
342 return mError;
343 }
344
345private:
346 fl::atomic<int> mState; // stores PromiseState_t as int (atomics require integer type)
349
352
354
357 return static_cast<PromiseState_t>(mState.load());
358 }
359
362 mState.store(static_cast<int>(s));
363 }
364
367 if (mCallbacksProcessed) return;
368
369 PromiseState_t s = state();
372 } else if (s == PromiseState_t::REJECTED && mCatchCallback) {
374 }
375
376 mCallbacksProcessed = true;
377 }
378};
379
380} // namespace detail
381
382} // namespace task
383} // namespace fl
Promise & operator=(const Promise &other)=default
Copy assignment operator.
static Promise< T > reject(const fl::string &error_message) FL_NOEXCEPT
Create a rejected Promise with error message.
Definition promise.h:88
fl::shared_ptr< detail::PromiseImpl< T > > mImpl
Shared pointer to implementation - this allows copying and sharing Promise state.
Definition promise.h:209
bool is_completed() const FL_NOEXCEPT
Check if Promise is completed (resolved or rejected)
Definition promise.h:140
const T & value() const FL_NOEXCEPT
Get the result value (only valid if is_resolved() returns true)
Definition promise.h:158
Promise(fl::shared_ptr< detail::PromiseImpl< T > > impl) FL_NOEXCEPT
Constructor from shared implementation (used internally)
Definition promise.h:206
Promise(Promise &&other) FL_NOEXCEPT=default
Move constructor.
Promise() FL_NOEXCEPT
Default constructor - creates invalid Promise.
Definition promise.h:93
Promise & catch_(fl::function< void(const Error &)> callback) FL_NOEXCEPT
Register error callback - returns reference for chaining.
Definition promise.h:125
const Error & error() const FL_NOEXCEPT
Get the error (only valid if is_rejected() returns true)
Definition promise.h:167
Promise(const Promise &other)=default
Copy constructor (promises are now copyable via shared implementation)
bool is_rejected() const FL_NOEXCEPT
Check if Promise is rejected (completed with error)
Definition promise.h:152
bool complete_with_value(const T &value) FL_NOEXCEPT
Complete the Promise with a result (used by networking library)
Definition promise.h:183
Promise & then(fl::function< void(const T &)> callback) FL_NOEXCEPT
Register success callback - returns reference for chaining.
Definition promise.h:115
static Promise< T > resolve(const T &value) FL_NOEXCEPT
Create a resolved Promise with value.
Definition promise.h:67
static Promise< T > resolve(T &&value) FL_NOEXCEPT
Create a resolved Promise with value (move version)
Definition promise.h:74
static Promise< T > reject(const Error &error) FL_NOEXCEPT
Create a rejected Promise with error.
Definition promise.h:81
void clear() FL_NOEXCEPT
Clear Promise to invalid state.
Definition promise.h:176
static Promise< T > create() FL_NOEXCEPT
Create a pending Promise.
Definition promise.h:61
bool valid() const FL_NOEXCEPT
Check if Promise is valid.
Definition promise.h:108
bool complete_with_error(const Error &error) FL_NOEXCEPT
Complete the Promise with an error (used by networking library)
Definition promise.h:194
void update() FL_NOEXCEPT
Update Promise state in main loop - should be called periodically This processes pending callbacks wh...
Definition promise.h:134
Promise & operator=(Promise &&other) FL_NOEXCEPT=default
Move assignment operator.
bool complete_with_error(const fl::string &error_message) FL_NOEXCEPT
Definition promise.h:199
bool is_resolved() const FL_NOEXCEPT
Check if Promise is resolved (completed successfully)
Definition promise.h:146
bool complete_with_value(T &&value) FL_NOEXCEPT
Definition promise.h:188
Promise class that provides fluent .then() and .catch_() semantics This is a lightweight wrapper arou...
Definition promise.h:58
fl::atomic< int > mState
Definition promise.h:346
bool is_rejected() const FL_NOEXCEPT
Check if Promise is rejected.
Definition promise.h:331
const T & value() const FL_NOEXCEPT
Get value (only valid if resolved)
Definition promise.h:336
const Error & error() const FL_NOEXCEPT
Get error (only valid if rejected)
Definition promise.h:341
bool reject(const Error &error) FL_NOEXCEPT
Reject Promise with error.
Definition promise.h:307
void set_then_callback(fl::function< void(const T &)> callback) FL_NOEXCEPT
Set success callback.
Definition promise.h:250
fl::function< void(const Error &)> mCatchCallback
Definition promise.h:351
void update() FL_NOEXCEPT
Update Promise state - processes callbacks if needed.
Definition promise.h:268
void process_callbacks() FL_NOEXCEPT
Process pending callbacks.
Definition promise.h:366
void set_state(PromiseState_t s) FL_NOEXCEPT
Write the state atomically.
Definition promise.h:361
bool resolve(T &&value) FL_NOEXCEPT
Definition promise.h:293
bool resolve(const T &value) FL_NOEXCEPT
Resolve Promise with value.
Definition promise.h:276
fl::function< void(const T &)> mThenCallback
Definition promise.h:350
PromiseState_t state() const FL_NOEXCEPT
Read the state atomically.
Definition promise.h:356
bool is_completed() const FL_NOEXCEPT
Check if Promise is completed.
Definition promise.h:321
void set_catch_callback(fl::function< void(const Error &)> callback) FL_NOEXCEPT
Set error callback.
Definition promise.h:259
bool is_resolved() const FL_NOEXCEPT
Check if Promise is resolved.
Definition promise.h:326
Implementation class for Promise - holds the actual state and logic.
Definition promise.h:245
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_traits.h:48
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
PromiseState_t
State enumeration for promises.
Definition promise.h:237
Promise< T > make_resolved_promise(T value) FL_NOEXCEPT
Convenience function to create a resolved Promise.
Definition promise.h:214
Promise< T > make_rejected_promise(const fl::string &error_message) FL_NOEXCEPT
Convenience function to create a rejected Promise.
Definition promise.h:220
constexpr int type_rank< T >::value
AtomicFake< T > atomic
Definition atomic.h:26
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
Error(const char *msg) FL_NOEXCEPT
Definition promise.h:44
Error() FL_NOEXCEPT=default
bool is_empty() const FL_NOEXCEPT
Definition promise.h:46
fl::string message
Definition promise.h:40
Error(fl::string &&msg) FL_NOEXCEPT
Definition promise.h:45
Error type for promises.
Definition promise.h:39