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:
Valentin Shergin 2018-08-27 07:21:22 -07:00 committed by Facebook Github Bot
parent 5f8d5e0665
commit 0dae893eec
5 changed files with 77 additions and 117 deletions

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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