key templates off explicitly defined classes rather than the internal type

This commit is contained in:
Ari Lazier 2016-04-15 13:47:01 -07:00
parent 760126f0d7
commit bd4088ce91
11 changed files with 148 additions and 114 deletions

View File

@ -70,6 +70,8 @@ using PropertyMap = std::map<std::string, PropertyType<T>>;
template<typename T, typename U>
struct ClassDefinition {
using Internal = U;
// Every specialization *must* at least have a name.
std::string name;
};
@ -89,7 +91,7 @@ struct BaseClassDefinition {
StringPropertyType<T> string_accessor;
};
template<typename T, typename U>
template<typename T, typename ClassType>
class ObjectWrap;
} // js

View File

@ -27,7 +27,7 @@ namespace js {
class Collection {};
template<typename T>
struct ClassDefinition<T, Collection> : BaseClassDefinition<T> {
struct CollectionClass : ClassDefinition<T, Collection>, BaseClassDefinition<T> {
std::string const name = "Collection";
};

View File

@ -58,7 +58,7 @@ struct List {
};
template<typename T>
struct ClassDefinition<T, realm::List> : BaseClassDefinition<T, Collection> {
struct ListClass : ClassDefinition<T, realm::List>, BaseClassDefinition<T, CollectionClass<T>> {
using List = List<T>;
std::string const name = "List";
@ -83,18 +83,18 @@ struct ClassDefinition<T, realm::List> : BaseClassDefinition<T, Collection> {
template<typename T>
typename T::Object List<T>::create_instance(TContext ctx, realm::List &list) {
return create_object<T, realm::List>(ctx, new realm::List(list));
return create_object<T, ListClass<T>>(ctx, new realm::List(list));
}
template<typename T>
void List<T>::GetLength(TContext ctx, TObject object, ReturnValue &return_value) {
auto list = get_internal<T, realm::List>(object);
auto list = get_internal<T, ListClass<T>>(object);
return_value.set((uint32_t)list->size());
}
template<typename T>
void List<T>::GetIndex(TContext ctx, TObject object, uint32_t index, ReturnValue &return_value) {
auto list = get_internal<T, realm::List>(object);
auto list = get_internal<T, ListClass<T>>(object);
auto realm_object = realm::Object(list->get_realm(), list->get_object_schema(), list->get(index));
return_value.set(RealmObject<T>::create_instance(ctx, realm_object));
@ -102,7 +102,7 @@ void List<T>::GetIndex(TContext ctx, TObject object, uint32_t index, ReturnValue
template<typename T>
bool List<T>::SetIndex(TContext ctx, TObject object, uint32_t index, TValue value) {
auto list = get_internal<T, realm::List>(object);
auto list = get_internal<T, ListClass<T>>(object);
list->set(ctx, value, index);
return true;
}
@ -111,7 +111,7 @@ template<typename T>
void List<T>::Push(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count_at_least(argc, 1);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
for (size_t i = 0; i < argc; i++) {
list->add(ctx, arguments[i]);
}
@ -123,7 +123,7 @@ template<typename T>
void List<T>::Pop(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
size_t size = list->size();
if (size == 0) {
list->verify_in_transaction();
@ -142,7 +142,7 @@ template<typename T>
void List<T>::Unshift(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count_at_least(argc, 1);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
for (size_t i = 0; i < argc; i++) {
list->insert(ctx, arguments[i], i);
}
@ -154,7 +154,7 @@ template<typename T>
void List<T>::Shift(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
if (list->size() == 0) {
list->verify_in_transaction();
return_value.set_undefined();
@ -171,7 +171,7 @@ template<typename T>
void List<T>::Splice(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count_at_least(argc, 1);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
size_t size = list->size();
long index = std::min<long>(Value::to_number(ctx, arguments[0]), size);
if (index < 0) {
@ -207,7 +207,7 @@ template<typename T>
void List<T>::StaticResults(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
return_value.set(Results<T>::create_instance(ctx, *list, false));
}
@ -215,7 +215,7 @@ template<typename T>
void List<T>::Filtered(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count_at_least(argc, 1);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
return_value.set(Results<T>::create_filtered(ctx, *list, argc, arguments));
}
@ -223,7 +223,7 @@ template<typename T>
void List<T>::Sorted(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 1, 2);
auto list = get_internal<T, realm::List>(this_object);
auto list = get_internal<T, ListClass<T>>(this_object);
return_value.set(Results<T>::create_sorted(ctx, *list, argc, arguments));
}

View File

@ -48,7 +48,7 @@ struct RealmObject {
};
template<typename T>
struct ClassDefinition<T, realm::Object> : BaseClassDefinition<T> {
struct RealmObjectClass : ClassDefinition<T, realm::Object>, BaseClassDefinition<T> {
using RealmObject = RealmObject<T>;
const std::string name = "RealmObject";
@ -66,7 +66,7 @@ typename T::Object RealmObject<T>::create_instance(TContext ctx, realm::Object &
auto delegate = get_delegate<T>(realm_object.realm().get());
auto name = realm_object.get_object_schema().name;
auto object = create_object<T, realm::Object>(ctx, new realm::Object(realm_object));
auto object = create_object<T, RealmObjectClass<T>>(ctx, new realm::Object(realm_object));
if (!delegate->m_constructors.count(name)) {
return object;
@ -87,7 +87,7 @@ typename T::Object RealmObject<T>::create_instance(TContext ctx, realm::Object &
template<typename T>
void RealmObject<T>::GetProperty(TContext ctx, TObject object, const String &property, ReturnValue &return_value) {
try {
auto realm_object = get_internal<T, realm::Object>(object);
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
auto result = realm_object->template get_property_value<TValue>(ctx, property);
return_value.set(result);
} catch (InvalidPropertyException &ex) {
@ -97,14 +97,14 @@ void RealmObject<T>::GetProperty(TContext ctx, TObject object, const String &pro
template<typename T>
bool RealmObject<T>::SetProperty(TContext ctx, TObject object, const String &property, TValue value) {
auto realm_object = get_internal<T, realm::Object>(object);
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
realm_object->set_property_value(ctx, property, value, true);
return true;
}
template<typename T>
std::vector<String<T>> RealmObject<T>::GetPropertyNames(TContext ctx, TObject object) {
auto realm_object = get_internal<T, realm::Object>(object);
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
auto &properties = realm_object->get_object_schema().properties;
std::vector<String> names;

View File

@ -102,8 +102,8 @@ struct NativeAccessor {
static size_t to_object_index(TContext ctx, SharedRealm realm, TValue &value, const std::string &type, bool try_update) {
TObject object = Value::validated_to_object(ctx, value);
if (Object::template is_instance<realm::Object>(ctx, object)) {
return get_internal<T, realm::Object>(object)->row().get_index();
if (Object::template is_instance<RealmObjectClass<T>>(ctx, object)) {
return get_internal<T, RealmObjectClass<T>>(object)->row().get_index();
}
auto object_schema = realm->config().schema->find(type);
@ -116,8 +116,8 @@ struct NativeAccessor {
}
static size_t to_existing_object_index(TContext ctx, TValue &value) {
TObject object = Value::validated_to_object(ctx, value);
if (Object::template is_instance<realm::Object>(ctx, object)) {
return get_internal<T, realm::Object>(object)->row().get_index();
if (Object::template is_instance<RealmObjectClass<T>>(ctx, object)) {
return get_internal<T, RealmObjectClass<T>>(object)->row().get_index();
}
throw std::runtime_error("object is not a Realm Object");
}

View File

@ -37,6 +37,9 @@
namespace realm {
namespace js {
template<typename T>
struct RealmClass;
template<typename T>
class RealmDelegate : public BindingContext {
public:
@ -87,7 +90,7 @@ class RealmDelegate : public BindingContext {
throw std::runtime_error("Realm no longer exists");
}
TObject realm_object = create_object<T, SharedRealm>(m_context, new SharedRealm(realm));
TObject realm_object = create_object<T, RealmClass<T>>(m_context, new SharedRealm(realm));
TValue arguments[2];
arguments[0] = realm_object;
arguments[1] = Value::from_string(m_context, notification_name);
@ -140,10 +143,10 @@ class Realm {
static void SetDefaultPath(TContext, TObject, TValue value);
static TObject create_constructor(TContext ctx) {
TObject realm_constructor = ObjectWrap<T, SharedRealm>::create_constructor(ctx);
TObject collection_constructor = ObjectWrap<T, Collection>::create_constructor(ctx);
TObject list_constructor = ObjectWrap<T, realm::List>::create_constructor(ctx);
TObject results_constructor = ObjectWrap<T, realm::Results>::create_constructor(ctx);
TObject realm_constructor = ObjectWrap<T, RealmClass<T>>::create_constructor(ctx);
TObject collection_constructor = ObjectWrap<T, CollectionClass<T>>::create_constructor(ctx);
TObject list_constructor = ObjectWrap<T, ListClass<T>>::create_constructor(ctx);
TObject results_constructor = ObjectWrap<T, ResultsClass<T>>::create_constructor(ctx);
PropertyAttributes attributes = PropertyAttributes(ReadOnly | DontEnum | DontDelete);
Object::set_property(ctx, realm_constructor, "Collection", collection_constructor, attributes);
@ -186,7 +189,7 @@ class Realm {
};
template<typename T>
struct ClassDefinition<T, SharedRealm> : BaseClassDefinition<T> {
struct RealmClass : ClassDefinition<T, SharedRealm>, BaseClassDefinition<T> {
using Realm = Realm<T>;
std::string const name = "Realm";
@ -288,7 +291,7 @@ void Realm<T>::Constructor(TContext ctx, TObject this_object, size_t argc, const
delegate->m_defaults = std::move(defaults);
delegate->m_constructors = std::move(constructors);
set_internal<T, SharedRealm>(this_object, new SharedRealm(realm));
set_internal<T, RealmClass<T>>(this_object, new SharedRealm(realm));
}
template<typename T>
@ -330,13 +333,13 @@ void Realm<T>::SetDefaultPath(TContext ctx, TObject object, TValue value) {
template<typename T>
void Realm<T>::GetPath(TContext ctx, TObject object, ReturnValue &return_value) {
std::string path = get_internal<T, SharedRealm>(object)->get()->config().path;
std::string path = get_internal<T, RealmClass<T>>(object)->get()->config().path;
return_value.set(path);
}
template<typename T>
void Realm<T>::GetSchemaVersion(TContext ctx, TObject object, ReturnValue &return_value) {
double version = get_internal<T, SharedRealm>(object)->get()->config().schema_version;
double version = get_internal<T, RealmClass<T>>(object)->get()->config().schema_version;
return_value.set(version);
}
@ -344,7 +347,7 @@ template<typename T>
void Realm<T>::Objects(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 1);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
std::string type = validated_object_type_for_value(realm, ctx, arguments[0]);
return_value.set(Results<T>::create_instance(ctx, realm, type));
@ -354,7 +357,7 @@ template<typename T>
void Realm<T>::Create(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 2, 3);
SharedRealm sharedRealm = *get_internal<T, SharedRealm>(this_object);
SharedRealm sharedRealm = *get_internal<T, RealmClass<T>>(this_object);
std::string className = validated_object_type_for_value(sharedRealm, ctx, arguments[0]);
auto &schema = sharedRealm->config().schema;
auto object_schema = schema->find(className);
@ -381,15 +384,15 @@ template<typename T>
void Realm<T>::Delete(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 1);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
if (!realm->is_in_transaction()) {
throw std::runtime_error("Can only delete objects within a transaction.");
}
TObject arg = Value::validated_to_object(ctx, arguments[0]);
if (Object::template is_instance<realm::Object>(ctx, arg)) {
auto object = get_internal<T, realm::Object>(arg);
if (Object::template is_instance<RealmObjectClass<T>>(ctx, arg)) {
auto object = get_internal<T, RealmObjectClass<T>>(arg);
realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object->get_object_schema().name);
table->move_last_over(object->row().get_index());
}
@ -398,21 +401,21 @@ void Realm<T>::Delete(TContext ctx, TObject this_object, size_t argc, const TVal
for (uint32_t i = length; i--;) {
TObject object = Object::validated_get_object(ctx, arg, i);
if (!Object::template is_instance<realm::Object>(ctx, object)) {
if (!Object::template is_instance<RealmObjectClass<T>>(ctx, object)) {
throw std::runtime_error("Argument to 'delete' must be a Realm object or a collection of Realm objects.");
}
auto realm_object = get_internal<T, realm::Object>(object);
auto realm_object = get_internal<T, RealmObjectClass<T>>(object);
realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), realm_object->get_object_schema().name);
table->move_last_over(realm_object->row().get_index());
}
}
else if (Object::template is_instance<realm::Results>(ctx, arg)) {
auto results = get_internal<T, realm::Results>(arg);
else if (Object::template is_instance<ResultsClass<T>>(ctx, arg)) {
auto results = get_internal<T, ResultsClass<T>>(arg);
results->clear();
}
else if (Object::template is_instance<realm::List>(ctx, arg)) {
auto list = get_internal<T, realm::List>(arg);
else if (Object::template is_instance<ListClass<T>>(ctx, arg)) {
auto list = get_internal<T, ListClass<T>>(arg);
list->delete_all();
}
else {
@ -424,7 +427,7 @@ template<typename T>
void Realm<T>::DeleteAll(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
if (!realm->is_in_transaction()) {
throw std::runtime_error("Can only delete objects within a transaction.");
@ -439,7 +442,7 @@ template<typename T>
void Realm<T>::Write(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 1);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
TFunction callback = Value::validated_to_function(ctx, arguments[0]);
try {
@ -462,7 +465,7 @@ void Realm<T>::AddListener(TContext ctx, TObject this_object, size_t argc, const
__unused std::string name = validated_notification_name(ctx, arguments[0]);
auto callback = Value::validated_to_function(ctx, arguments[1]);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
get_delegate<T>(realm.get())->add_notification(callback);
}
@ -473,7 +476,7 @@ void Realm<T>::RemoveListener(TContext ctx, TObject this_object, size_t argc, co
__unused std::string name = validated_notification_name(ctx, arguments[0]);
auto callback = Value::validated_to_function(ctx, arguments[1]);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
get_delegate<T>(realm.get())->remove_notification(callback);
}
@ -484,7 +487,7 @@ void Realm<T>::RemoveAllListeners(TContext ctx, TObject this_object, size_t argc
validated_notification_name(ctx, arguments[0]);
}
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
get_delegate<T>(realm.get())->remove_all_notifications();
}
@ -492,7 +495,7 @@ template<typename T>
void Realm<T>::Close(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
SharedRealm realm = *get_internal<T, SharedRealm>(this_object);
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
realm->close();
}

View File

@ -58,7 +58,7 @@ struct Results {
};
template<typename T>
struct ClassDefinition<T, realm::Results> : BaseClassDefinition<T, Collection> {
struct ResultsClass : ClassDefinition<T, realm::Results>, BaseClassDefinition<T, CollectionClass<T>> {
using Results = Results<T>;
std::string const name = "Results";
@ -81,7 +81,7 @@ typename T::Object Results<T>::create_instance(TContext ctx, const realm::Result
auto new_results = new realm::Results(results);
new_results->set_live(live);
return create_object<T, realm::Results>(ctx, new_results);
return create_object<T, ResultsClass<T>>(ctx, new_results);
}
template<typename T>
@ -102,7 +102,7 @@ typename T::Object Results<T>::create_instance(TContext ctx, SharedRealm realm,
auto results = new realm::Results(realm, *object_schema, *table);
results->set_live(live);
return create_object<T, realm::Results>(ctx, results);
return create_object<T, ResultsClass<T>>(ctx, results);
}
template<typename T>
@ -110,7 +110,7 @@ typename T::Object Results<T>::create_instance(TContext ctx, SharedRealm realm,
auto results = new realm::Results(realm, object_schema, std::move(query));
results->set_live(live);
return create_object<T, realm::Results>(ctx, results);
return create_object<T, ResultsClass<T>>(ctx, results);
}
template<typename T>
@ -190,18 +190,18 @@ typename T::Object Results<T>::create_sorted(TContext ctx, const U &collection,
}
auto results = new realm::Results(realm, object_schema, collection.get_query(), {std::move(columns), std::move(ascending)});
return create_object<T, realm::Results>(ctx, results);
return create_object<T, ResultsClass<T>>(ctx, results);
}
template<typename T>
void Results<T>::GetLength(TContext ctx, TObject object, ReturnValue &return_value) {
auto results = get_internal<T, realm::Results>(object);
auto results = get_internal<T, ResultsClass<T>>(object);
return_value.set((uint32_t)results->size());
}
template<typename T>
void Results<T>::GetIndex(TContext ctx, TObject object, uint32_t index, ReturnValue &return_value) {
auto results = get_internal<T, realm::Results>(object);
auto results = get_internal<T, ResultsClass<T>>(object);
auto row = results->get(index);
// Return null for deleted objects in a snapshot.
@ -218,7 +218,7 @@ template<typename T>
void Results<T>::StaticResults(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 0);
auto results = get_internal<T, realm::Results>(this_object);
auto results = get_internal<T, ResultsClass<T>>(this_object);
return_value.set(Results<T>::create_instance(ctx, *results, false));
}
@ -226,7 +226,7 @@ template<typename T>
void Results<T>::Filtered(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count_at_least(argc, 1);
auto results = get_internal<T, realm::Results>(this_object);
auto results = get_internal<T, ResultsClass<T>>(this_object);
return_value.set(create_filtered(ctx, *results, argc, arguments));
}
@ -234,7 +234,7 @@ template<typename T>
void Results<T>::Sorted(TContext ctx, TObject this_object, size_t argc, const TValue arguments[], ReturnValue &return_value) {
validate_argument_count(argc, 1, 2);
auto results = get_internal<T, realm::Results>(this_object);
auto results = get_internal<T, ResultsClass<T>>(this_object);
return_value.set(create_sorted(ctx, *results, argc, arguments));
}

View File

@ -219,17 +219,17 @@ struct Object {
static TObject create_date(TContext, double);
template<typename U>
static TObject create_instance(TContext, U*);
template<typename ClassType>
static TObject create_instance(TContext, typename ClassType::Internal*);
template<typename U>
template<typename ClassType>
static bool is_instance(TContext, const TObject &);
template<typename U>
static U* get_internal(const TObject &);
template<typename ClassType>
static typename ClassType::Internal* get_internal(const TObject &);
template<typename U>
static void set_internal(const TObject &, U*);
template<typename ClassType>
static void set_internal(const TObject &, typename ClassType::Internal*);
};
template<typename TValue>
@ -280,19 +280,19 @@ struct ReturnValue {
void set_undefined();
};
template<typename T, typename U>
REALM_JS_INLINE typename T::Object create_object(typename T::Context ctx, U* internal = nullptr) {
return Object<T>::template create_instance<U>(ctx, internal);
template<typename T, typename ClassType>
REALM_JS_INLINE typename T::Object create_object(typename T::Context ctx, typename ClassType::Internal* internal = nullptr) {
return Object<T>::template create_instance<ClassType>(ctx, internal);
}
template<typename T, typename U>
REALM_JS_INLINE U* get_internal(const typename T::Object &object) {
return Object<T>::template get_internal<U>(object);
template<typename T, typename ClassType>
REALM_JS_INLINE typename ClassType::Internal* get_internal(const typename T::Object &object) {
return Object<T>::template get_internal<ClassType>(object);
}
template<typename T, typename U>
REALM_JS_INLINE void set_internal(const typename T::Object &object, U* ptr) {
Object<T>::template set_internal<U>(object, ptr);
template<typename T, typename ClassType>
REALM_JS_INLINE void set_internal(const typename T::Object &object, typename ClassType::Internal* ptr) {
Object<T>::template set_internal<ClassType>(object, ptr);
}
} // js

View File

@ -28,7 +28,6 @@ namespace jsc {
template<typename T>
using ClassDefinition = js::ClassDefinition<Types, T>;
using BaseClassDefinition = js::BaseClassDefinition<Types>;
using ConstructorType = js::ConstructorType<Types>;
using MethodType = js::MethodType<Types>;
using PropertyType = js::PropertyType<Types>;
@ -37,15 +36,16 @@ using StringPropertyType = js::StringPropertyType<Types>;
using MethodMap = js::MethodMap<Types>;
using PropertyMap = js::PropertyMap<Types>;
template<typename T>
template<typename ClassType>
class ObjectWrap {
public:
operator T*() const {
using Internal = typename ClassType::Internal;
operator Internal*() const {
return m_object.get();
}
ObjectWrap<T>& operator=(T* object) {
ObjectWrap<ClassType>& operator=(Internal* object) {
if (m_object.get() != object) {
m_object = std::unique_ptr<T>(object);
m_object = std::unique_ptr<Internal>(object);
}
return *this;
}
@ -60,8 +60,8 @@ public:
return js_class;
}
static JSObjectRef create_instance(JSContextRef ctx, T* internal = nullptr) {
return JSObjectMake(ctx, get_class(), new ObjectWrap<T>(internal));
static JSObjectRef create_instance(JSContextRef ctx, Internal* internal = nullptr) {
return JSObjectMake(ctx, get_class(), new ObjectWrap<ClassType>(internal));
}
static JSObjectRef create_constructor(JSContextRef ctx) {
@ -77,11 +77,11 @@ public:
}
private:
static ClassDefinition<T> s_class;
static ClassType s_class;
std::unique_ptr<T> m_object;
std::unique_ptr<Internal> m_object;
ObjectWrap(T* object = nullptr) : m_object(object) {}
ObjectWrap(Internal* object = nullptr) : m_object(object) {}
static JSObjectRef construct(JSContextRef ctx, JSObjectRef constructor, size_t argc, const JSValueRef arguments[], JSValueRef* exception) {
if (!s_class.constructor) {
@ -89,7 +89,7 @@ private:
return nullptr;
}
JSObjectRef this_object = ObjectWrap<T>::create_instance(ctx);
JSObjectRef this_object = ObjectWrap<ClassType>::create_instance(ctx);
try {
s_class.constructor(ctx, this_object, argc, arguments);
}
@ -178,7 +178,7 @@ private:
static void finalize(JSObjectRef object) {
// This is called for the most derived class before superclasses.
if (auto wrap = static_cast<ObjectWrap<T> *>(JSObjectGetPrivate(object))) {
if (auto wrap = static_cast<ObjectWrap<ClassType> *>(JSObjectGetPrivate(object))) {
delete wrap;
JSObjectSetPrivate(object, nullptr);
}
@ -283,14 +283,42 @@ private:
}
};
// Make the top-level base class return a NULL JSClassRef.
template<>
inline JSClassRef ObjectWrap<void>::get_class() {
return nullptr;
}
class ObjectWrap<void> {
public:
using Internal = void;
operator Internal*() const {
return nullptr;
}
ObjectWrap<void>& operator=(Internal* object) {
return *this;
}
static JSClassRef get_class() {
return nullptr;
}
static JSClassRef get_constructor_class() {
return nullptr;
}
static JSObjectRef create_instance(JSContextRef ctx, Internal* internal = nullptr) {
return nullptr;
}
static JSObjectRef create_constructor(JSContextRef ctx) {
return nullptr;
}
static bool has_instance(JSContextRef ctx, JSValueRef value) {
return nullptr;
}
};
// The declared static variables must be defined as well.
template<typename T> ClassDefinition<T> ObjectWrap<T>::s_class;
template<typename T> T ObjectWrap<T>::s_class;
} // jsc

View File

@ -481,27 +481,27 @@ inline JSObjectRef jsc::Object::create_date(JSContextRef ctx, double time) {
}
template<>
template<typename U>
inline JSObjectRef jsc::Object::create_instance(JSContextRef ctx, U* internal) {
return jsc::ObjectWrap<U>::create_instance(ctx, internal);
template<typename ClassType>
inline JSObjectRef jsc::Object::create_instance(JSContextRef ctx, typename ClassType::Internal* internal) {
return jsc::ObjectWrap<ClassType>::create_instance(ctx, internal);
}
template<>
template<typename U>
template<typename ClassType>
inline bool jsc::Object::is_instance(JSContextRef ctx, const JSObjectRef &object) {
return jsc::ObjectWrap<U>::has_instance(ctx, object);
return jsc::ObjectWrap<ClassType>::has_instance(ctx, object);
}
template<>
template<typename U>
inline U* jsc::Object::get_internal(const JSObjectRef &object) {
return *static_cast<jsc::ObjectWrap<U> *>(JSObjectGetPrivate(object));
template<typename ClassType>
inline typename ClassType::Internal* jsc::Object::get_internal(const JSObjectRef &object) {
return *static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
}
template<>
template<typename U>
inline void jsc::Object::set_internal(const JSObjectRef &object, U* ptr) {
auto wrap = static_cast<jsc::ObjectWrap<U> *>(JSObjectGetPrivate(object));
template<typename ClassType>
inline void jsc::Object::set_internal(const JSObjectRef &object, typename ClassType::Internal* ptr) {
auto wrap = static_cast<jsc::ObjectWrap<ClassType> *>(JSObjectGetPrivate(object));
*wrap = ptr;
}

View File

@ -24,6 +24,7 @@
#include "rpc.hpp"
#include "jsc_init.hpp"
#include "jsc_types.hpp"
#include "js_object.hpp"
#include "js_results.hpp"
#include "js_realm.hpp"
@ -86,21 +87,21 @@ RPCServer::RPCServer() {
};
m_requests["/begin_transaction"] = [this](const json dict) {
RPCObjectID realm_id = dict["realmId"].get<RPCObjectID>();
SharedRealm realm = *jsc::Object::get_internal<SharedRealm>(m_objects[realm_id]);
SharedRealm realm = *jsc::Object::get_internal<js::RealmClass<jsc::Types>>(m_objects[realm_id]);
realm->begin_transaction();
return json::object();
};
m_requests["/cancel_transaction"] = [this](const json dict) {
RPCObjectID realm_id = dict["realmId"].get<RPCObjectID>();
SharedRealm realm = *jsc::Object::get_internal<SharedRealm>(m_objects[realm_id]);
SharedRealm realm = *jsc::Object::get_internal<js::RealmClass<jsc::Types>>(m_objects[realm_id]);
realm->cancel_transaction();
return json::object();
};
m_requests["/commit_transaction"] = [this](const json dict) {
RPCObjectID realm_id = dict["realmId"].get<RPCObjectID>();
SharedRealm realm = *jsc::Object::get_internal<SharedRealm>(m_objects[realm_id]);
SharedRealm realm = *jsc::Object::get_internal<js::RealmClass<jsc::Types>>(m_objects[realm_id]);
realm->commit_transaction();
return json::object();
@ -220,16 +221,16 @@ json RPCServer::serialize_json_value(JSValueRef js_value) {
JSObjectRef js_object = jsc::Value::validated_to_object(m_context, js_value);
if (jsc::Object::is_instance<realm::Object>(m_context, js_object)) {
auto object = jsc::Object::get_internal<realm::Object>(js_object);
if (jsc::Object::is_instance<js::RealmObjectClass<jsc::Types>>(m_context, js_object)) {
auto object = jsc::Object::get_internal<js::RealmObjectClass<jsc::Types>>(js_object);
return {
{"type", RealmObjectTypesObject},
{"id", store_object(js_object)},
{"schema", serialize_object_schema(object->get_object_schema())}
};
}
else if (jsc::Object::is_instance<realm::List>(m_context, js_object)) {
auto list = jsc::Object::get_internal<realm::List>(js_object);
else if (jsc::Object::is_instance<js::ListClass<jsc::Types>>(m_context, js_object)) {
auto list = jsc::Object::get_internal<js::ListClass<jsc::Types>>(js_object);
return {
{"type", RealmObjectTypesList},
{"id", store_object(js_object)},
@ -237,8 +238,8 @@ json RPCServer::serialize_json_value(JSValueRef js_value) {
{"schema", serialize_object_schema(list->get_object_schema())}
};
}
else if (jsc::Object::is_instance<realm::Results>(m_context, js_object)) {
auto results = jsc::Object::get_internal<realm::Results>(js_object);
else if (jsc::Object::is_instance<js::ResultsClass<jsc::Types>>(m_context, js_object)) {
auto results = jsc::Object::get_internal<js::ResultsClass<jsc::Types>>(js_object);
return {
{"type", RealmObjectTypesResults},
{"id", store_object(js_object)},