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

Any idea for using SetHandler on class? #47

Open
Yangff opened this issue Jan 30, 2017 · 2 comments
Open

Any idea for using SetHandler on class? #47

Yangff opened this issue Jan 30, 2017 · 2 comments

Comments

@Yangff
Copy link

Yangff commented Jan 30, 2017

To achieve this, I added some code to class.hpp, so I can call klass.index<Type>() to make this class array-like. However I don't think it's an elegant way (my code)...

#define METHOD_CHECKER_ANY(fn, args) \
template<class C, typename=void> struct has_member_##fn : std::false_type {}; \
template<class C> struct has_member_##fn<C, typename std::enable_if< \
  !std::is_same<decltype(std::declval<C>().fn args)*, void>::value>::type> : std::true_type {};

METHOD_CHECKER_ANY(index_query, (0));
METHOD_CHECKER_ANY(index_set, (0, T1()));
METHOD_CHECKER_ANY(index_delete, (0));
METHOD_CHECKER_ANY(index_enum, ());

	template<class T1>
	static auto set_index_set(v8::IndexedPropertySetterCallback &indexset) -> typename std::enable_if_t<has_member_index_set<T>::value> {
		indexset = [](uint32_t index, v8::Local<v8::Value> value, v8::PropertyCallbackInfo <v8::Value> &info) -> void {
			auto klass = v8pp::from_v8<T&>(info.GetIsolate(), info.This());
			
			info.GetReturnValue().Set(v8pp::to_v8<T1>(info.GetIsolate(), klass.index_set(index, v8pp::to_local<T1>(value))));
		};
	}


	template<class T1>
	static auto set_index_set(v8::IndexedPropertySetterCallback &indexset) -> typename std::enable_if_t<!has_member_index_set<T>::value> {

	}
	template<class T1>
	static auto set_index_query(v8::IndexedPropertyQueryCallback &indexquery) -> typename std::enable_if_t<has_member_index_query<T>::value> {
		indexquery = [](uint32_t index, v8::PropertyCallbackInfo <v8::Integer> &info) -> void {
			auto klass = v8pp::from_v8<T&>(info.GetIsolate(), info.This());
			info.GetReturnValue().Set(v8pp::to_v8<int>(info.GetIsolate(), klass.index_query(index)));
		};
	}
	template<class T1>
	static auto set_index_query(v8::IndexedPropertyQueryCallback &indexquery) -> typename std::enable_if_t<!has_member_index_query<T>::value> {

	}
	template<class T1>
	static auto set_index_delete(v8::IndexedPropertyDeleterCallback &indexdelete) -> typename std::enable_if_t<has_member_index_delete<T>::value> {
		indexdelete = [](uint32_t index, v8::PropertyCallbackInfo <v8::Boolean> &info) -> void {
			auto klass = v8pp::from_v8<T&>(info.GetIsolate(), info.This());
			info.GetReturnValue().Set(v8pp::to_v8<bool>(info.GetIsolate(), klass.index_delete(index)));
		};
	}
	template<class T1>
	static auto set_index_delete(v8::IndexedPropertyDeleterCallback &indexdelete) -> typename std::enable_if_t<!has_member_index_delete<T>::value> {

	}
	template<class T1>
	static auto set_index_enum(v8::IndexedPropertyEnumeratorCallback &indexenum) -> typename std::enable_if_t<has_member_index_enum<T>::value> {
		indexenum = [](v8::PropertyCallbackInfo <v8::Array> &info) -> void {
			auto klass = v8pp::from_v8<T&>(info.GetIsolate(), info.This());
			info.GetReturnValue().Set(v8pp::to_v8<v8::Array>(info.GetIsolate(), klass.index_enum()));
		};
	}
	template<class T1>
	static auto set_index_enum(v8::IndexedPropertyEnumeratorCallback &indexenum) -> typename std::enable_if_t<!has_member_index_enum<T>::value> {

	}

	template<class T1> // element type
	void index() {
		v8::IndexedPropertyGetterCallback IndexGet = [](uint32_t index, const v8::PropertyCallbackInfo<v8::Value> &info) -> void {
			auto klass = v8pp::from_v8<T&>(info.GetIsolate(), info.This());
			info.GetReturnValue().Set(v8pp::to_v8<T1>(info.GetIsolate(), klass.index_get(index)));
		};

		v8::IndexedPropertySetterCallback IndexSet = NULL;
		set_index_set<T1>(IndexSet);

		v8::IndexedPropertyQueryCallback IndexQuery = NULL;
		set_index_query<T1>(IndexQuery);

		v8::IndexedPropertyDeleterCallback IndexDelete = NULL;
		set_index_delete<T1>(IndexDelete);

		v8::IndexedPropertyEnumeratorCallback IndexEnum = NULL;
		set_index_enum<T1>(IndexEnum);

		class_function_template()->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(IndexGet, IndexSet, IndexQuery, IndexDelete,IndexEnum));
	}

Is there any better method to do this?

@mhalenza
Copy link

I can't help you with your code, @Yangff, but I'd like to 1 this proposal and take it a step further: I'd like a way to intercept all property accesses that aren't handled by other v8pp properties. Use case is simple: I want all other properties to return null to JS and throw a JS exception on set.

@pmed
Copy link
Owner

pmed commented Mar 16, 2018

Some time ago I started working on generalized indexed/named property accessor handler in v8pp::class_. Both of these handlers have 5 functions to get/set/query/delete/enumerate items or properties. Unfortunately, currently I have no spare time to complete that implementation.

At the present moment the only way is to set accessor handler with v8pp::class_::class_function_template()->InstanceTemplate()->SetHandler(your_accessor_handler_configuration). The accessor handler configuration could be created similar to example above by @Yangff

@pmed pmed mentioned this issue Aug 29, 2019
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

3 participants