Fabric: Rethinking of `EventDispatcher`
Summary: @public Now, it's not just an abstract class, it's a regular class which unifies event delivery priorities using specific event beats and event pipe. Reviewed By: mdvacca Differential Revision: D8886232 fbshipit-source-id: c4360511e5fd477ca7407fc3ebbd99ca578e79cc
This commit is contained in:
parent
5f8d5e0665
commit
0dae893eec
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright (c) 2015-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 "EventDispatcher.h"
|
||||
|
||||
#include "UnbatchedEventQueue.h"
|
||||
#include "BatchedEventQueue.h"
|
||||
|
||||
#define REACT_FABRIC_SYNC_EVENT_DISPATCHING_DISABLED
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
EventDispatcher::EventDispatcher(
|
||||
const EventPipe &eventPipe,
|
||||
const EventBeatFactory &synchonousEventBeatFactory,
|
||||
const EventBeatFactory &asynchonousEventBeatFactory
|
||||
) {
|
||||
// Synchronous/Unbatched
|
||||
eventQueues_[(int)EventPriority::SynchronousUnbatched] =
|
||||
std::make_unique<UnbatchedEventQueue>(eventPipe, synchonousEventBeatFactory());
|
||||
|
||||
// Synchronous/Batched
|
||||
eventQueues_[(int)EventPriority::SynchronousBatched] =
|
||||
std::make_unique<BatchedEventQueue>(eventPipe, synchonousEventBeatFactory());
|
||||
|
||||
// Asynchronous/Unbatched
|
||||
eventQueues_[(int)EventPriority::AsynchronousUnbatched] =
|
||||
std::make_unique<UnbatchedEventQueue>(eventPipe, asynchonousEventBeatFactory());
|
||||
|
||||
// Asynchronous/Batched
|
||||
eventQueues_[(int)EventPriority::AsynchronousBatched] =
|
||||
std::make_unique<BatchedEventQueue>(eventPipe, asynchonousEventBeatFactory());
|
||||
}
|
||||
|
||||
void EventDispatcher::dispatchEvent(
|
||||
const RawEvent &rawEvent,
|
||||
EventPriority priority
|
||||
) const {
|
||||
#ifdef REACT_FABRIC_SYNC_EVENT_DISPATCHING_DISABLED
|
||||
// Synchronous dispatch works, but JavaScript interop layer does not have
|
||||
// proper synchonization yet and it crashes.
|
||||
if (priority == EventPriority::SynchronousUnbatched) {
|
||||
priority = EventPriority::AsynchronousUnbatched;
|
||||
}
|
||||
|
||||
if (priority == EventPriority::SynchronousBatched) {
|
||||
priority = EventPriority::AsynchronousBatched;
|
||||
}
|
||||
#endif
|
||||
|
||||
eventQueues_[(int)priority]->enqueueEvent(rawEvent);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -8,37 +8,40 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <fabric/events/EventBeat.h>
|
||||
#include <fabric/events/EventQueue.h>
|
||||
#include <fabric/events/primitives.h>
|
||||
#include <folly/dynamic.h>
|
||||
#include <fabric/events/RawEvent.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class EventDispatcher;
|
||||
|
||||
using SharedEventDispatcher = std::shared_ptr<const EventDispatcher>;
|
||||
|
||||
/*
|
||||
* Abstract class that represent event-delivery infrastructure.
|
||||
* Particular `EventEmitter` clases use an object of this class to invoke
|
||||
* events.
|
||||
* Represents event-delivery infrastructure.
|
||||
* Particular `EventEmitter` clases use this for sending events.
|
||||
*/
|
||||
class EventDispatcher {
|
||||
|
||||
public:
|
||||
EventDispatcher(
|
||||
const EventPipe &eventPipe,
|
||||
const EventBeatFactory &synchonousEventBeatFactory,
|
||||
const EventBeatFactory &asynchonousEventBeatFactory
|
||||
);
|
||||
|
||||
/*
|
||||
* Dispatches "raw" event using some event-delivery infrastructure.
|
||||
* Dispatches a raw event with given priority using event-delivery pipe.
|
||||
*/
|
||||
virtual void dispatchEvent(
|
||||
const EventTarget &eventTarget,
|
||||
const std::string &type,
|
||||
const folly::dynamic &payload,
|
||||
const EventPriority &priority
|
||||
) const = 0;
|
||||
|
||||
virtual void releaseEventTarget(const EventTarget &eventTarget) const = 0;
|
||||
void dispatchEvent(
|
||||
const RawEvent &rawEvent,
|
||||
EventPriority priority
|
||||
) const;
|
||||
|
||||
private:
|
||||
std::array<std::unique_ptr<EventQueue>, 4> eventQueues_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <fabric/core/LayoutConstraints.h>
|
||||
#include <fabric/uimanager/ContextContainer.h>
|
||||
#include <fabric/uimanager/SchedulerDelegate.h>
|
||||
#include <fabric/uimanager/SchedulerEventDispatcher.h>
|
||||
#include <fabric/uimanager/UIManagerDelegate.h>
|
||||
#include <fabric/uimanager/ShadowTree.h>
|
||||
#include <fabric/uimanager/ShadowTreeDelegate.h>
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-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 "SchedulerEventDispatcher.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
// TODO(T29874519): Get rid of "top" prefix once and for all.
|
||||
/*
|
||||
* Capitalizes the first letter of the event type and adds "top" prefix
|
||||
* (e.g. "layout" becames "topLayout").
|
||||
*/
|
||||
static std::string normalizeEventType(const std::string &type) {
|
||||
std::string prefixedType = type;
|
||||
prefixedType[0] = toupper(prefixedType[0]);
|
||||
prefixedType.insert(0, "top");
|
||||
return prefixedType;
|
||||
}
|
||||
|
||||
void SchedulerEventDispatcher::setUIManager(std::shared_ptr<const FabricUIManager> uiManager) const {
|
||||
uiManager_ = uiManager;
|
||||
}
|
||||
|
||||
void SchedulerEventDispatcher::dispatchEvent(
|
||||
const EventTarget &eventTarget,
|
||||
const std::string &type,
|
||||
const folly::dynamic &payload,
|
||||
const EventPriority &priority
|
||||
) const {
|
||||
if (!uiManager_) {
|
||||
return;
|
||||
}
|
||||
// TODO: Schedule the event based on priority.
|
||||
uiManager_->dispatchEventToTarget(eventTarget, normalizeEventType(type), payload);
|
||||
}
|
||||
|
||||
void SchedulerEventDispatcher::releaseEventTarget(const EventTarget &eventTarget) const {
|
||||
if (!uiManager_) {
|
||||
return;
|
||||
}
|
||||
// TODO(shergin): This needs to move to the destructor of EventEmitter. For now we'll leak.
|
||||
// uiManager_->releaseEventTarget(eventTarget);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-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 <fabric/events/EventDispatcher.h>
|
||||
#include <fabric/events/primitives.h>
|
||||
#include <fabric/uimanager/FabricUIManager.h>
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class SchedulerEventDispatcher;
|
||||
|
||||
using SharedSchedulerEventDispatcher = std::shared_ptr<const SchedulerEventDispatcher>;
|
||||
|
||||
/*
|
||||
* Concrete EventDispatcher.
|
||||
*/
|
||||
class SchedulerEventDispatcher final:
|
||||
public EventDispatcher {
|
||||
|
||||
public:
|
||||
|
||||
void setUIManager(std::shared_ptr<const FabricUIManager> uiManager) const;
|
||||
|
||||
#pragma mark - EventDispatcher
|
||||
|
||||
void dispatchEvent(
|
||||
const EventTarget &eventTarget,
|
||||
const std::string &type,
|
||||
const folly::dynamic &payload,
|
||||
const EventPriority &priority
|
||||
) const override;
|
||||
|
||||
|
||||
void releaseEventTarget(const EventTarget &eventTarget) const override;
|
||||
|
||||
private:
|
||||
|
||||
// TODO: consider using std::weak_ptr<> instead for better memory management.
|
||||
mutable std::shared_ptr<const FabricUIManager> uiManager_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Loading…
Reference in New Issue