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:
Valentin Shergin
2019-04-16 07:23:05 -07:00
committed by Facebook Github Bot
parent cdf3343dd0
commit 184cfd5594
20 changed files with 43 additions and 44 deletions

View File

@@ -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));

View File

@@ -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

View File

@@ -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());
}

View File

@@ -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

View File

@@ -201,7 +201,7 @@ using namespace facebook::react;
@synthesize contextContainer = _contextContainer;
- (SharedContextContainer)contextContainer
- (ContextContainer::Shared)contextContainer
{
std::lock_guard<std::mutex> lock(_contextContainerMutex);

View File

@@ -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 =

View File

@@ -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

View File

@@ -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

View File

@@ -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_{};

View File

@@ -20,7 +20,7 @@ namespace react {
*/
class SliderMeasurementsManager {
public:
SliderMeasurementsManager(const SharedContextContainer &contextContainer) {}
SliderMeasurementsManager(ContextContainer::Shared const &contextContainer) {}
static inline bool shouldMeasureSlider() {
return false;

View File

@@ -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`.

View File

@@ -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;
};

View File

@@ -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

View File

@@ -26,7 +26,7 @@ using SharedTextLayoutManager = std::shared_ptr<const TextLayoutManager>;
*/
class TextLayoutManager {
public:
TextLayoutManager(const SharedContextContainer &contextContainer);
TextLayoutManager(ContextContainer::Shared const &contextContainer);
~TextLayoutManager();
/*

View File

@@ -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];
}

View File

@@ -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();

View File

@@ -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");

View File

@@ -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();

View File

@@ -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));

View File

@@ -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