Merge remote-tracking branch 'origin/sk-rpc' into al-rpc

This commit is contained in:
Ari Lazier 2015-10-08 09:35:25 -06:00
commit fadf01a0e1
8 changed files with 172 additions and 33 deletions

View File

@ -73,7 +73,34 @@ static JSGlobalContextRef s_context;
inContext:[JSContext contextWithJSGlobalContextRef:s_context]] JSValueRef]; inContext:[JSContext contextWithJSGlobalContextRef:s_context]] JSValueRef];
JSValueRef exception = NULL; JSValueRef exception = NULL;
RPCObjectID oid = [self storeObject:(JSObjectRef)RealmCreateObject(s_context, NULL, s_objects[realmId], 1, &value, &exception)]; RPCObjectID oid = [self storeObject:(JSObjectRef)RealmCreateObject(s_context, NULL, s_objects[realmId], 1, &value, &exception)];
return @{@"result": @{@"type": @"PropTypesOBJECT", @"id": @(oid)}};
if (exception) {
return @{@"error": @(RJSStringForValue(s_context, exception).c_str())};
}
return @{@"result": @{@"type": @(RJSTypeGet(realm::PropertyTypeObject).c_str()), @"id": @(oid)}};
};
s_requests["/delete_object"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] longValue];
JSValueRef jsObject = [self valueFromDictionary:dict[@"object"]];
JSValueRef exception = NULL;
RealmDelete(s_context, NULL, s_objects[realmId], 1, &jsObject, &exception);
if (exception) {
return @{@"error": @(RJSStringForValue(s_context, exception).c_str())};
}
return @{};
};
s_requests["/delete_all"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] longValue];
JSValueRef exception = NULL;
RealmDeleteAll(s_context, NULL, s_objects[realmId], 0, NULL, &exception);
if (exception) {
return @{@"error": @(RJSStringForValue(s_context, exception).c_str())};
}
return @{};
}; };
s_requests["/dispose_realm"] = [=](NSDictionary *dict) { s_requests["/dispose_realm"] = [=](NSDictionary *dict) {
RPCObjectID realmId = [dict[@"realmId"] longValue]; RPCObjectID realmId = [dict[@"realmId"] longValue];
@ -95,11 +122,11 @@ static JSGlobalContextRef s_context;
return @{@"result": [self resultForJSValue:propertyValue]}; return @{@"result": [self resultForJSValue:propertyValue]};
}; };
s_requests["/set_property"] = [=](NSDictionary *dict) { s_requests["/set_property"] = [=](NSDictionary *dict) {
JSValueRef exception = NULL;
JSStringRef propString = RJSStringForString([dict[@"name"] UTF8String]); JSStringRef propString = RJSStringForString([dict[@"name"] UTF8String]);
RPCObjectID realmId = [dict[@"realmId"] longValue]; RPCObjectID realmId = [dict[@"objectId"] longValue];
JSValueRef value = [[JSValue valueWithObject:dict[@"value"] JSValueRef value = [self valueFromDictionary:dict[@"value"]];
inContext:[JSContext contextWithJSGlobalContextRef:s_context]] JSValueRef]; JSValueRef exception = NULL;
ObjectSetProperty(s_context, s_objects[realmId], propString, value, &exception); ObjectSetProperty(s_context, s_objects[realmId], propString, value, &exception);
JSStringRelease(propString); JSStringRelease(propString);
@ -181,10 +208,11 @@ static JSGlobalContextRef s_context;
JSValueRef exception = NULL; JSValueRef exception = NULL;
NSArray *arguments = dict[@"arguments"]; NSArray *arguments = dict[@"arguments"];
JSValueRef argumentValues[arguments.count]; NSUInteger count = arguments.count;
JSContext *context = [JSContext contextWithJSGlobalContextRef:s_context]; JSValueRef argumentValues[count];
for (int i = 0; i < arguments.count; i++) {
argumentValues[i] = [JSValue valueWithObject:arguments[i] inContext:context].JSValueRef; for (NSUInteger i = 0; i < count; i++) {
argumentValues[i] = [self valueFromDictionary:arguments[i]];
} }
JSValueRef ret; JSValueRef ret;
@ -308,4 +336,53 @@ static JSGlobalContextRef s_context;
}; };
} }
+ (JSValueRef)valueFromDictionary:(NSDictionary *)dict {
RPCObjectID oid = [dict[@"id"] longValue];
if (oid) {
return s_objects[oid];
}
id value = dict[@"value"];
if (!value) {
return JSValueMakeUndefined(s_context);
}
else if ([value isKindOfClass:[NSNull class]]) {
return JSValueMakeNull(s_context);
}
else if ([value isKindOfClass:[@YES class]]) {
return JSValueMakeBoolean(s_context, [value boolValue]);
}
else if ([value isKindOfClass:[NSNumber class]]) {
return JSValueMakeNumber(s_context, [value doubleValue]);
}
else if ([value isKindOfClass:[NSString class]]) {
return RJSValueForString(s_context, std::string([value UTF8String]));
}
else if ([value isKindOfClass:[NSArray class]]) {
NSUInteger count = [value count];
std::vector<JSValueRef> jsValues(count);
for (NSUInteger i = 0; i < count; i++) {
jsValues[i] = [self valueFromDictionary:value[i]];
}
return JSObjectMakeArray(s_context, count, jsValues.data(), NULL);
}
else if ([value isKindOfClass:[NSDictionary class]]) {
JSObjectRef jsObject = JSObjectMake(s_context, NULL, NULL);
for (NSString *key in value) {
JSValueRef jsValue = [self valueFromDictionary:value[key]];
JSStringRef jsKey = JSStringCreateWithCFString((__bridge CFStringRef)key);
JSObjectSetProperty(s_context, jsObject, jsKey, jsValue, 0, NULL);
JSStringRelease(jsKey);
}
return jsObject;
}
return JSValueMakeUndefined(s_context);
}
@end @end

