Improve calling object methods through RPC

This commit is contained in:
Scott Kyle 2015-10-19 15:52:32 -07:00
parent d172b43535
commit 57778ce878
10 changed files with 19 additions and 40 deletions

View File

@ -62,7 +62,7 @@ class Realm {
throw new Error('Realm.addNotification must be passed a function!');
}
let notification = rpc.callMethod(realmId, realmId, internal.REALM, 'addNotification', [callback]);
let notification = rpc.callMethod(realmId, realmId, 'addNotification', [callback]);
notification[notificationCallbackKey] = callback;
this[notificationsKey].push(notification);

View File

@ -42,12 +42,12 @@ function createRealm(args) {
return sendRequest('create_realm', {arguments: args});
}
function callMethod(realmId, id, type, name, args) {
function callMethod(realmId, id, name, args) {
if (args) {
args = args.map((arg) => serialize(realmId, arg));
}
let result = sendRequest('call_method', {realmId, id, type, name, arguments: args});
let result = sendRequest('call_method', {realmId, id, name, arguments: args});
return deserialize(realmId, result);
}

View File

@ -71,7 +71,7 @@ function createMethods(prototype, type, methodNames, resize) {
throw new TypeError(name + ' method was called on an object of the wrong type!');
}
let result = rpc.callMethod(realmId, id, type, name, Array.from(arguments));
let result = rpc.callMethod(realmId, id, name, Array.from(arguments));
if (resize) {
this[keys.resize]();

View File

@ -214,7 +214,7 @@ JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list) {
return RJSWrapObject<List *>(ctx, RJSListClass(), new List(list));
}
const JSStaticFunction RJSListFuncs[] = {
static const JSStaticFunction RJSListFuncs[] = {
{"push", ListPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"pop", ListPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"shift", ListShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},

View File

@ -20,6 +20,5 @@
#import "shared_realm.hpp"
#import "list.hpp"
extern const JSStaticFunction RJSListFuncs[];
JSClassRef RJSListClass();
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list);

View File

@ -18,8 +18,6 @@
#import "RJSUtil.hpp"
extern const JSStaticFunction RJSRealmFuncs[];
JSClassRef RJSRealmClass();
JSClassRef RJSRealmConstructorClass();
JSClassRef RJSNotificationClass();

View File

@ -433,7 +433,7 @@ JSValueRef RealmClose(JSContextRef ctx, JSObjectRef function, JSObjectRef thisOb
return NULL;
}
const JSStaticFunction RJSRealmFuncs[] = {
static const JSStaticFunction RJSRealmFuncs[] = {
{"objects", RealmObjects, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"create", RealmCreateObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"delete", RealmDelete, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},

View File

@ -23,7 +23,6 @@ namespace realm {
typedef std::shared_ptr<Realm> SharedRealm;
}
extern const JSStaticFunction RJSResultsFuncs[];
JSClassRef RJSResultsClass();
JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className);
JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className, std::string query);

View File

@ -118,7 +118,7 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl
return RJSWrapObject<Results *>(ctx, RJSResultsClass(), new Results(realm, *object_schema, std::move(query)));
}
const JSStaticFunction RJSResultsFuncs[] = {
static const JSStaticFunction RJSResultsFuncs[] = {
{"sortByProperty", SortByProperty, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL},
};

View File

@ -38,23 +38,14 @@ using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
static const char * const RealmObjectTypesFunction = "ObjectTypesFUNCTION";
static const char * const RealmObjectTypesNotification = "ObjectTypesNOTIFICATION";
static const char * const RealmObjectTypesRealm = "ObjectTypesREALM";
static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
static std::map<std::string, const JSStaticFunction *> s_objectTypeMethods;
@implementation RJSRPCServer {
JSGlobalContextRef _context;
std::map<std::string, RPCRequest> _requests;
std::map<RPCObjectID, JSObjectRef> _objects;
}
+ (void)initialize {
s_objectTypeMethods[RealmObjectTypesRealm] = RJSRealmFuncs;
s_objectTypeMethods[RealmObjectTypesResults] = RJSResultsFuncs;
s_objectTypeMethods[RJSTypeGet(realm::PropertyTypeArray)] = RJSListFuncs;
}
- (void)dealloc {
for (auto item : _objects) {
JSValueUnprotect(_context, item.second);
@ -115,7 +106,6 @@ static std::map<std::string, const JSStaticFunction *> s_objectTypeMethods;
};
_requests["/call_method"] = [=](NSDictionary *dict) {
return [self performObjectMethod:dict[@"name"]
withType:dict[@"type"]
args:dict[@"arguments"]
objectId:[dict[@"id"] unsignedLongValue]];
};
@ -194,32 +184,25 @@ static std::map<std::string, const JSStaticFunction *> s_objectTypeMethods;
return response ?: @{};
}
- (NSDictionary *)performObjectMethod:(NSString *)method
withType:(NSString *)type
args:(NSArray *)args
objectId:(RPCObjectID)oid {
const JSStaticFunction *methods = s_objectTypeMethods.at(type.UTF8String);
- (NSDictionary *)performObjectMethod:(NSString *)method args:(NSArray *)args objectId:(RPCObjectID)oid {
JSObjectRef object = _objects[oid];
JSStringRef methodString = RJSStringForString(method.UTF8String);
JSObjectRef function = RJSValidatedObjectProperty(_context, object, methodString);
JSStringRelease(methodString);
NSUInteger argCount = args.count;
JSValueRef argValues[argCount];
for (NSUInteger i = 0; i < argCount; i++) {
argValues[i] = [self deserializeDictionaryValue:args[i]];
}
const char *name = method.UTF8String;
size_t index = 0;
while (methods[index].name) {
if (!strcmp(methods[index].name, name)) {
JSValueRef exception = NULL;
JSValueRef ret = methods[index].callAsFunction(_context, NULL, _objects[oid], argCount, argValues, &exception);
if (exception) {
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
}
return @{@"result": [self resultForJSValue:ret]};
}
index++;
}
JSValueRef exception = NULL;
JSValueRef result = JSObjectCallAsFunction(_context, function, object, argCount, argValues, &exception);
return @{@"error": [NSString stringWithFormat:@"Attempted to call invalid method (%@) on type: %@", method, type]};
if (exception) {
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
}
return @{@"result": [self resultForJSValue:result]};
}
- (RPCObjectID)storeObject:(JSObjectRef)object {