fabric: send events via JS thread
Summary: Calling the event emitters on the main thread seems to be problematic, so let's dispatch it via the JS thread. This requires some changes to make "eventTarget" single-use because otherwise the binding would need to synchronize the actual JS call with the act of releasing the target. Reviewed By: shergin Differential Revision: D8375291 fbshipit-source-id: bd2b42731176ae209f4a19c232309c163fb1c01b
This commit is contained in:
parent
0883e52c74
commit
2ca4770011
|
@ -188,6 +188,11 @@ struct RCTInstanceCallback : public InstanceCallback {
|
|||
return (JSGlobalContextRef)(_reactInstance ? _reactInstance->getJavaScriptContext() : nullptr);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<MessageQueueThread>)jsMessageThread
|
||||
{
|
||||
return _jsMessageThread;
|
||||
}
|
||||
|
||||
- (BOOL)isInspectable
|
||||
{
|
||||
return _reactInstance ? _reactInstance->isInspectable() : NO;
|
||||
|
|
|
@ -30,8 +30,6 @@ public:
|
|||
|
||||
virtual EventTarget createEventTarget(const InstanceHandle &instanceHandle) const = 0;
|
||||
|
||||
virtual void releaseEventTarget(const EventTarget &eventTarget) const = 0;
|
||||
|
||||
/*
|
||||
* Dispatches "raw" event using some event-delivery infrastructure.
|
||||
*/
|
||||
|
|
|
@ -17,9 +17,7 @@ EventEmitter::EventEmitter(const InstanceHandle &instanceHandle, const Tag &tag,
|
|||
tag_(tag),
|
||||
eventDispatcher_(eventDispatcher) {}
|
||||
|
||||
EventEmitter::~EventEmitter() {
|
||||
releaseEventTargetIfNeeded();
|
||||
}
|
||||
EventEmitter::~EventEmitter() {}
|
||||
|
||||
void EventEmitter::dispatchEvent(
|
||||
const std::string &type,
|
||||
|
@ -31,7 +29,7 @@ void EventEmitter::dispatchEvent(
|
|||
return;
|
||||
}
|
||||
|
||||
createEventTargetIfNeeded();
|
||||
EventTarget eventTarget = createEventTarget();
|
||||
|
||||
// Mixing `target` into `payload`.
|
||||
assert(payload.isObject());
|
||||
|
@ -39,31 +37,13 @@ void EventEmitter::dispatchEvent(
|
|||
extendedPayload.merge_patch(payload);
|
||||
|
||||
// TODO(T29610783): Reconsider using dynamic dispatch here.
|
||||
eventDispatcher->dispatchEvent(eventTarget_, type, extendedPayload, priority);
|
||||
eventDispatcher->dispatchEvent(eventTarget, type, extendedPayload, priority);
|
||||
}
|
||||
|
||||
void EventEmitter::createEventTargetIfNeeded() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (eventTarget_) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventTarget EventEmitter::createEventTarget() const {
|
||||
auto &&eventDispatcher = eventDispatcher_.lock();
|
||||
assert(eventDispatcher);
|
||||
eventTarget_ = eventDispatcher->createEventTarget(instanceHandle_);
|
||||
}
|
||||
|
||||
void EventEmitter::releaseEventTargetIfNeeded() const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (!eventTarget_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &&eventDispatcher = eventDispatcher_.lock();
|
||||
assert(eventDispatcher);
|
||||
eventDispatcher->releaseEventTarget(eventTarget_);
|
||||
return eventDispatcher->createEventTarget(instanceHandle_);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -48,14 +48,11 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
void createEventTargetIfNeeded() const;
|
||||
void releaseEventTargetIfNeeded() const;
|
||||
EventTarget createEventTarget() const;
|
||||
|
||||
InstanceHandle instanceHandle_;
|
||||
Tag tag_;
|
||||
std::weak_ptr<const EventDispatcher> eventDispatcher_;
|
||||
mutable EventTarget eventTarget_ {nullptr};
|
||||
mutable std::mutex mutex_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -98,10 +98,6 @@ void FabricUIManager::setDispatchEventFunction(std::function<DispatchEventFuncti
|
|||
dispatchEventFunction_ = dispatchEventFunction;
|
||||
}
|
||||
|
||||
void FabricUIManager::setReleaseEventTargetFunction(std::function<ReleaseEventTargetFunction> releaseEventTargetFunction) {
|
||||
releaseEventTargetFunction_ = releaseEventTargetFunction;
|
||||
}
|
||||
|
||||
void FabricUIManager::setReleaseEventHandlerFunction(std::function<ReleaseEventHandlerFunction> releaseEventHandlerFunction) {
|
||||
releaseEventHandlerFunction_ = releaseEventHandlerFunction;
|
||||
}
|
||||
|
@ -119,10 +115,6 @@ void FabricUIManager::dispatchEvent(const EventTarget &eventTarget, const std::s
|
|||
);
|
||||
}
|
||||
|
||||
void FabricUIManager::releaseEventTarget(const EventTarget &eventTarget) const {
|
||||
releaseEventTargetFunction_(eventTarget);
|
||||
}
|
||||
|
||||
SharedShadowNode FabricUIManager::createNode(int tag, std::string viewName, int rootTag, folly::dynamic props, InstanceHandle instanceHandle) {
|
||||
isLoggingEnabled && LOG(INFO) << "FabricUIManager::createNode(tag: " << tag << ", name: " << viewName << ", rootTag: " << rootTag << ", props: " << props << ")";
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace react {
|
|||
|
||||
using CreateEventTargetFunction = EventTarget (InstanceHandle instanceHandle);
|
||||
using DispatchEventFunction = void (EventHandler eventHandler, EventTarget eventTarget, std::string type, folly::dynamic payload);
|
||||
using ReleaseEventTargetFunction = void (EventTarget eventTarget);
|
||||
using ReleaseEventHandlerFunction = void (EventHandler eventHandler);
|
||||
|
||||
class FabricUIManager {
|
||||
|
@ -46,14 +45,12 @@ public:
|
|||
*/
|
||||
void setCreateEventTargetFunction(std::function<CreateEventTargetFunction> createEventTargetFunction);
|
||||
void setDispatchEventFunction(std::function<DispatchEventFunction> dispatchEventFunction);
|
||||
void setReleaseEventTargetFunction(std::function<ReleaseEventTargetFunction> releaseEventTargetFunction);
|
||||
void setReleaseEventHandlerFunction(std::function<ReleaseEventHandlerFunction> releaseEventHandlerFunction);
|
||||
|
||||
#pragma mark - Native-facing Interface
|
||||
|
||||
EventTarget createEventTarget(const InstanceHandle &instanceHandle) const;
|
||||
void dispatchEvent(const EventTarget &eventTarget, const std::string &type, const folly::dynamic &payload) const;
|
||||
void releaseEventTarget(const EventTarget &eventTarget) const;
|
||||
|
||||
#pragma mark - JavaScript/React-facing Interface
|
||||
|
||||
|
@ -75,7 +72,6 @@ private:
|
|||
EventHandler eventHandler_;
|
||||
std::function<CreateEventTargetFunction> createEventTargetFunction_;
|
||||
std::function<DispatchEventFunction> dispatchEventFunction_;
|
||||
std::function<ReleaseEventTargetFunction> releaseEventTargetFunction_;
|
||||
std::function<ReleaseEventHandlerFunction> releaseEventHandlerFunction_;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,16 +30,13 @@ EventTarget SchedulerEventDispatcher::createEventTarget(const InstanceHandle &in
|
|||
return uiManager_->createEventTarget(instanceHandle);
|
||||
}
|
||||
|
||||
void SchedulerEventDispatcher::releaseEventTarget(const EventTarget &eventTarget) const {
|
||||
uiManager_->releaseEventTarget(eventTarget);
|
||||
}
|
||||
|
||||
void SchedulerEventDispatcher::dispatchEvent(
|
||||
const EventTarget &eventTarget,
|
||||
const std::string &type,
|
||||
const folly::dynamic &payload,
|
||||
const EventPriority &priority
|
||||
) const {
|
||||
// TODO: Schedule the event based on priority.
|
||||
uiManager_->dispatchEvent(eventTarget, normalizeEventType(type), payload);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ public:
|
|||
|
||||
EventTarget createEventTarget(const InstanceHandle &instanceHandle) const override;
|
||||
|
||||
void releaseEventTarget(const EventTarget &eventTarget) const override;
|
||||
|
||||
void dispatchEvent(
|
||||
const EventTarget &eventTarget,
|
||||
const std::string &type,
|
||||
|
|
Loading…
Reference in New Issue