mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Fabric: Bunch of small changes in ContextContainer
Summary: So, changes: * Correctness checks only in debug mode (codesize win?); * `registerInstance` marked as const (because it's thread safe); * ContextContainer::Shared also enforces constness; * Using faster better::map; * Using shared/RW mutex instead of regular one; * SharedContextContainer got removed. Reviewed By: sahrens Differential Revision: D14920284 fbshipit-source-id: f0f8d970e7fae79a1abe3bc32827db9fd2d17e13
This commit is contained in:
committed by
Facebook Github Bot
parent
cdf3343dd0
commit
184cfd5594
@@ -28,7 +28,7 @@ namespace react {
|
||||
*/
|
||||
ComponentRegistryFactory getDefaultComponentRegistryFactory() {
|
||||
return [](const EventDispatcher::Shared &eventDispatcher,
|
||||
const SharedContextContainer &contextContainer) {
|
||||
const ContextContainer::Shared &contextContainer) {
|
||||
auto registry = std::make_shared<ComponentDescriptorRegistry>();
|
||||
registry->registerComponentDescriptor(std::make_shared<ViewComponentDescriptor>(eventDispatcher));
|
||||
registry->registerComponentDescriptor(std::make_shared<ImageComponentDescriptor>(eventDispatcher, contextContainer));
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import <react/core/LayoutConstraints.h>
|
||||
#import <react/core/LayoutContext.h>
|
||||
#import <react/mounting/ShadowViewMutation.h>
|
||||
#import <react/utils/ContextContainer.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -37,7 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@property (atomic, weak, nullable) id<RCTSchedulerDelegate> delegate;
|
||||
|
||||
- (instancetype)initWithContextContainer:(std::shared_ptr<void>)contextContatiner;
|
||||
- (instancetype)initWithContextContainer:(facebook::react::ContextContainer::Shared)contextContatiner;
|
||||
|
||||
- (void)startSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId
|
||||
moduleName:(NSString *)moduleName
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#import <react/uimanager/ComponentDescriptorFactory.h>
|
||||
#import <react/uimanager/Scheduler.h>
|
||||
#import <react/uimanager/SchedulerDelegate.h>
|
||||
#import <react/utils/ContextContainer.h>
|
||||
|
||||
#import <React/RCTFollyConvert.h>
|
||||
|
||||
@@ -48,12 +47,11 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
|
||||
std::shared_ptr<SchedulerDelegateProxy> _delegateProxy;
|
||||
}
|
||||
|
||||
- (instancetype)initWithContextContainer:(std::shared_ptr<void>)contextContainer
|
||||
- (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContainer
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_delegateProxy = std::make_shared<SchedulerDelegateProxy>((__bridge void *)self);
|
||||
_scheduler = std::make_shared<Scheduler>(
|
||||
std::static_pointer_cast<ContextContainer>(contextContainer), getDefaultComponentRegistryFactory());
|
||||
_scheduler = std::make_shared<Scheduler>(contextContainer, getDefaultComponentRegistryFactory());
|
||||
_scheduler->setDelegate(_delegateProxy.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
config:(std::shared_ptr<const facebook::react::ReactNativeConfig>)config;
|
||||
|
||||
@property (nonatomic, readonly) RCTComponentViewFactory *componentViewFactory;
|
||||
@property (nonatomic, readonly) facebook::react::SharedContextContainer contextContainer;
|
||||
@property (nonatomic, readonly) facebook::react::ContextContainer::Shared contextContainer;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ using namespace facebook::react;
|
||||
|
||||
@synthesize contextContainer = _contextContainer;
|
||||
|
||||
- (SharedContextContainer)contextContainer
|
||||
- (ContextContainer::Shared)contextContainer
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_contextContainerMutex);
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ void Binding::installFabricUIManager(
|
||||
jni::alias_ref<jobject> reactNativeConfig) {
|
||||
javaUIManager_ = make_global(javaUIManager);
|
||||
|
||||
SharedContextContainer contextContainer =
|
||||
ContextContainer::Shared contextContainer =
|
||||
std::make_shared<ContextContainer>();
|
||||
|
||||
auto sharedJSMessageQueueThread =
|
||||
|
||||
@@ -23,7 +23,7 @@ class ImageComponentDescriptor final
|
||||
public:
|
||||
ImageComponentDescriptor(
|
||||
EventDispatcher::Shared eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
: ConcreteComponentDescriptor(eventDispatcher),
|
||||
// TODO (39486757): implement image manager on Android, currently Android does
|
||||
// not have an ImageManager so this will crash
|
||||
|
||||
@@ -22,7 +22,7 @@ class SliderComponentDescriptor final
|
||||
public:
|
||||
SliderComponentDescriptor(
|
||||
EventDispatcher::Shared eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
: ConcreteComponentDescriptor(eventDispatcher),
|
||||
// TODO (39486757): implement image manager on Android, currently Android does
|
||||
// not have an ImageManager so this will crash
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace react {
|
||||
*/
|
||||
class SliderMeasurementsManager {
|
||||
public:
|
||||
SliderMeasurementsManager(const SharedContextContainer &contextContainer)
|
||||
SliderMeasurementsManager(const ContextContainer::Shared &contextContainer)
|
||||
: contextContainer_(contextContainer) {}
|
||||
|
||||
static inline bool shouldMeasureSlider() {
|
||||
@@ -30,7 +30,7 @@ class SliderMeasurementsManager {
|
||||
Size measure(LayoutConstraints layoutConstraints) const;
|
||||
|
||||
private:
|
||||
const SharedContextContainer contextContainer_;
|
||||
const ContextContainer::Shared contextContainer_;
|
||||
mutable std::mutex mutex_;
|
||||
mutable bool hasBeenMeasured_ = false;
|
||||
mutable Size cachedMeasurement_{};
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace react {
|
||||
*/
|
||||
class SliderMeasurementsManager {
|
||||
public:
|
||||
SliderMeasurementsManager(const SharedContextContainer &contextContainer) {}
|
||||
SliderMeasurementsManager(ContextContainer::Shared const &contextContainer) {}
|
||||
|
||||
static inline bool shouldMeasureSlider() {
|
||||
return false;
|
||||
|
||||
@@ -27,7 +27,7 @@ class ParagraphComponentDescriptor final
|
||||
public:
|
||||
ParagraphComponentDescriptor(
|
||||
EventDispatcher::Shared eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
: ConcreteComponentDescriptor<ParagraphShadowNode>(eventDispatcher) {
|
||||
// Every single `ParagraphShadowNode` will have a reference to
|
||||
// a shared `TextLayoutManager`.
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace react {
|
||||
*/
|
||||
ComponentRegistryFactory getDefaultComponentRegistryFactory() {
|
||||
return [](const EventDispatcher::Shared &eventDispatcher,
|
||||
const SharedContextContainer &contextContainer) {
|
||||
const ContextContainer::Shared &contextContainer) {
|
||||
auto registry = std::make_shared<ComponentDescriptorRegistry>();
|
||||
return registry;
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ using SharedTextLayoutManager = std::shared_ptr<const TextLayoutManager>;
|
||||
*/
|
||||
class TextLayoutManager {
|
||||
public:
|
||||
TextLayoutManager(const SharedContextContainer &contextContainer)
|
||||
TextLayoutManager(const ContextContainer::Shared &contextContainer)
|
||||
: contextContainer_(contextContainer){};
|
||||
~TextLayoutManager();
|
||||
|
||||
@@ -47,7 +47,7 @@ class TextLayoutManager {
|
||||
private:
|
||||
void *self_;
|
||||
|
||||
SharedContextContainer contextContainer_;
|
||||
ContextContainer::Shared contextContainer_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -26,7 +26,7 @@ using SharedTextLayoutManager = std::shared_ptr<const TextLayoutManager>;
|
||||
*/
|
||||
class TextLayoutManager {
|
||||
public:
|
||||
TextLayoutManager(const SharedContextContainer &contextContainer);
|
||||
TextLayoutManager(ContextContainer::Shared const &contextContainer);
|
||||
~TextLayoutManager();
|
||||
|
||||
/*
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
TextLayoutManager::TextLayoutManager(
|
||||
const SharedContextContainer &contextContainer) {
|
||||
TextLayoutManager::TextLayoutManager(ContextContainer::Shared const &contextContainer)
|
||||
{
|
||||
self_ = (__bridge_retained void *)[RCTTextLayoutManager new];
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace react {
|
||||
*/
|
||||
using ComponentRegistryFactory =
|
||||
std::function<SharedComponentDescriptorRegistry(
|
||||
const EventDispatcher::Shared &eventDispatcher,
|
||||
const SharedContextContainer &contextContainer)>;
|
||||
EventDispatcher::Shared const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer)>;
|
||||
|
||||
ComponentRegistryFactory getDefaultComponentRegistryFactory();
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace facebook {
|
||||
namespace react {
|
||||
|
||||
Scheduler::Scheduler(
|
||||
const SharedContextContainer &contextContainer,
|
||||
ContextContainer::Shared const &contextContainer,
|
||||
ComponentRegistryFactory buildRegistryFunction) {
|
||||
const auto asynchronousEventBeatFactory =
|
||||
contextContainer->getInstance<EventBeatFactory>("asynchronous");
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace react {
|
||||
class Scheduler final : public UIManagerDelegate, public ShadowTreeDelegate {
|
||||
public:
|
||||
Scheduler(
|
||||
const SharedContextContainer &contextContainer,
|
||||
ContextContainer::Shared const &contextContainer,
|
||||
ComponentRegistryFactory buildRegistryFunction);
|
||||
~Scheduler();
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/uimanager/ComponentDescriptorFactory.h>
|
||||
#include <react/uimanager/UITemplateProcessor.h>
|
||||
@@ -31,7 +32,7 @@ namespace react {
|
||||
// TODO (T29441913): Codegen this app-specific implementation.
|
||||
ComponentRegistryFactory getDefaultComponentRegistryFactory() {
|
||||
return [](const EventDispatcher::Shared &eventDispatcher,
|
||||
const SharedContextContainer &contextContainer) {
|
||||
const ContextContainer::Shared &contextContainer) {
|
||||
auto registry = std::make_shared<ComponentDescriptorRegistry>();
|
||||
registry->registerComponentDescriptor(
|
||||
std::make_shared<ViewComponentDescriptor>(eventDispatcher));
|
||||
|
||||
@@ -8,24 +8,21 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <glog/logging.h>
|
||||
#include <better/map.h>
|
||||
#include <better/mutex.h>
|
||||
#include <better/optional.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class ContextContainer;
|
||||
|
||||
using SharedContextContainer = std::shared_ptr<ContextContainer>;
|
||||
|
||||
/*
|
||||
* General purpose dependecy injection container.
|
||||
* Instance types must be copyable.
|
||||
*/
|
||||
class ContextContainer final {
|
||||
public:
|
||||
using Shared = std::shared_ptr<ContextContainer>;
|
||||
using Shared = std::shared_ptr<const ContextContainer>;
|
||||
|
||||
/*
|
||||
* Registers an instance of the particular type `T` in the container
|
||||
@@ -38,14 +35,13 @@ class ContextContainer final {
|
||||
*`EmptyReactNativeConfig`.
|
||||
*/
|
||||
template <typename T>
|
||||
void registerInstance(T const &instance, std::string const &key) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
void registerInstance(T const &instance, std::string const &key) const {
|
||||
std::unique_lock<better::shared_mutex> lock(mutex_);
|
||||
|
||||
auto res = instances_.insert({key, std::make_shared<T>(instance)});
|
||||
if (res.second == false) {
|
||||
LOG(FATAL) << "ContextContainer already had instance for key '" << key
|
||||
<< "'";
|
||||
}
|
||||
assert(
|
||||
instances_.find(key) == instances_.end() &&
|
||||
"ContextContainer already had instance for given key.");
|
||||
instances_.insert({key, std::make_shared<T>(instance)});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -54,15 +50,18 @@ class ContextContainer final {
|
||||
*/
|
||||
template <typename T>
|
||||
T getInstance(std::string const &key) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::shared_lock<better::shared_mutex> lock(mutex_);
|
||||
|
||||
assert(
|
||||
instances_.find(key) != instances_.end() &&
|
||||
"ContextContainer doesn't have an instance for given key.");
|
||||
return *std::static_pointer_cast<T>(instances_.at(key));
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<void>> instances_;
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
mutable better::shared_mutex mutex_;
|
||||
// Protected by mutex_`.
|
||||
mutable better::map<std::string, std::shared_ptr<void>> instances_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user