Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to implement js_traits<std::unique_ptr>? #61

Closed
hc-tec opened this issue Jan 1, 2023 · 1 comment
Closed

How to implement js_traits<std::unique_ptr>? #61

hc-tec opened this issue Jan 1, 2023 · 1 comment

Comments

@hc-tec
Copy link

hc-tec commented Jan 1, 2023

There are some methods which return std::unique_ptr object in my program, while the program can't compile successly.
From the code of quickjspp.h, I find I must implement js_traits<std::unique_ptr> first, but I am not familiar with template.
So I am looking for helps for that.

@hc-tec
Copy link
Author

hc-tec commented Jan 13, 2023

With deeping into the source code these days, I know what js_traits do gradually.
js_traits::wrap is used to transform C++ object to JS object,js_traits::unwrap is used to transform JS object to C++ object.

The special of unique_ptr decides that there isn't a certain solution to solve this problem.
When we use unique_ptr to point our object, we own the ownership of this object.

My solution is to use a global map to manage the ownership of objects used in js_traits.

  • When we use js_traits::wrap, we should transfer object ownership from unique_ptr to the global map, then use js_traits<T*>::wrap to transfrom raw ptr to JS object.
  • When we use js_traits::unwrap, we should get object ownership back from the global map, return it to user.
template <class T>
struct js_traits<std::unique_ptr<T>> {

    static JSValue wrap(JSContext* ctx, std::unique_ptr<T> val) noexcept {
		T* raw_ptr = val.get();
                // transfer ownership to the global map which saves ownership temporately
		GetOwnershipMgr<T>()->ShiftOwner(std::move(val));
                // transform C++ object to JS object
		return js_traits<T*>::wrap(ctx, raw_ptr);
	}

    static std::unique_ptr<T> unwrap(JSContext* ctx, JSValueConst v)
    {
        std::unique_ptr<T> ptr = nullptr;
        if (JS_IsNull(v)) {
            return ptr;
        }
         // transform JS object to C++ object by js_traits<std::shared_ptr<T>>
        auto shared_ptr = js_traits<std::shared_ptr<T>>::unwrap(ctx, v);
        // get and return ownership to user from the global map
        return GetOwnershipMgr<T>()->GetOwner(shared_ptr.get());
    }
};

Above is just a simple thought to solve my problem, if you find some problems or better solutions, please feel free to comment.

@hc-tec hc-tec closed this as completed Jan 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant