diff --git a/src/js_realm.hpp b/src/js_realm.hpp index a04dcb04..cb369d9f 100644 --- a/src/js_realm.hpp +++ b/src/js_realm.hpp @@ -140,9 +140,17 @@ 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); @@ -267,6 +275,26 @@ void Realm::SchemaVersion(ContextType ctx, ObjectType thisObject, size_t argu } } +template +void Realm::GetDefaultPath(ContextType ctx, ObjectType object, ReturnType &returnObject) { + returnObject = RJSValueForString(ctx, realm::js::default_path()); +} + +template +void Realm::SetDefaultPath(ContextType ctx, ObjectType object, ValueType value) { + js::set_default_path(RJSValidatedStringForValue(ctx, value, "defaultPath")); +} + +template +void Realm::GetPath(ContextType ctx, ObjectType object, ReturnType &returnObject) { + returnObject = RJSValueForString(ctx, RJSGetInternal(object)->get()->config().path); +} + +template +void Realm::GetSchemaVersion(ContextType ctx, ObjectType object, ReturnType &returnObject) { + returnObject = JSValueMakeNumber(ctx, RJSGetInternal(object)->get()->config().schema_version); +} + template void Realm::Objects(ContextType ctx, ObjectType thisObject, size_t argumentCount, const ValueType arguments[], ReturnType &returnObject) { RJSValidateArgumentCount(argumentCount, 1); diff --git a/src/js_util.hpp b/src/js_util.hpp index 3c6222c6..d416827f 100644 --- a/src/js_util.hpp +++ b/src/js_util.hpp @@ -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 inline void RJSFinalize(JSObjectRef object) { delete static_cast(JSObjectGetPrivate(object)); @@ -64,7 +78,7 @@ inline T RJSGetInternal(JSObjectRef jsObject) { template 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; @@ -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); } diff --git a/src/jsc/jsc_list.cpp b/src/jsc/jsc_list.cpp index 5f4f2802..da2ef3f9 100644 --- a/src/jsc/jsc_list.cpp +++ b/src/jsc/jsc_list.cpp @@ -24,14 +24,23 @@ using RJSAccessor = realm::NativeAccessor; using namespace realm; +JSValueRef ListGetLength(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { + try { + List *list = RJSGetInternal(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(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", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass()); + static JSClassRef s_listClass = RJSCreateWrapperClass("List", ListGetProperty, ListSetProperty, RJSListFuncs, ListPropertyNames, RJSCollectionClass(), RJSListProps); return s_listClass; } diff --git a/src/jsc/jsc_realm.cpp b/src/jsc/jsc_realm.cpp index 7623454c..118bf267 100644 --- a/src/jsc/jsc_realm.cpp +++ b/src/jsc/jsc_realm.cpp @@ -35,36 +35,20 @@ using namespace realm; using RJSAccessor = realm::NativeAccessor; - -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; 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(object)->get()->config().path); - } - - static JSStringRef s_schemaVersion = JSStringCreateWithUTF8CString("schemaVersion"); - if (JSStringIsEqual(propertyName, s_schemaVersion)) { - return JSValueMakeNumber(ctx, RJSGetInternal(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("Realm", RealmGetProperty, NULL, RJSRealmFuncs); + static JSClassRef s_realmClass = RJSCreateWrapperClass("Realm", NULL, NULL, RJSRealmFuncs, NULL, NULL, RealmStaticProperties); return s_realmClass; } - namespace realm { namespace js { JSClassRef realm_class() { return RJSRealmClass(); };