View File

@ -3,8 +3,9 @@
let rpc = require('./rpc'); let rpc = require('./rpc');
let util = require('./util'); let util = require('./util');
let idKey = Symbol(); let idKey = util.idKey;
let realmKey = Symbol(); let realmKey = util.realmKey;
let resizeListKey = util.resizeListKey;
let prototype = {}; let prototype = {};
exports.create = create; exports.create = create;
@ -26,7 +27,7 @@ exports.create = create;
} }
let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments)); let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments));
this[util.resizeListKey](); this[resizeListKey]();
return result; return result;
} }
@ -40,7 +41,7 @@ function create(realmId, info) {
list[realmKey] = realmId; list[realmKey] = realmId;
list[idKey] = info.id; list[idKey] = info.id;
list[util.resizeListKey](size); list[resizeListKey](size);
return list; return list;
} }

View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
let rpc = require('./rpc'); let rpc = require('./rpc');
let util = require('./util');
let idKey = Symbol(); let idKey = util.idKey;
let realmKey = Symbol(); let realmKey = util.realmKey;
let schemaKey = Symbol();
let registeredConstructors = {}; let registeredConstructors = {};
exports.create = create; exports.create = create;
@ -18,7 +18,6 @@ function create(realmId, info) {
object[realmKey] = realmId; object[realmKey] = realmId;
object[idKey] = info.id; object[idKey] = info.id;
object[schemaKey] = schema;
for (let prop of schema.properties) { for (let prop of schema.properties) {
let name = prop.name; let name = prop.name;

View File

@ -5,8 +5,9 @@ let objects = require('./objects');
let results = require('./results'); let results = require('./results');
let rpc = require('./rpc'); let rpc = require('./rpc');
let types = require('./types'); let types = require('./types');
let util = require('./util');
let realmKey = Symbol(); let realmKey = util.realmKey;
// TODO: DATA // TODO: DATA
rpc.registerTypeConverter(types.DATE, (_, info) => new Date(info.value)); rpc.registerTypeConverter(types.DATE, (_, info) => new Date(info.value));
@ -45,11 +46,11 @@ class Realm {
} }
delete(object) { delete(object) {
// TODO rpc.deleteObject(this[realmKey], object);
} }
deleteAll() { deleteAll() {
// TODO rpc.deleteAll(this[realmKey]);
} }
objects(type, predicate) { objects(type, predicate) {

View File

@ -3,8 +3,9 @@
let rpc = require('./rpc'); let rpc = require('./rpc');
let util = require('./util'); let util = require('./util');
let idKey = Symbol(); let idKey = util.idKey;
let realmKey = Symbol(); let realmKey = util.realmKey;
let resizeListKey = util.resizeListKey;
exports.create = create; exports.create = create;
@ -15,7 +16,7 @@ function create(realmId, info) {
results[realmKey] = realmId; results[realmKey] = realmId;
results[idKey] = info.resultsId; results[idKey] = info.resultsId;
results[util.resizeListKey](size); results[resizeListKey](size);
return results; return results;
} }

View File

@ -1,7 +1,11 @@
'use strict'; 'use strict';
let util = require('./util');
let DEVICE_HOST = 'localhost:8082'; let DEVICE_HOST = 'localhost:8082';
let idKey = util.idKey;
let realmKey = util.realmKey;
let typeConverters = {}; let typeConverters = {};
let XMLHttpRequest = window.XMLHttpRequest; let XMLHttpRequest = window.XMLHttpRequest;
@ -17,6 +21,8 @@ exports.registerTypeConverter = registerTypeConverter;
exports.createRealm = createRealm; exports.createRealm = createRealm;
exports.createObject = createObject; exports.createObject = createObject;
exports.deleteObject = deleteObject;
exports.deleteAllObjects = deleteAllObjects;
exports.getObjects = getObjects; exports.getObjects = getObjects;
exports.getObjectProperty = getObjectProperty; exports.getObjectProperty = getObjectProperty;
@ -46,22 +52,32 @@ function createObject(realmId, type, values) {
return sendRequest('create_object', {realmId, type, values}); return sendRequest('create_object', {realmId, type, values});
} }
function deleteObject(realmId, object) {
object = serialize(realmId, object);
sendRequest('delete_object', {realmId, object});
}
function deleteAllObjects(realmId) {
sendRequest('delete_all', {realmId});
}
function getObjects(realmId, type, predicate) { function getObjects(realmId, type, predicate) {
return sendRequest('get_objects', {realmId, type, predicate}); return sendRequest('get_objects', {realmId, type, predicate});
} }
function getObjectProperty(realmId, objectId, name) { function getObjectProperty(realmId, objectId, name) {
let result = sendRequest('get_property', {realmId, objectId, name}); let result = sendRequest('get_property', {realmId, objectId, name});
return convert(realmId, result); return deserialize(realmId, result);
} }
function setObjectProperty(realmId, objectId, name, value) { function setObjectProperty(realmId, objectId, name, value) {
value = serialize(realmId, value);
sendRequest('set_property', {realmId, objectId, name, value}); sendRequest('set_property', {realmId, objectId, name, value});
} }
function getListItem(realmId, listId, index) { function getListItem(realmId, listId, index) {
let result = sendRequest('get_list_item', {realmId, listId, index}); let result = sendRequest('get_list_item', {realmId, listId, index});
return convert(realmId, result); return deserialize(realmId, result);
} }
function setListItem(realmId, listId, index, value) { function setListItem(realmId, listId, index, value) {
@ -73,13 +89,17 @@ function getListSize(realmId, listId) {
} }
function callListMethod(realmId, listId, name, args) { function callListMethod(realmId, listId, name, args) {
if (args) {
args = args.map((arg) => serialize(realmId, arg));
}
let result = sendRequest('call_list_method', {realmId, listId, name, arguments: args}); let result = sendRequest('call_list_method', {realmId, listId, name, arguments: args});
return convert(realmId, result); return deserialize(realmId, result);
} }
function getResultsItem(realmId, resultsId, index) { function getResultsItem(realmId, resultsId, index) {
let result = sendRequest('get_results_item', {realmId, resultsId, index}); let result = sendRequest('get_results_item', {realmId, resultsId, index});
return convert(realmId, result); return deserialize(realmId, result);
} }
function getResultsSize(realmId, resultsId) { function getResultsSize(realmId, resultsId) {
@ -98,9 +118,45 @@ function commitTransaction(realmId) {
sendRequest('commit_transaction', {realmId}); sendRequest('commit_transaction', {realmId});
} }
function convert(realmId, info) { function serialize(realmId, value) {
let handler = typeConverters[info.type]; if (!value || typeof value != 'object') {
return handler ? handler(realmId, info) : info.value; return {value: value};
}
let id = value[idKey];
if (id) {
if (value[realmKey] != realmId) {
throw new Error('Unable to serialize value from another Realm');
}
return {id: id};
}
if (Array.isArray(value)) {
let array = value.map((item) => serialize(realmId, item));
return {value: array};
}
let object = {};
for (let key in value) {
object[key] = serialize(realmId, value[key]);
}
return {value: object};
}
function deserialize(realmId, info) {
let type = info.type;
let handler = type && typeConverters[type];
if (handler) {
return handler(realmId, info);
}
let value = info.value;
if (value && Array.isArray(value)) {
return value.map((item) => deserialize(realmId, item));
}
return value;
} }
function sendRequest(command, data) { function sendRequest(command, data) {

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
let idKey = exports.idKey = Symbol();
let realmKey = exports.realmKey = Symbol();
let resizeListKey = exports.resizeListKey = Symbol(); let resizeListKey = exports.resizeListKey = Symbol();
exports.createList = createList; exports.createList = createList;

View File

@ -27,4 +27,6 @@ void RJSSetDefaultPath(std::string path);
JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException); JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
JSValueRef RealmCreateObject(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException); JSValueRef RealmCreateObject(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
JSValueRef RealmDelete(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
JSValueRef RealmDeleteAll(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
JSValueRef RealmObjects(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException); JSValueRef RealmObjects(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);