From c674303dfdeca2816529aae40a374a6e55792005 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 22 Jun 2018 07:28:34 -0700 Subject: [PATCH] Fabric: Introducing `ContextContainer` Summary: @public `ContextContainer` is general purpose DI container for Fabric. We need this to communicate some enviroment-specific and/or platform-specific modules down to cross-platform C++ code. The first one will be ImageManager. Soon. Reviewed By: fkgozali Differential Revision: D8475636 fbshipit-source-id: 0afc65063f818d0bab736cd2c55c6fdd21b629ac --- React/Fabric/RCTScheduler.mm | 5 ++- .../SampleComponentDescriptorFactor.cpp | 6 ++- .../uimanager/ComponentDescriptorFactory.h | 3 +- .../fabric/uimanager/ContextContainer.cpp | 22 ++++++++++ .../fabric/uimanager/ContextContainer.h | 40 +++++++++++++++++++ ReactCommon/fabric/uimanager/Scheduler.cpp | 5 ++- ReactCommon/fabric/uimanager/Scheduler.h | 4 +- 7 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 ReactCommon/fabric/uimanager/ContextContainer.cpp create mode 100644 ReactCommon/fabric/uimanager/ContextContainer.h diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index fcd1a9d8b..79cae1c13 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -7,6 +7,7 @@ #import "RCTScheduler.h" +#import #import #import @@ -41,7 +42,9 @@ private: { if (self = [super init]) { _delegateProxy = std::make_shared((__bridge void *)self); - _scheduler = std::make_shared(); + + SharedContextContainer contextContainer = std::make_shared(); + _scheduler = std::make_shared(contextContainer); _scheduler->setDelegate(_delegateProxy.get()); } diff --git a/ReactCommon/fabric/sample/SampleComponentDescriptorFactor.cpp b/ReactCommon/fabric/sample/SampleComponentDescriptorFactor.cpp index 28a8a8b29..b3066e58f 100644 --- a/ReactCommon/fabric/sample/SampleComponentDescriptorFactor.cpp +++ b/ReactCommon/fabric/sample/SampleComponentDescriptorFactor.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace facebook { namespace react { @@ -14,7 +15,10 @@ namespace react { /** * This is a sample implementation. Each app should provide its own. */ -SharedComponentDescriptorRegistry ComponentDescriptorFactory::buildRegistry(const SharedEventDispatcher &eventDispatcher) { +SharedComponentDescriptorRegistry ComponentDescriptorFactory::buildRegistry( + const SharedEventDispatcher &eventDispatcher, + const SharedContextContainer &contextContainer +) { auto registry = std::make_shared(); return registry; } diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorFactory.h b/ReactCommon/fabric/uimanager/ComponentDescriptorFactory.h index ea6ef34ac..d4c4b965c 100644 --- a/ReactCommon/fabric/uimanager/ComponentDescriptorFactory.h +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorFactory.h @@ -11,6 +11,7 @@ #include #include +#include #include "ComponentDescriptorRegistry.h" @@ -25,7 +26,7 @@ namespace react { class ComponentDescriptorFactory { public: - static SharedComponentDescriptorRegistry buildRegistry(const SharedEventDispatcher &eventDispatcher); + static SharedComponentDescriptorRegistry buildRegistry(const SharedEventDispatcher &eventDispatcher, const SharedContextContainer &contextContainer); }; } // namespace react diff --git a/ReactCommon/fabric/uimanager/ContextContainer.cpp b/ReactCommon/fabric/uimanager/ContextContainer.cpp new file mode 100644 index 000000000..ef2ceb473 --- /dev/null +++ b/ReactCommon/fabric/uimanager/ContextContainer.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2004-present, Facebook, Inc. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#include "ContextContainer.h" + +namespace facebook { +namespace react { + +void ContextContainer::registerInstance(const ClassHandle &handle, SharedInstance instance) { + std::lock_guard lock(mutex_); + instances_.insert({handle, instance}); +} + +const ContextContainer::SharedInstance &ContextContainer::at(const ClassHandle &handle) const { + std::lock_guard lock(mutex_); + return instances_.at(handle); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/uimanager/ContextContainer.h b/ReactCommon/fabric/uimanager/ContextContainer.h new file mode 100644 index 000000000..bec29b6bf --- /dev/null +++ b/ReactCommon/fabric/uimanager/ContextContainer.h @@ -0,0 +1,40 @@ +// Copyright (c) 2004-present, Facebook, Inc. + +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree. + +#pragma once + +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class ContextContainer; + +using SharedContextContainer = std::shared_ptr; + +/* + * General purpose dependecy injection container. + */ +class ContextContainer final { + +public: + using ClassHandle = std::type_index; + using SharedInstance = std::shared_ptr; + + void registerInstance(const ClassHandle &handle, SharedInstance instance); + + const SharedInstance &at(const ClassHandle &handle) const; + +private: + std::unordered_map instances_; + mutable std::mutex mutex_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index bcb89f0ad..8a5f2f6e2 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -22,9 +22,10 @@ namespace facebook { namespace react { -Scheduler::Scheduler() { +Scheduler::Scheduler(const SharedContextContainer &contextContainer): + contextContainer_(contextContainer) { auto &&eventDispatcher = std::make_shared(); - auto &&componentDescriptorRegistry = ComponentDescriptorFactory::buildRegistry(eventDispatcher); + auto &&componentDescriptorRegistry = ComponentDescriptorFactory::buildRegistry(eventDispatcher, contextContainer); uiManager_ = std::make_shared(componentDescriptorRegistry); uiManager_->setDelegate(this); diff --git a/ReactCommon/fabric/uimanager/Scheduler.h b/ReactCommon/fabric/uimanager/Scheduler.h index 6b6fae79d..036d3cef4 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.h +++ b/ReactCommon/fabric/uimanager/Scheduler.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,7 @@ class Scheduler final: public: - Scheduler(); + Scheduler(const SharedContextContainer &contextContainer); ~Scheduler(); #pragma mark - Shadow Tree Management @@ -74,6 +75,7 @@ private: std::shared_ptr uiManager_; std::unordered_map shadowTreeRegistry_; SharedSchedulerEventDispatcher eventDispatcher_; + SharedContextContainer contextContainer_; }; } // namespace react