/
githubmr
/
facebook-react-native
Обзор
Документация
Войти
/
githubmr
/
facebook-react-native
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-native/ReactCommon/cxxreact/CxxModule.h
250 строк
7 KB
generatedunixname89002005287564
Fix CQS signal readability-named-parameter in xplat/js/react-native-github/packages [B] (#54028)
02 окт 2025, 22:55
02 окт 2025, 22:55
481df76
Код
Авторство
О чём код?
/* * Copyright (c) Meta Platforms, Inc. and 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> #include <map> #include <tuple> #include <vector> #include <folly/dynamic.h> namespace facebook::react { class Instance; } // namespace facebook::react namespace facebook::xplat::module { /** * Base class for Catalyst native modules whose implementations are * written in C++. Native methods are represented by instances of the * Method struct. Generally, a derived class will manage an instance * which represents the data for the module, and non-Catalyst-specific * methods can be wrapped in lambdas which convert between * folly::dynamic and native C++ objects. The Callback arguments will * pass through to js functions passed to the analogous javascript * methods. At most two callbacks will be converted. Results should * be passed to the first callback, and errors to the second callback. * Exceptions thrown by a method will be converted to platform * exceptions, and handled however they are handled on that platform. * (TODO mhorowitz #7128529: this exception behavior is not yet * implemented.) * * There are two sets of constructors here. The first set initializes * a Method using a name and anything convertible to a std::function. * This is most useful for registering a lambda as a RN method. There * are overloads to support functions which take no arguments, * arguments only, and zero, one, or two callbacks. * * The second set of methods is similar, but instead of taking a * function, takes the method name, an object, and a pointer to a * method on that object. */ class CxxModule { class AsyncTagType {}; class SyncTagType {}; public: using Provider = std::function<std::unique_ptr<CxxModule>()>; using Callback = std::function<void(std::vector<folly::dynamic>)>; constexpr static AsyncTagType AsyncTag = AsyncTagType(); constexpr static SyncTagType SyncTag = SyncTagType(); struct Method { std::string name; size_t callbacks; bool isPromise; std::function<void(folly::dynamic, Callback, Callback)> func; std::function<folly::dynamic(folly::dynamic)> syncFunc; const char* getType() { assert(func || syncFunc); return func ? (isPromise ? "promise" : "async") : "sync"; } // std::function/lambda ctors Method(std::string aname, std::function<void()>&& afunc) : name(std::move(aname)), callbacks(0), isPromise(false), func(std::bind(std::move(afunc))) {} Method(std::string aname, std::function<void(folly::dynamic)>&& afunc) : name(std::move(aname)), callbacks(0), isPromise(false), func(std::bind(std::move(afunc), std::placeholders::_1)) {} Method( std::string aname, std::function<void(folly::dynamic, Callback)>&& afunc) : name(std::move(aname)), callbacks(1), isPromise(false), func(std::bind( std::move(afunc), std::placeholders::_1, std::placeholders::_2)) {} Method( std::string aname, std::function<void(folly::dynamic, Callback, Callback)>&& afunc) : name(std::move(aname)), callbacks(2), isPromise(true), func(std::move(afunc)) {} Method( std::string aname, std::function<void(folly::dynamic, Callback, Callback)>&& afunc, AsyncTagType /*unused*/) : name(std::move(aname)), callbacks(2), isPromise(false), func(std::move(afunc)) {} // method pointer ctors template <typename T> Method(std::string aname, T* t, void (T::*method)()) : name(std::move(aname)), callbacks(0), isPromise(false), func(std::bind(method, t)) {} template <typename T> Method(std::string aname, T* t, void (T::*method)(folly::dynamic)) : name(std::move(aname)), callbacks(0), isPromise(false), func(std::bind(method, t, std::placeholders::_1)) {} template <typename T> Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback)) : name(std::move(aname)), callbacks(1), isPromise(false), func(std::bind( method, t, std::placeholders::_1, std::placeholders::_2)) {} template <typename T> Method( std::string aname, T* t, void (T::*method)(folly::dynamic, Callback, Callback)) : name(std::move(aname)), callbacks(2), isPromise(true), func(std::bind( method, t, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {} template <typename T> Method( std::string aname, T* t, void (T::*method)(folly::dynamic, Callback, Callback), AsyncTagType /*unused*/) : name(std::move(aname)), callbacks(2), isPromise(false), func(std::bind( method, t, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {} // sync std::function/lambda ctors // Overloads for functions returning void give ambiguity errors. // I am not sure if this is a runtime/compiler bug, or a // limitation I do not understand. Method( std::string aname, std::function<folly::dynamic()>&& afunc, SyncTagType /*unused*/) : name(std::move(aname)), callbacks(0), isPromise(false), syncFunc([afunc = std::move(afunc)](const folly::dynamic&) { return afunc(); }) {} Method( std::string aname, std::function<folly::dynamic(folly::dynamic)>&& afunc, SyncTagType /*unused*/) : name(std::move(aname)), callbacks(0), isPromise(false), syncFunc(std::move(afunc)) {} }; /** * This may block, if necessary to complete cleanup before the * object is destroyed. */ virtual ~CxxModule() = default; /** * @return the name of this module. This will be the name used to {@code * require()} this module from javascript. */ virtual std::string getName() = 0; /** * Each entry in the map will be exported as a property to JS. The * key is the property name, and the value can be anything. */ virtual auto getConstants() -> std::map<std::string, folly::dynamic> { return {}; }; /** * @return a list of methods this module exports to JS. */ virtual auto getMethods() -> std::vector<Method> = 0; /** * Called during the construction of CxxNativeModule. */ void setInstance(std::weak_ptr<react::Instance> instance) { instance_ = instance; } /** * @return a weak_ptr to the current instance of the bridge. * When used with CxxNativeModule, this gives Cxx modules access to functions * such as `callJSFunction`, allowing them to communicate back to JS outside * of the regular callbacks. */ std::weak_ptr<react::Instance> getInstance() { return instance_; } private: std::weak_ptr<react::Instance> instance_; }; } // namespace facebook::xplat::module