mirror of
https://github.com/status-im/realm-js.git
synced 2025-02-17 09:06:26 +00:00
Merge pull request #117 from realm/sk-listener-fixes
Make sure Realm.addListener uniques on callbacks and doesn't leak memory
This commit is contained in:
commit
14f0b0e3de
14
lib/realm.js
14
lib/realm.js
@ -42,7 +42,7 @@ class Realm {
|
|||||||
this[keys.id] = realmId;
|
this[keys.id] = realmId;
|
||||||
this[keys.realm] = realmId;
|
this[keys.realm] = realmId;
|
||||||
this[keys.type] = objectTypes.REALM;
|
this[keys.type] = objectTypes.REALM;
|
||||||
this[listenersKey] = [];
|
this[listenersKey] = new Set();
|
||||||
|
|
||||||
[
|
[
|
||||||
'path',
|
'path',
|
||||||
@ -59,28 +59,24 @@ class Realm {
|
|||||||
if (name != 'change') {
|
if (name != 'change') {
|
||||||
throw new Error("Only 'change' notification is supported.");
|
throw new Error("Only 'change' notification is supported.");
|
||||||
}
|
}
|
||||||
this[listenersKey].push(callback);
|
this[listenersKey].add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeListener(name, callback) {
|
removeListener(name, callback) {
|
||||||
if (typeof callback != 'function') {
|
if (typeof callback != 'function') {
|
||||||
throw new Error('Realm.addListener must be passed a function!');
|
throw new Error('Realm.removeListener must be passed a function!');
|
||||||
}
|
}
|
||||||
if (name != 'change') {
|
if (name != 'change') {
|
||||||
throw new Error("Only 'change' notification is supported.");
|
throw new Error("Only 'change' notification is supported.");
|
||||||
}
|
}
|
||||||
|
this[listenersKey].delete(callback);
|
||||||
let index = 0;
|
|
||||||
while ((index = this[listenersKey].indexOf(callback, index)) != -1) {
|
|
||||||
this[listenersKey].splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllListeners(name) {
|
removeAllListeners(name) {
|
||||||
if (name != undefined && name != 'change') {
|
if (name != undefined && name != 'change') {
|
||||||
throw new Error("Only 'change' notification is supported.");
|
throw new Error("Only 'change' notification is supported.");
|
||||||
}
|
}
|
||||||
this[listenersKey] = [];
|
this[listenersKey].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
write(callback) {
|
write(callback) {
|
||||||
|
@ -49,12 +49,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void add_notification(JSObjectRef notification) {
|
void add_notification(JSObjectRef notification) {
|
||||||
JSValueProtect(m_context, notification);
|
if (!m_notifications.count(notification)) {
|
||||||
m_notifications.insert(notification);
|
JSValueProtect(m_context, notification);
|
||||||
|
m_notifications.insert(notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void remove_notification(JSObjectRef notification) {
|
void remove_notification(JSObjectRef notification) {
|
||||||
JSValueUnprotect(m_context, notification);
|
if (m_notifications.count(notification)) {
|
||||||
m_notifications.erase(notification);
|
JSValueUnprotect(m_context, notification);
|
||||||
|
m_notifications.erase(notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void remove_all_notifications() {
|
void remove_all_notifications() {
|
||||||
for (auto notification : m_notifications) {
|
for (auto notification : m_notifications) {
|
||||||
|
@ -289,8 +289,11 @@ module.exports = BaseTest.extend({
|
|||||||
var secondNotificationCount = 0;
|
var secondNotificationCount = 0;
|
||||||
function secondNotification(realm, name) {
|
function secondNotification(realm, name) {
|
||||||
secondNotificationCount++;
|
secondNotificationCount++;
|
||||||
};
|
}
|
||||||
realm.addListener('change', secondNotification)
|
|
||||||
|
// The listener should only be added once.
|
||||||
|
realm.addListener('change', secondNotification);
|
||||||
|
realm.addListener('change', secondNotification);
|
||||||
|
|
||||||
realm.write(function() {});
|
realm.write(function() {});
|
||||||
TestCase.assertEqual(notificationCount, 2);
|
TestCase.assertEqual(notificationCount, 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user