From e51ca9571394b874f622f3a75332bf722952d681 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Wed, 1 May 2019 17:04:17 -0700 Subject: [PATCH] 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 --- yoga/events.cpp | 41 ++++++++++++++++++++++++++++++++++++ yoga/events.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 yoga/events.cpp create mode 100644 yoga/events.h diff --git a/yoga/events.cpp b/yoga/events.cpp new file mode 100644 index 00000000..19092fc5 --- /dev/null +++ b/yoga/events.cpp @@ -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 +#include + +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& globalEventSubscriber() { + static std::function subscriber = nullptr; + return subscriber; +} + +} // namespace + +void Event::subscribe(std::function&& 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 diff --git a/yoga/events.h b/yoga/events.h new file mode 100644 index 00000000..c48fab7b --- /dev/null +++ b/yoga/events.h @@ -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 + +struct YGConfig; +struct YGNode; + +namespace facebook { +namespace yoga { + +struct Event { + enum Type {}; + class Data; + using Subscriber = void(const YGNode&, Type, Data); + + template + struct TypedData {}; + + class Data { + const void* data_; + + public: + template + Data(const TypedData& data) : data_{&data} {} + + template + const TypedData& get() const { + return *static_cast*>(data_); + }; + }; + + static void subscribe(std::function&& subscriber); + + template + static void publish(const YGNode& node, const TypedData& eventData = {}) { + publish(node, E, Data{eventData}); + } + + template + static void publish(const YGNode* node, const TypedData& eventData = {}) { + publish(*node, eventData); + } + +private: + static void publish(const YGNode&, Type, const Data&); +}; + +} // namespace yoga +} // namespace facebook