wrap list properties
This commit is contained in:
parent
c249eea505
commit
29213f1d87
|
@ -42,6 +42,10 @@ struct List {
|
||||||
using ValueType = typename T::Value;
|
using ValueType = typename T::Value;
|
||||||
using ReturnType = typename T::Return;
|
using ReturnType = typename T::Return;
|
||||||
|
|
||||||
|
static void GetLength(ContextType ctx, ObjectType thisObject, ReturnType &ret);
|
||||||
|
static void GetIndex(ContextType ctx, ObjectType thisObject, size_t index, ReturnType &ret);
|
||||||
|
static void SetIndex(ContextType ctx, ObjectType thisObject, size_t index, ValueType value);
|
||||||
|
|
||||||
static void Push(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
static void Push(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||||
static void Pop(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
static void Pop(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||||
static void Unshift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
static void Unshift(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||||
|
@ -52,6 +56,24 @@ struct List {
|
||||||
static void Sorted(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
static void Sorted(ContextType ctx, ObjectType thisObject, size_t argCount, const ValueType args[], ReturnType &ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void List<T>::GetLength(ContextType ctx, ObjectType object, ReturnType &ret) {
|
||||||
|
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||||
|
RJSSetReturnNumber(ctx, ret, list->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void List<T>::GetIndex(ContextType ctx, ObjectType object, size_t index, ReturnType &ret) {
|
||||||
|
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||||
|
ret = RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void List<T>::SetIndex(ContextType ctx, ObjectType object, size_t index, ValueType value) {
|
||||||
|
realm::List *list = RJSGetInternal<realm::List *>(object);
|
||||||
|
list->set(ctx, value, index);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void List<T>::Push(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
|
void List<T>::Push(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
|
||||||
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
|
realm::List *list = RJSGetInternal<realm::List *>(thisObject);
|
||||||
|
|
|
@ -64,6 +64,31 @@ bool CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef
|
||||||
return true; \
|
return true; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for stol failure (std::invalid_argument) this could be another property that is handled externally, so ignore
|
||||||
|
#define WRAP_INDEXED_GETTER(CLASS_NAME, METHOD_NAME) \
|
||||||
|
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* ex) { \
|
||||||
|
JSValueRef returnValue = NULL; \
|
||||||
|
try { \
|
||||||
|
size_t index = RJSValidatedPositiveIndex(RJSStringForJSString(property)); \
|
||||||
|
CLASS_NAME::METHOD_NAME(ctx, object, index, returnValue); return returnValue; \
|
||||||
|
} \
|
||||||
|
catch (std::out_of_range &exp) { return JSValueMakeUndefined(ctx); } \
|
||||||
|
catch (std::invalid_argument &exp) { return NULL; } \
|
||||||
|
catch (std::exception &e) { RJSSetException(ctx, *ex, e); return NULL; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WRAP_INDEXED_SETTER(CLASS_NAME, METHOD_NAME) \
|
||||||
|
bool CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef* ex) { \
|
||||||
|
try { \
|
||||||
|
size_t index = RJSValidatedPositiveIndex(RJSStringForJSString(property)); \
|
||||||
|
{ CLASS_NAME::METHOD_NAME(ctx, object, index, value); return true; } \
|
||||||
|
} \
|
||||||
|
catch (std::out_of_range &exp) { RJSSetException(ctx, *ex, exp); } \
|
||||||
|
catch (std::invalid_argument &exp) { *ex = RJSMakeError(ctx, "Invalid index"); } \
|
||||||
|
catch (std::exception &e) { RJSSetException(ctx, *ex, e); } \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void RJSFinalize(JSObjectRef object) {
|
inline void RJSFinalize(JSObjectRef object) {
|
||||||
|
|
|
@ -24,64 +24,6 @@
|
||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
JSValueRef ListGetLength(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) {
|
|
||||||
try {
|
|
||||||
List *list = RJSGetInternal<List *>(object);
|
|
||||||
return JSValueMakeNumber(ctx, list->size());
|
|
||||||
}
|
|
||||||
catch (std::exception &exp) {
|
|
||||||
if (exception) {
|
|
||||||
*exception = RJSMakeError(ctx, exp);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValueRef ListGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
|
|
||||||
try {
|
|
||||||
List *list = RJSGetInternal<List *>(object);
|
|
||||||
std::string indexStr = RJSStringForJSString(propertyName);
|
|
||||||
return RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(RJSValidatedPositiveIndex(indexStr))));
|
|
||||||
}
|
|
||||||
catch (std::out_of_range &exp) {
|
|
||||||
// getters for nonexistent properties in JS should always return undefined
|
|
||||||
return JSValueMakeUndefined(ctx);
|
|
||||||
}
|
|
||||||
catch (std::invalid_argument &exp) {
|
|
||||||
// for stol failure this could be another property that is handled externally, so ignore
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
catch (std::exception &exp) {
|
|
||||||
if (jsException) {
|
|
||||||
*jsException = RJSMakeError(ctx, exp);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ListSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
|
|
||||||
try {
|
|
||||||
List *list = RJSGetInternal<List *>(object);
|
|
||||||
std::string indexStr = RJSStringForJSString(propertyName);
|
|
||||||
if (indexStr == "length") {
|
|
||||||
throw std::runtime_error("The 'length' property is readonly.");
|
|
||||||
}
|
|
||||||
|
|
||||||
list->set(ctx, value, RJSValidatedPositiveIndex(indexStr));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (std::invalid_argument &exp) {
|
|
||||||
// for stol failure this could be another property that is handled externally, so ignore
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (std::exception &exp) {
|
|
||||||
if (jsException) {
|
|
||||||
*jsException = RJSMakeError(ctx, exp);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
|
void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
|
||||||
List *list = RJSGetInternal<List *>(object);
|
List *list = RJSGetInternal<List *>(object);
|
||||||
size_t size = list->size();
|
size_t size = list->size();
|
||||||
|
@ -96,6 +38,9 @@ void ListPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccum
|
||||||
}
|
}
|
||||||
|
|
||||||
using RJSList = realm::js::List<realm::jsc::Types>;
|
using RJSList = realm::js::List<realm::jsc::Types>;
|
||||||
|
WRAP_PROPERTY_GETTER(RJSList, GetLength)
|
||||||
|
WRAP_INDEXED_GETTER(RJSList, GetIndex)
|
||||||
|
WRAP_INDEXED_SETTER(RJSList, SetIndex)
|
||||||
WRAP_CLASS_METHOD(RJSList, Push)
|
WRAP_CLASS_METHOD(RJSList, Push)
|
||||||
WRAP_CLASS_METHOD(RJSList, Pop)
|
WRAP_CLASS_METHOD(RJSList, Pop)
|
||||||
WRAP_CLASS_METHOD(RJSList, Unshift)
|
WRAP_CLASS_METHOD(RJSList, Unshift)
|
||||||
|
@ -122,12 +67,12 @@ static const JSStaticFunction RJSListFuncs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const JSStaticValue RJSListProps[] = {
|
static const JSStaticValue RJSListProps[] = {
|
||||||
{"length", ListGetLength, nullptr, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
{"length", RJSListGetLength, nullptr, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
JSClassRef RJSListClass() {
|
JSClassRef RJSListClass() {
|
||||||
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps);
|
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", RJSListGetIndex, RJSListSetIndex, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps);
|
||||||
return s_listClass;
|
return s_listClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue