Skip to content

Commit 2d8f639

Browse files
authored
Merge pull request #1023 from jpudysz/feature/mutex-and-listener-id
feat: improve native callbacks with mutex and unique ids
2 parents 29e71b7 + a9d65b0 commit 2d8f639

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

cxx/hybridObjects/HybridStyleSheet.cpp

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,9 @@ void HybridStyleSheet::loadExternalMethods(const jsi::Value& thisValue, jsi::Run
251251
auto maybeProcessColorFn = jsMethods.asObject(rt).getProperty(rt, "processColor");
252252

253253
helpers::assertThat(rt, maybeProcessColorFn.isObject(), "Unistyles: Can't load processColor function from JS.");
254-
254+
255255
auto maybeParseBoxShadowStringFn = jsMethods.asObject(rt).getProperty(rt, "parseBoxShadowString");
256-
256+
257257
helpers::assertThat(rt, maybeParseBoxShadowStringFn.isObject(), "Unistyles: Can't load parseBoxShadowString function from JS.");
258258

259259
auto processColorFn = maybeProcessColorFn.asObject(rt).asFunction(rt);
@@ -386,25 +386,36 @@ void HybridStyleSheet::onImeChange(UnistylesNativeMiniRuntime miniRuntime) {
386386
}
387387

388388
void HybridStyleSheet::notifyJSListeners(std::vector<UnistyleDependency>& dependencies) {
389-
if (!dependencies.empty()) {
390-
std::for_each(this->_changeListeners.begin(), this->_changeListeners.end(), [&](auto& listener){
391-
(*listener)(dependencies);
392-
});
389+
if (dependencies.empty()) {
390+
return;
391+
}
392+
393+
std::vector<std::function<void(std::vector<UnistyleDependency>&)>> callbacks;
394+
{
395+
std::lock_guard<std::mutex> lock(this->_listenersMutex);
396+
callbacks.reserve(this->_changeListeners.size());
397+
398+
for (auto& [id, listener] : this->_changeListeners) {
399+
callbacks.push_back(*listener);
400+
}
401+
}
402+
403+
for (auto& callback : callbacks) {
404+
callback(dependencies);
393405
}
394406
}
395407

396408
std::function<void ()> HybridStyleSheet::addChangeListener(const std::function<void (const std::vector<UnistyleDependency>&)>& onChanged) {
397-
auto listener = std::make_unique<std::function<void(std::vector<UnistyleDependency>&)>>(onChanged);
409+
static size_t nextListenerId = 0;
398410

399-
this->_changeListeners.push_back(std::move(listener));
411+
std::lock_guard<std::mutex> lock(this->_listenersMutex);
400412

401-
return [this, listenerPtr = this->_changeListeners.back().get()](){
402-
auto it = std::find_if(this->_changeListeners.begin(), this->_changeListeners.end(), [listenerPtr](auto& ptr) {
403-
return ptr.get() == listenerPtr;
404-
});
413+
size_t id = nextListenerId++;
414+
auto listener = std::make_unique<std::function<void(std::vector<UnistyleDependency>&)>>(onChanged);
415+
this->_changeListeners[id] = std::move(listener);
405416

406-
if (it != this->_changeListeners.end()) {
407-
this->_changeListeners.erase(it);
408-
}
417+
return [this, id](){
418+
std::lock_guard<std::mutex> lock(this->_listenersMutex);
419+
this->_changeListeners.erase(id);
409420
};
410421
}

cxx/hybridObjects/HybridStyleSheet.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <cmath>
44
#include <jsi/jsi.h>
5+
#include <mutex>
6+
#include <unordered_map>
57
#include "HybridUnistylesRuntime.h"
68
#include "HybridUnistylesStyleSheetSpec.hpp"
79
#include "RNStyle.h"
@@ -72,7 +74,8 @@ struct HybridStyleSheet: public HybridUnistylesStyleSheetSpec {
7274

7375
bool isInitialized = false;
7476
double __unid = -1;
75-
std::vector<std::unique_ptr<const std::function<void(std::vector<UnistyleDependency>&)>>> _changeListeners{};
77+
std::unordered_map<size_t, std::unique_ptr<std::function<void(std::vector<UnistyleDependency>&)>>> _changeListeners{};
78+
std::mutex _listenersMutex;
7679
std::shared_ptr<HybridUnistylesRuntime> _unistylesRuntime;
7780
std::shared_ptr<UIManager> _uiManager;
7881
};

0 commit comments

Comments
 (0)