template<typename T, typename = void>
struct ultralight::js::ClassHolder< T, typename >
Type trait that selects the smart pointer type for owned instances of a bound class.
When an owned instance of a bound C++ class crosses the bridge to JavaScript, it travels in its canonical holder– the smart pointer that manages native ownership for that class.
This specialization sets std::shared_ptr as the holder for a bound Database class:
template <>
using type = std::shared_ptr<Database>;
};
Type trait that selects the smart pointer type for owned instances of a bound class.
Definition Holder.h:170
std::conditional_t< std::is_base_of_v< RefCounted, T >, RefPtr< T >, std::unique_ptr< T > > type
Definition Holder.h:171
Where the Holder Is Used
The library requires the canonical holder when transferring ownership across the bridge:
- Bound functions must return owned instances in the canonical holder. Returning an owned instance in any other smart pointer is a compile error.
- API::Emit() and Resolver::Resolve() require the canonical holder. Delivering an instance later during Renderer::Update() requires an owning smart pointer rather than a borrowed raw pointer.
Supported Holder Types
By default, type is RefPtr for a class that derives from RefCounted, or std::unique_ptr for any other class. You can specialize ClassHolder to select any smart pointer that matches your ownership model:
- Use std::shared_ptr for shared ownership. Native code and the JavaScript wrapper share ownership of non-RefCounted objects.
- Use js::Eternal for program-lifetime objects. Singletons and subsystems wrapped in js::Eternal are never destroyed by the library or the page.
- Use a custom smart pointer with HolderTraits. Specialize ultralight::HolderTraits for your smart pointer type before specializing ClassHolder.
- Note
- Declare the specialization in the header that defines the class, so every file that binds or converts the class uses the same holder type.
- Note
- ClassBuilder::Constructor() works only when the canonical holder is RefPtr, std::unique_ptr, or std::shared_ptr. For another holder (such as js::Eternal), bind a static factory method with ClassBuilder::StaticMethod() that returns the holder instead.
- See also
- js::ClassBuilder, ultralight::HolderTraits, js::Eternal, js::Detach()