169 lines
4.7 KiB
C++
169 lines
4.7 KiB
C++
#include <reanimated/Fabric/updates/UpdatesRegistry.h>
|
|
|
|
namespace reanimated {
|
|
|
|
std::lock_guard<std::mutex> UpdatesRegistry::lock() const {
|
|
return std::lock_guard<std::mutex>{mutex_};
|
|
}
|
|
|
|
bool UpdatesRegistry::isEmpty() const {
|
|
return updatesRegistry_.empty();
|
|
}
|
|
|
|
folly::dynamic UpdatesRegistry::get(const Tag tag) const {
|
|
std::lock_guard<std::mutex> lock{mutex_};
|
|
|
|
auto it = updatesRegistry_.find(tag);
|
|
if (it == updatesRegistry_.cend()) {
|
|
return nullptr;
|
|
}
|
|
return it->second.second;
|
|
}
|
|
|
|
void UpdatesRegistry::flushUpdates(UpdatesBatch &updatesBatch) {
|
|
auto copiedUpdatesBatch = std::move(updatesBatch_);
|
|
updatesBatch_.clear();
|
|
|
|
// Store all updates in the registry for later use in the commit hook
|
|
flushUpdatesToRegistry(copiedUpdatesBatch);
|
|
// Flush the updates to the updatesBatch used to apply current changes
|
|
for (auto &[shadowNode, props] : copiedUpdatesBatch) {
|
|
updatesBatch.emplace_back(shadowNode, std::move(props));
|
|
}
|
|
}
|
|
|
|
UpdatesBatch UpdatesRegistry::getPendingUpdates() {
|
|
auto lock = std::lock_guard<std::mutex>{mutex_};
|
|
flushUpdatesToRegistry(updatesBatch_);
|
|
|
|
UpdatesBatch updatesBatch;
|
|
for (const auto &[tag, pair] : updatesRegistry_) {
|
|
const auto &[shadowNode, props] = pair;
|
|
updatesBatch.emplace_back(shadowNode, props);
|
|
}
|
|
return updatesBatch;
|
|
}
|
|
|
|
void UpdatesRegistry::collectProps(PropsMap &propsMap) {
|
|
std::lock_guard<std::mutex> lock{mutex_};
|
|
|
|
auto copiedRegistry = updatesRegistry_;
|
|
for (const auto &[tag, pair] : copiedRegistry) {
|
|
const auto &[shadowNode, props] = pair;
|
|
auto &family = shadowNode->getFamily();
|
|
auto it = propsMap.find(&family);
|
|
|
|
if (it == propsMap.cend()) {
|
|
auto propsVector = std::vector<RawProps>{};
|
|
propsVector.emplace_back(RawProps(props));
|
|
propsMap.emplace(&family, propsVector);
|
|
} else {
|
|
it->second.push_back(RawProps(props));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdatesRegistry::addUpdatesToBatch(
|
|
const std::shared_ptr<const ShadowNode> &shadowNode,
|
|
const folly::dynamic &props) {
|
|
updatesBatch_.emplace_back(shadowNode, props);
|
|
}
|
|
|
|
void UpdatesRegistry::setInUpdatesRegistry(
|
|
const std::shared_ptr<const ShadowNode> &shadowNode,
|
|
const folly::dynamic &props) {
|
|
const auto tag = shadowNode->getTag();
|
|
#ifdef ANDROID
|
|
updatePropsToRevert(tag, &props);
|
|
#endif
|
|
updatesRegistry_[tag] = std::make_pair(shadowNode, props);
|
|
}
|
|
|
|
folly::dynamic UpdatesRegistry::getUpdatesFromRegistry(const Tag tag) const {
|
|
auto it = updatesRegistry_.find(tag);
|
|
if (it == updatesRegistry_.cend()) {
|
|
return folly::dynamic();
|
|
}
|
|
return it->second.second;
|
|
}
|
|
|
|
void UpdatesRegistry::removeFromUpdatesRegistry(const Tag tag) {
|
|
#ifdef ANDROID
|
|
updatePropsToRevert(tag);
|
|
#endif
|
|
updatesRegistry_.erase(tag);
|
|
}
|
|
|
|
void UpdatesRegistry::flushUpdatesToRegistry(const UpdatesBatch &updatesBatch) {
|
|
for (auto &[shadowNode, props] : updatesBatch) {
|
|
const auto tag = shadowNode->getTag();
|
|
auto it = updatesRegistry_.find(tag);
|
|
|
|
if (it == updatesRegistry_.cend()) {
|
|
updatesRegistry_[tag] = std::make_pair(shadowNode, props);
|
|
} else {
|
|
it->second.second.update(props);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef ANDROID
|
|
|
|
bool UpdatesRegistry::hasPropsToRevert() const {
|
|
return !propsToRevertMap_.empty();
|
|
}
|
|
|
|
void UpdatesRegistry::collectPropsToRevert(PropsToRevertMap &propsToRevertMap) {
|
|
std::lock_guard<std::mutex> lock{mutex_};
|
|
|
|
for (const auto &[tag, pair] : propsToRevertMap_) {
|
|
const auto &[shadowNode, props] = pair;
|
|
const auto it = propsToRevertMap.find(tag);
|
|
if (it == propsToRevertMap.end()) {
|
|
propsToRevertMap[tag] = {shadowNode, props};
|
|
} else {
|
|
it->second.props.insert(props.begin(), props.end());
|
|
}
|
|
}
|
|
|
|
propsToRevertMap_.clear();
|
|
}
|
|
|
|
void UpdatesRegistry::updatePropsToRevert(
|
|
const Tag tag,
|
|
const folly::dynamic *newProps) {
|
|
auto it = updatesRegistry_.find(tag);
|
|
if (it == updatesRegistry_.end()) {
|
|
return;
|
|
}
|
|
|
|
const auto &shadowNode = it->second.first;
|
|
const auto ®istryProps = it->second.second;
|
|
if (propsToRevertMap_.find(tag) == propsToRevertMap_.end()) {
|
|
propsToRevertMap_[tag] = {shadowNode, std::unordered_set<std::string>()};
|
|
}
|
|
|
|
if (newProps == nullptr) {
|
|
// If newProps is not provided, revert all props from registry
|
|
for (const auto &propName : registryProps.keys()) {
|
|
propsToRevertMap_[tag].props.emplace(propName.asString());
|
|
}
|
|
} else {
|
|
// If newProps is provided, revert only props that are in registry but not
|
|
// in newProps
|
|
for (const auto &propName : registryProps.keys()) {
|
|
if (newProps->find(propName) == newProps->items().end()) {
|
|
propsToRevertMap_[tag].props.emplace(propName.asString());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (propsToRevertMap_[tag].props.empty()) {
|
|
propsToRevertMap_.erase(tag);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
} // namespace reanimated
|