aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Austin <chad@imvu.com>2013-04-02 02:24:21 -0700
committerJukka Jylänki <jujjyl@gmail.com>2013-04-12 14:27:08 +0300
commitdef5681c4f191c5e273765624b200619a50cf805 (patch)
treeb3a6460b237e460a083d16929fc6bb80f221d988
parentfbcb6a4b34c0d0e4b16cbcdfccdb11a9e3a6b080 (diff)
Generalize and support mix-and-match member/non-member getter/setter for value types.
-rwxr-xr-xsystem/include/emscripten/bind.h223
1 files changed, 97 insertions, 126 deletions
diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h
index 6e420a29..3161289d 100755
--- a/system/include/emscripten/bind.h
+++ b/system/include/emscripten/bind.h
@@ -361,55 +361,93 @@ namespace emscripten {
}
};
- template<typename ClassType, typename PropertyType>
- struct PropertyAccess {
- typedef internal::BindingType<PropertyType> MemberBinding;
- typedef typename MemberBinding::WireType WireType;
+ // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
+ template<typename T>
+ inline void* getContext(const T& t) {
+ // not a leak because this is called once per binding
+ void* p = malloc(sizeof(T));
+ assert(p);
+ memcpy(p, &t, sizeof(T));
+ return p;
+ }
- template<typename Getter>
- static WireType getByFunction(
- const Getter& getter,
- const ClassType& ptr
- ) {
- return MemberBinding::toWireType(getter(ptr));
+ template<typename T>
+ struct GetterPolicy;
+
+ template<typename GetterReturnType, typename GetterThisType>
+ struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
+ typedef GetterReturnType ReturnType;
+ typedef GetterReturnType (GetterThisType::*Context)() const;
+
+ typedef internal::BindingType<ReturnType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static WireType get(const Context& context, const ClassType& ptr) {
+ return Binding::toWireType((ptr.*context)());
}
- template<typename Getter>
- static WireType getByMemberFunction(
- const Getter& getter,
- const ClassType& ptr
- ) {
- return MemberBinding::toWireType((ptr.*getter)());
+ static void* getContext(Context context) {
+ return internal::getContext(context);
}
+ };
- template<typename Setter>
- static void setByFunction(
- const Setter& setter,
- ClassType& ptr,
- WireType value
- ) {
- setter(ptr, MemberBinding::fromWireType(value));
+ template<typename GetterReturnType, typename GetterThisType>
+ struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
+ typedef GetterReturnType ReturnType;
+ typedef GetterReturnType (*Context)(const GetterThisType&);
+
+ typedef internal::BindingType<ReturnType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static WireType get(const Context& context, const ClassType& ptr) {
+ return Binding::toWireType(context(ptr));
}
- template<typename Setter>
- static void setByMemberFunction(
- const Setter& setter,
- ClassType& ptr,
- WireType value
- ) {
- (ptr.*setter)(MemberBinding::fromWireType(value));
+ static void* getContext(Context context) {
+ return internal::getContext(context);
}
};
- // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
template<typename T>
- inline void* getContext(const T& t) {
- // not a leak because this is called once per binding
- void* p = malloc(sizeof(T));
- assert(p);
- memcpy(p, &t, sizeof(T));
- return p;
- }
+ struct SetterPolicy;
+
+ template<typename SetterThisType, typename SetterArgumentType>
+ struct SetterPolicy<void (SetterThisType::*)(SetterArgumentType)> {
+ typedef SetterArgumentType ArgumentType;
+ typedef void (SetterThisType::*Context)(SetterArgumentType);
+
+ typedef internal::BindingType<SetterArgumentType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static void set(const Context& context, ClassType& ptr, WireType wt) {
+ (ptr.*context)(Binding::fromWireType(wt));
+ }
+
+ static void* getContext(Context context) {
+ return internal::getContext(context);
+ }
+ };
+
+ template<typename SetterThisType, typename SetterArgumentType>
+ struct SetterPolicy<void (*)(SetterThisType&, SetterArgumentType)> {
+ typedef SetterArgumentType ArgumentType;
+ typedef void (*Context)(SetterThisType&, SetterArgumentType);
+
+ typedef internal::BindingType<SetterArgumentType> Binding;
+ typedef typename Binding::WireType WireType;
+
+ template<typename ClassType>
+ static void set(const Context& context, ClassType& ptr, WireType wt) {
+ context(ptr, Binding::fromWireType(wt));
+ }
+
+ static void* getContext(Context context) {
+ return internal::getContext(context);
+ }
+ };
}
////////////////////////////////////////////////////////////////////////////////
@@ -446,55 +484,21 @@ namespace emscripten {
return *this;
}
- template<
- typename GetterReturnType,
- typename GetterThisType,
- typename SetterArgumentType,
- typename SetterThisType>
- value_tuple& element(
- GetterReturnType (GetterThisType::*getter)() const,
- void (SetterThisType::*setter)(SetterArgumentType)
- ) {
+ template<typename Getter, typename Setter>
+ value_tuple& element(Getter getter, Setter setter) {
using namespace internal;
+ typedef GetterPolicy<Getter> GP;
+ typedef SetterPolicy<Setter> SP;
_embind_register_tuple_element(
TypeID<ClassType>::get(),
- TypeID<GetterReturnType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, GetterReturnType>
- ::template getByMemberFunction<decltype(getter)>),
- getContext(getter),
- TypeID<SetterArgumentType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, SetterArgumentType>
- ::template setByMemberFunction<decltype(setter)>),
- getContext(setter));
+ TypeID<typename GP::ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
+ GP::getContext(getter),
+ TypeID<typename SP::ArgumentType>::get(),
+ reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
+ SP::getContext(setter));
return *this;
}
-
- template<
- typename GetterReturnType,
- typename GetterThisType,
- typename SetterArgumentType,
- typename SetterThisType>
- value_tuple& element(
- GetterReturnType (*getter)(const GetterThisType&),
- void (*setter)(SetterThisType&, SetterArgumentType)
- ) {
- using namespace internal;
- _embind_register_tuple_element(
- TypeID<ClassType>::get(),
- TypeID<GetterReturnType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, GetterReturnType>
- ::template getByFunction<decltype(getter)>),
- getContext(getter),
- TypeID<SetterArgumentType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, SetterArgumentType>
- ::template setByFunction<decltype(setter)>),
- getContext(setter));
- return *this;
- }
};
////////////////////////////////////////////////////////////////////////////////
@@ -532,57 +536,24 @@ namespace emscripten {
return *this;
}
- template<
- typename GetterReturnType,
- typename GetterThisType,
- typename SetterArgumentType,
- typename SetterThisType>
+ template<typename Getter, typename Setter>
value_struct& field(
const char* fieldName,
- GetterReturnType (GetterThisType::*getter)() const,
- void (SetterThisType::*setter)(SetterArgumentType)
+ Getter getter,
+ Setter setter
) {
using namespace internal;
+ typedef GetterPolicy<Getter> GP;
+ typedef SetterPolicy<Setter> SP;
_embind_register_struct_field(
TypeID<ClassType>::get(),
fieldName,
- TypeID<GetterReturnType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, GetterReturnType>
- ::template getByMemberFunction<decltype(getter)>),
- getContext(getter),
- TypeID<SetterArgumentType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, SetterArgumentType>
- ::template setByMemberFunction<decltype(setter)>),
- getContext(setter));
- return *this;
- }
-
- template<
- typename GetterReturnType,
- typename GetterThisType,
- typename SetterArgumentType,
- typename SetterThisType>
- value_struct& field(
- const char* fieldName,
- GetterReturnType (*getter)(const GetterThisType&),
- void (*setter)(SetterThisType&, SetterArgumentType)
- ) {
- using namespace internal;
- _embind_register_struct_field(
- TypeID<ClassType>::get(),
- fieldName,
- TypeID<GetterReturnType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, GetterReturnType>
- ::template getByFunction<decltype(getter)>),
- getContext(getter),
- TypeID<SetterArgumentType>::get(),
- reinterpret_cast<GenericFunction>(
- &PropertyAccess<ClassType, SetterArgumentType>
- ::template setByFunction<decltype(setter)>),
- getContext(setter));
+ TypeID<typename GP::ReturnType>::get(),
+ reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
+ GP::getContext(getter),
+ TypeID<typename SP::ArgumentType>::get(),
+ reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
+ SP::getContext(setter));
return *this;
}
};