Skip to content

Commit

Permalink
Fabric: Moving RNWrapManagedObject to react/utils module
Browse files Browse the repository at this point in the history
Summary: Apparently we can/should not have in RCTConversions because it creates unnecessary dependency to core iOS module.

Reviewed By: mdvacca

Differential Revision: D15055325

fbshipit-source-id: 507f5a40c03b5c261967de4504297d31ecd02783
  • Loading branch information
shergin authored and facebook-github-bot committed Apr 30, 2019
1 parent 718ffe5 commit a0523da
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 23 deletions.
21 changes: 0 additions & 21 deletions React/Fabric/RCTConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,6 @@

NS_ASSUME_NONNULL_BEGIN

/*
* `RNWrapManagedObject` and `RNUnwrapManagedObject` are wrapper functions that convert ARC-managed objects into
* `std::shared_ptr<void>` and vice-versa. It's a very useful mechanism when we need to pass Objective-C objects through
* pure C++ code, pass blocks into C++ lambdas, and so on.
*
* The idea behind this mechanism is quite simple but tricky: When we instantiate a C++ shared pointer for a managed
* object, we practically call `CFRetain` for it once and then we represent this single retaining operation as a counter
* inside the shared pointer; when the counter became zero, we call `CFRelease` on the object. In this model, one bump
* of ARC-managed counter is represented as multiple bumps of C++ counter, so we can have multiple counters for the same
* object that form some kind of counters tree.
*/
inline std::shared_ptr<void> RNWrapManagedObject(id object)
{
return std::shared_ptr<void>((__bridge_retained void *)object, CFRelease);
}

inline id RNUnwrapManagedObject(std::shared_ptr<void> const &object)
{
return (__bridge id)object.get();
}

inline NSString *RCTNSStringFromString(const std::string &string, const NSStringEncoding &encoding = NSUTF8StringEncoding) {
return [NSString stringWithCString:string.c_str() encoding:encoding];
}
Expand Down
6 changes: 4 additions & 2 deletions React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
#import <React/RCTSurfaceView+Internal.h>
#import <React/RCTSurfaceView.h>
#import <React/RCTUtils.h>

#import <react/components/root/RootShadowNode.h>
#import <react/core/LayoutConstraints.h>
#import <react/core/LayoutContext.h>
#import <react/imagemanager/ImageManager.h>
#import <react/uimanager/ComponentDescriptorFactory.h>
#import <react/utils/ContextContainer.h>
#import <react/utils/ManagedObjectWrapper.h>

#import "MainRunLoopEventBeat.h"
#import "RuntimeEventBeat.h"
Expand Down Expand Up @@ -195,10 +197,10 @@ - (RCTScheduler *)_scheduler
return _scheduler;
}

auto componentRegistryFactory = [factory = RNWrapManagedObject(self.componentViewFactory)](
auto componentRegistryFactory = [factory = wrapManagedObject(self.componentViewFactory)](
EventDispatcher::Shared const &eventDispatcher,
ContextContainer::Shared const &contextContainer) {
return [(RCTComponentViewFactory *)RNUnwrapManagedObject(factory)
return [(RCTComponentViewFactory *)unwrapManagedObject(factory)
createComponentDescriptorRegistryWithParameters:{eventDispatcher, contextContainer}];
};

Expand Down
44 changes: 44 additions & 0 deletions ReactCommon/utils/ManagedObjectWrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#ifdef __OBJC__
#ifdef __cplusplus

#include <memory>

namespace facebook {
namespace react {

/*
* `wrapManagedObject` and `unwrapManagedObject` are wrapper functions that
* convert ARC-managed objects into `std::shared_ptr<void>` and vice-versa. It's
* a very useful mechanism when we need to pass Objective-C objects through pure
* C++ code, pass blocks into C++ lambdas, and so on.
*
* The idea behind this mechanism is quite simple but tricky: When we
* instantiate a C++ shared pointer for a managed object, we practically call
* `CFRetain` for it once and then we represent this single retaining operation
* as a counter inside the shared pointer; when the counter became zero, we call
* `CFRelease` on the object. In this model, one bump of ARC-managed counter is
* represented as multiple bumps of C++ counter, so we can have multiple
* counters for the same object that form some kind of counters tree.
*/
inline std::shared_ptr<void> wrapManagedObject(id object) {
return std::shared_ptr<void>((__bridge_retained void *)object, CFRelease);
}

inline id unwrapManagedObject(std::shared_ptr<void> const &object) {
return (__bridge id)object.get();
}

} // namespace react
} // namespace facebook

#endif
#endif

0 comments on commit a0523da

Please sign in to comment.