Add foundations for event system

Summary:
@public

We want to enable tooling, instrumentation, and statistics within Yoga without coupling these functionalities to our core code.

This commit introduces the foundations of a simple, global event system.
For the time being, we will only support a single subscriber. Should we require more than one, we can add support for it later.

Reviewed By: SidharthGuglani

Differential Revision: D15153678

fbshipit-source-id: 7d96f4c8def646a6a1b3908f946e7f81a6dba9c3
This commit is contained in:
David Aurelio 2019-05-01 17:04:17 -07:00 коммит произвёл Facebook Github Bot
Родитель ea8a57116f
Коммит 29d77ec251
2 изменённых файлов: 96 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,41 @@
/**
* 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.
*/
#include "events.h"
#include <memory>
#include <stdexcept>
namespace facebook {
namespace yoga {
namespace {
// For now, a single subscriber is enough.
// This can be changed as soon as the need for more than one subscriber arises.
std::function<Event::Subscriber>& globalEventSubscriber() {
static std::function<Event::Subscriber> subscriber = nullptr;
return subscriber;
}
} // namespace
void Event::subscribe(std::function<Subscriber>&& subscriber) {
if (globalEventSubscriber() != nullptr) {
throw std::logic_error(
"Yoga currently supports only one global event subscriber");
}
globalEventSubscriber() = std::move(subscriber);
}
void Event::publish(const YGNode& node, Type eventType, const Data& eventData) {
auto& subscriber = globalEventSubscriber();
if (subscriber) {
subscriber(node, eventType, eventData);
}
}
} // namespace yoga
} // namespace facebook

Просмотреть файл

@ -0,0 +1,55 @@
/**
* 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
#include <functional>
struct YGConfig;
struct YGNode;
namespace facebook {
namespace yoga {
struct Event {
enum Type {};
class Data;
using Subscriber = void(const YGNode&, Type, Data);
template <Type E>
struct TypedData {};
class Data {
const void* data_;
public:
template <Type E>
Data(const TypedData<E>& data) : data_{&data} {}
template <Type E>
const TypedData<E>& get() const {
return *static_cast<const TypedData<E>*>(data_);
};
};
static void subscribe(std::function<Subscriber>&& subscriber);
template <Type E>
static void publish(const YGNode& node, const TypedData<E>& eventData = {}) {
publish(node, E, Data{eventData});
}
template <Type E>
static void publish(const YGNode* node, const TypedData<E>& eventData = {}) {
publish<E>(*node, eventData);
}
private:
static void publish(const YGNode&, Type, const Data&);
};
} // namespace yoga
} // namespace facebook