6#include <Ultralight/CAPI/CAPI_JSAPI.h>
7#include <Ultralight/CAPI/CAPI_JSClass.h>
8#include <Ultralight/detail/Exceptions.h>
126 : resolver_(std::exchange(other.resolver_,
nullptr)),
127 protected_(other.protected_.exchange(
nullptr)) {}
134 if (
this != &other) {
135 ulDestroyJSPromiseResolver(resolver_);
137 resolver_ = std::exchange(other.resolver_,
nullptr);
138 protected_.store(other.protected_.exchange(
nullptr));
150 ulDestroyJSPromiseResolver(resolver_);
157 explicit operator bool()
const {
return resolver_ !=
nullptr; }
165 ulJSPromiseResolverComplete(resolver_, &UndefinedThunk,
nullptr,
nullptr);
178 template <
typename T>
181 static_assert(!detail::kIsClassInstancePointer<T>,
182 "a raw instance pointer cannot cross a deferred boundary (delivery "
183 "happens later, on the Renderer's thread): capture an owning holder (the "
184 "class's canonical holder) or js::Eternal<T> instead");
185 static_assert(!detail::IsCallScopedView<std::decay_t<T>>::value,
186 "a std::span cannot cross a deferred boundary (delivery happens later; "
187 "the view would dangle): copy into a std::vector<E> or RefPtr<Buffer>");
188 using Stored = detail::CapturedArg<T>;
189 auto* payload =
new Stored(detail::CaptureArg(std::forward<T>(value)));
190 ulJSPromiseResolverComplete(resolver_, &ResolveThunk<Stored>, payload,
191 &DeletePayload<Stored>);
203 auto* payload =
new Error(std::move(error));
204 ulJSPromiseResolverComplete(resolver_, &RejectThunk, payload, &DeletePayload<Error>);
216 ULJSPromiseResolver
raw()
const {
return resolver_; }
227 ULJSPromiseResolver handle = resolver_;
233 explicit Resolver(ULJSPromiseResolver handle) : resolver_(handle) {}
235 static ULJSValue UndefinedThunk(
void*,
ULJSContext, ULJSValue*) {
return nullptr; }
239 template <
typename Stored>
240 static ULJSValue ResolveThunk(
void* user_data,
ULJSContext ctx, ULJSValue* exception) {
241 ULJSValue result =
nullptr;
242 ultralight::detail::CallCatchingExceptions(
243 [&] { result = TypeTraits<Stored>::ToJS(ctx, *
static_cast<Stored*
>(user_data)); },
244 [&](
const char* what) {
246 *exception = detail::NativeExceptionError(
nullptr, what).ToJS(ctx);
251 static ULJSValue RejectThunk(
void* user_data,
ULJSContext ctx, ULJSValue* exception) {
252 ultralight::detail::CallCatchingExceptions(
253 [&] { *exception =
static_cast<Error*
>(user_data)->
ToJS(ctx); },
254 [&](
const char* what) {
255 *exception = detail::NativeExceptionError(
nullptr, what).ToJS(ctx);
260 template <
typename Stored>
261 static void DeletePayload(
void* user_data) {
262 delete static_cast<Stored*
>(user_data);
265 friend struct detail::ResolverAccess;
271 void ReleaseProtection()
const { ulJSObjectUnprotectInstance(protected_.exchange(
nullptr)); }
273 ULJSPromiseResolver resolver_ =
nullptr;
274 mutable std::atomic<ULJSProtectedInstance> protected_ {
nullptr };
struct C_JSContext * ULJSContext
Opaque handle to a JavaScript execution context (one page's script world in one View).
Definition View.h:25
An error from a JavaScript operation.
Definition Error.h:115
Error(Error &&other) noexcept
Move constructor (other no longer holds the exception).
Definition Error.h:175
ULJSPromiseResolver raw() const
Get the C API handle without transferring ownership (this Resolver still destroys it).
Definition Resolver.h:216
static Resolver Adopt(ULJSPromiseResolver handle)
Take ownership of a resolver handle from the C API.
Definition Resolver.h:120
void Resolve() const
Resolve the Promise with undefined.
Definition Resolver.h:164
Resolver & operator=(const Resolver &)=delete
void Resolve(T &&value) const
Resolve the Promise with a value.
Definition Resolver.h:180
Resolver(Resolver &&other) noexcept
Move constructor (other becomes empty).
Definition Resolver.h:125
ULJSPromiseResolver LeakRef()
Give up ownership of the C API handle and return it.
Definition Resolver.h:226
void Reject(Error error) const
Reject the Promise with an error.
Definition Resolver.h:202
Resolver(const Resolver &)=delete
~Resolver()
Destructor (rejects the Promise if it hasn't been settled).
Definition Resolver.h:149
Resolver & operator=(Resolver &&other) noexcept
Move assignment (other becomes empty).
Definition Resolver.h:133
Resolver()=default
Create an empty Resolver (Resolve() and Reject() do nothing).
Whether or not js::TypeTraits can convert T (ignoring const, volatile, and references).
Definition TypeTraits.h:275
js::Value ToJS(const js::Context &context, const Element &element)
Get an element's JavaScript object (the same object the page's scripts see for it).
Definition JSInterop.h:97
Type-checked JavaScript bridge between C++ and web pages.
Definition JSInterop.h:141
Root namespace for every public Ultralight type, function, and enumeration.
@ Error
Error icon.
Definition Dialogs.h:57