amis-rpc-design/node_modules/react-native/React/Fabric/Utils/PlatformRunLoopObserver.mm
2023-10-07 19:42:30 +08:00

98 lines
2.8 KiB
Plaintext

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "PlatformRunLoopObserver.h"
#import <mutex>
namespace facebook {
namespace react {
static CFRunLoopActivity toCFRunLoopActivity(RunLoopObserver::Activity activity)
{
auto result = CFRunLoopActivity{};
if (RunLoopObserver::Activity(activity & RunLoopObserver::Activity::BeforeWaiting) ==
RunLoopObserver::Activity::BeforeWaiting) {
result = result | kCFRunLoopBeforeWaiting;
}
if (RunLoopObserver::Activity(activity & RunLoopObserver::Activity::AfterWaiting) ==
RunLoopObserver::Activity::AfterWaiting) {
result = result | kCFRunLoopAfterWaiting;
}
return result;
}
static RunLoopObserver::Activity toRunLoopActivity(CFRunLoopActivity activity)
{
auto result = RunLoopObserver::Activity{};
if (CFRunLoopActivity(activity & kCFRunLoopBeforeWaiting) == kCFRunLoopBeforeWaiting) {
result = RunLoopObserver::Activity(result | RunLoopObserver::Activity::BeforeWaiting);
}
if (CFRunLoopActivity(activity & kCFRunLoopAfterWaiting) == kCFRunLoopAfterWaiting) {
result = RunLoopObserver::Activity(result | RunLoopObserver::Activity::AfterWaiting);
}
return result;
}
PlatformRunLoopObserver::PlatformRunLoopObserver(
RunLoopObserver::Activity activities,
RunLoopObserver::WeakOwner const &owner,
CFRunLoopRef runLoop)
: RunLoopObserver(activities, owner), runLoop_(runLoop)
{
// A value (not a reference) to be captured by the block.
auto weakOwner = owner;
// The documentation for `CFRunLoop` family API states that all of the methods are thread-safe.
// See "Thread Safety and Run Loop Objects" section of the "Threading Programming Guide" for more details.
mainRunLoopObserver_ = CFRunLoopObserverCreateWithHandler(
NULL /* allocator */,
toCFRunLoopActivity(activities_) /* activities */,
true /* repeats */,
0 /* order */,
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
auto strongOwner = weakOwner.lock();
if (!strongOwner) {
return;
}
this->activityDidChange(toRunLoopActivity(activity));
});
assert(mainRunLoopObserver_);
}
PlatformRunLoopObserver::~PlatformRunLoopObserver()
{
stopObserving();
CFRelease(mainRunLoopObserver_);
}
void PlatformRunLoopObserver::startObserving() const noexcept
{
CFRunLoopAddObserver(runLoop_, mainRunLoopObserver_, kCFRunLoopCommonModes);
}
void PlatformRunLoopObserver::stopObserving() const noexcept
{
CFRunLoopRemoveObserver(runLoop_, mainRunLoopObserver_, kCFRunLoopCommonModes);
}
bool PlatformRunLoopObserver::isOnRunLoopThread() const noexcept
{
return CFRunLoopGetCurrent() == runLoop_;
}
} // namespace react
} // namespace facebook