wrap realm properties

This commit is contained in:
Ari Lazier 2016-03-30 13:48:24 -07:00
parent 2baec5bec6
commit c249eea505
4 changed files with 83 additions and 48 deletions

View File

@ -140,10 +140,18 @@ public:
static void RemoveAllListeners(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
static void Close(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
// properties
static void GetPath(ContextType ctx, ObjectType object, ReturnType &returnObject);
static void GetSchemaVersion(ContextType ctx, ObjectType object, ReturnType &returnObject);
// constructor methods
static void Constructor(ContextType ctx, ObjectType constructor, size_t argumentCount, const ValueType arguments[], ObjectType &returnObject);
static void SchemaVersion(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject);
// static properties
static void GetDefaultPath(ContextType ctx, ObjectType object, ReturnType &returnObject);
static void SetDefaultPath(ContextType ctx, ObjectType object, ValueType value);
static std::string validated_notification_name(JSContextRef ctx, JSValueRef value) {
std::string name = RJSValidatedStringForValue(ctx, value);
if (name != "change") {
@ -267,6 +275,26 @@ void Realm<T>::SchemaVersion(ContextType ctx, ObjectType thisObject, size_t argu
}
}
template<typename T>
void Realm<T>::GetDefaultPath(ContextType ctx, ObjectType object, ReturnType &returnObject) {
returnObject = RJSValueForString(ctx, realm::js::default_path());
}
template<typename T>
void Realm<T>::SetDefaultPath(ContextType ctx, ObjectType object, ValueType value) {
js::set_default_path(RJSValidatedStringForValue(ctx, value, "defaultPath"));
}
template<typename T>
void Realm<T>::GetPath(ContextType ctx, ObjectType object, ReturnType &returnObject) {
returnObject = RJSValueForString(ctx, RJSGetInternal<SharedRealm *>(object)->get()->config().path);
}
template<typename T>
void Realm<T>::GetSchemaVersion(ContextType ctx, ObjectType object, ReturnType &returnObject) {
returnObject = JSValueMakeNumber(ctx, RJSGetInternal<SharedRealm *>(object)->get()->config().schema_version);
}
template<typename T>
void Realm<T>::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) {
RJSValidateArgumentCount(argumentCount, 1);

View File

@ -39,9 +39,9 @@ catch(std::exception &e) { RJSSetException(ctx, EXCEPTION, e); }
#define WRAP_CLASS_METHOD(CLASS_NAME, METHOD_NAME) \
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* ex) { \
JSValueRef returnObject = NULL; \
WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, thisObject, argumentCount, arguments, returnObject); \
return returnObject; \
JSValueRef returnValue = NULL; \
WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, thisObject, argumentCount, arguments, returnValue); \
return returnValue; \
}
#define WRAP_CONSTRUCTOR(CLASS_NAME, METHOD_NAME) \
@ -51,6 +51,20 @@ JSObjectRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef constructor,
return returnObject; \
}
#define WRAP_PROPERTY_GETTER(CLASS_NAME, METHOD_NAME) \
JSValueRef CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* ex) { \
JSValueRef returnValue = NULL; \
WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, object, returnValue); \
return returnValue; \
}
#define WRAP_PROPERTY_SETTER(CLASS_NAME, METHOD_NAME) \
bool CLASS_NAME ## METHOD_NAME(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef value, JSValueRef* ex) { \
WRAP_EXCEPTION(CLASS_NAME::METHOD_NAME, *ex, ctx, object, value); \
return true; \
}
template<typename T>
inline void RJSFinalize(JSObjectRef object) {
delete static_cast<T>(JSObjectGetPrivate(object));
@ -64,7 +78,7 @@ inline T RJSGetInternal(JSObjectRef jsObject) {
template<typename T>
JSClassRef RJSCreateWrapperClass(const char * name, JSObjectGetPropertyCallback getter = NULL, JSObjectSetPropertyCallback setter = NULL, const JSStaticFunction *funcs = NULL,
JSObjectGetPropertyNamesCallback propertyNames = NULL, JSClassRef parentClass = NULL) {
JSObjectGetPropertyNamesCallback propertyNames = NULL, JSClassRef parentClass = NULL, const JSStaticValue *values = NULL) {
JSClassDefinition classDefinition = kJSClassDefinitionEmpty;
classDefinition.className = name;
classDefinition.finalize = RJSFinalize<T>;
@ -73,6 +87,7 @@ JSClassRef RJSCreateWrapperClass(const char * name, JSObjectGetPropertyCallback
classDefinition.staticFunctions = funcs;
classDefinition.getPropertyNames = propertyNames;
classDefinition.parentClass = parentClass;
classDefinition.staticValues = values;
return JSClassCreate(&classDefinition);
}

View File

@ -24,14 +24,23 @@
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
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);
if (indexStr == "length") {
return JSValueMakeNumber(ctx, list->size());
}
return RJSObjectCreate(ctx, Object(list->get_realm(), list->get_object_schema(), list->get(RJSValidatedPositiveIndex(indexStr))));
}
catch (std::out_of_range &exp) {
@ -112,8 +121,13 @@ static const JSStaticFunction RJSListFuncs[] = {
{NULL, NULL},
};
static const JSStaticValue RJSListProps[] = {
{"length", ListGetLength, nullptr, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL},
};
JSClassRef RJSListClass() {
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass());
static JSClassRef s_listClass = RJSCreateWrapperClass<List *>("List", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps);
return s_listClass;
}

View File

@ -35,36 +35,20 @@
using namespace realm;
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
static JSValueRef GetDefaultPath(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException) {
return RJSValueForString(ctx, realm::js::default_path());
}
static bool SetDefaultPath(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
try {
js::set_default_path(RJSValidatedStringForValue(ctx, value, "defaultPath"));
}
catch (std::exception &ex) {
if (jsException) {
*jsException = RJSMakeError(ctx, ex);
}
}
return true;
}
bool RealmHasInstance(JSContextRef ctx, JSObjectRef constructor, JSValueRef value, JSValueRef* exception) {
return JSValueIsObjectOfClass(ctx, value, RJSRealmClass());
}
static const JSStaticValue RealmStaticProperties[] = {
{"defaultPath", GetDefaultPath, SetDefaultPath, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL}
};
using RJSRealm = realm::js::Realm<realm::jsc::Types>;
WRAP_CONSTRUCTOR(RJSRealm, Constructor);
WRAP_CLASS_METHOD(RJSRealm, SchemaVersion)
WRAP_PROPERTY_GETTER(RJSRealm, GetDefaultPath)
WRAP_PROPERTY_SETTER(RJSRealm, SetDefaultPath)
static const JSStaticValue RealmConstructorStaticProperties[] = {
{"defaultPath", RJSRealmGetDefaultPath, RJSRealmSetDefaultPath, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL}
};
static const JSStaticFunction RealmConstructorFuncs[] = {
{"schemaVersion", RJSRealmSchemaVersion, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
@ -77,24 +61,11 @@ JSClassRef RJSRealmConstructorClass() {
realmConstructorDefinition.className = "RealmConstructor";
realmConstructorDefinition.callAsConstructor = RJSRealmConstructor;
realmConstructorDefinition.hasInstance = RealmHasInstance;
realmConstructorDefinition.staticValues = RealmStaticProperties;
realmConstructorDefinition.staticValues = RealmConstructorStaticProperties;
realmConstructorDefinition.staticFunctions = RealmConstructorFuncs;
return JSClassCreate(&realmConstructorDefinition);
}
JSValueRef RealmGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) {
static JSStringRef s_pathString = JSStringCreateWithUTF8CString("path");
if (JSStringIsEqual(propertyName, s_pathString)) {
return RJSValueForString(ctx, RJSGetInternal<SharedRealm *>(object)->get()->config().path);
}
static JSStringRef s_schemaVersion = JSStringCreateWithUTF8CString("schemaVersion");
if (JSStringIsEqual(propertyName, s_schemaVersion)) {
return JSValueMakeNumber(ctx, RJSGetInternal<SharedRealm *>(object)->get()->config().schema_version);
}
return NULL;
}
WRAP_CLASS_METHOD(RJSRealm, Objects)
WRAP_CLASS_METHOD(RJSRealm, Create)
WRAP_CLASS_METHOD(RJSRealm, Delete)
@ -104,6 +75,14 @@ WRAP_CLASS_METHOD(RJSRealm, AddListener)
WRAP_CLASS_METHOD(RJSRealm, RemoveListener)
WRAP_CLASS_METHOD(RJSRealm, RemoveAllListeners)
WRAP_CLASS_METHOD(RJSRealm, Close)
WRAP_PROPERTY_GETTER(RJSRealm, GetPath)
WRAP_PROPERTY_GETTER(RJSRealm, GetSchemaVersion)
static const JSStaticValue RealmStaticProperties[] = {
{"path", RJSRealmGetPath, RJSRealmSetDefaultPath, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"schemaVersion", RJSRealmGetSchemaVersion, RJSRealmSetDefaultPath, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL}
};
static const JSStaticFunction RJSRealmFuncs[] = {
{"objects", RJSRealmObjects, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
@ -119,11 +98,10 @@ static const JSStaticFunction RJSRealmFuncs[] = {
};
JSClassRef RJSRealmClass() {
static JSClassRef s_realmClass = RJSCreateWrapperClass<SharedRealm *>("Realm", RealmGetProperty, NULL, RJSRealmFuncs);
static JSClassRef s_realmClass = RJSCreateWrapperClass<SharedRealm *>("Realm", NULL, NULL, RJSRealmFuncs, NULL, NULL, RealmStaticProperties);
return s_realmClass;
}
namespace realm {
namespace js {
JSClassRef realm_class() { return RJSRealmClass(); };