mirror of
https://github.com/status-im/react-native.git
synced 2025-02-22 06:08:24 +00:00
Allow CxxModules to implement methods with two callbacks (#21586)
Summary: When writing a native module in C++ using CxxModule, its not currently possible to write async methods which take two callbacks, that shouldn't be projected to JS as a promise. I hit this when trying to implement the AppState module in c++. AppState has a single method on it, getCurrentAppState, which takes two callbacks (a success and a failure callback). This change adds a couple of new CxxModule::Method ctors, which allow devs to specify that they want two callbacks, but not a promise. This is done using an extra tag in the ctor, similar to how you specify that you want to make a synchronous method. I used the existing AsyncTag to indicate that the 2 callback version should be async, and not a promise. Pull Request resolved: https://github.com/facebook/react-native/pull/21586 Reviewed By: shergin Differential Revision: D10520204 Pulled By: fkgozali fbshipit-source-id: bcb2dbd91cba3c1db987dc18960247218fdbc032
This commit is contained in:
parent
11d4512abf
commit
8826d8b233
@ -67,13 +67,14 @@ public:
|
|||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
size_t callbacks;
|
size_t callbacks;
|
||||||
|
bool isPromise;
|
||||||
std::function<void(folly::dynamic, Callback, Callback)> func;
|
std::function<void(folly::dynamic, Callback, Callback)> func;
|
||||||
|
|
||||||
std::function<folly::dynamic(folly::dynamic)> syncFunc;
|
std::function<folly::dynamic(folly::dynamic)> syncFunc;
|
||||||
|
|
||||||
const char *getType() {
|
const char *getType() {
|
||||||
assert(func || syncFunc);
|
assert(func || syncFunc);
|
||||||
return func ? (callbacks == 2 ? "promise" : "async") : "sync";
|
return func ? (isPromise ? "promise" : "async") : "sync";
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::function/lambda ctors
|
// std::function/lambda ctors
|
||||||
@ -82,24 +83,36 @@ public:
|
|||||||
std::function<void()>&& afunc)
|
std::function<void()>&& afunc)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
|
, isPromise(false)
|
||||||
, func(std::bind(std::move(afunc))) {}
|
, func(std::bind(std::move(afunc))) {}
|
||||||
|
|
||||||
Method(std::string aname,
|
Method(std::string aname,
|
||||||
std::function<void(folly::dynamic)>&& afunc)
|
std::function<void(folly::dynamic)>&& afunc)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
, func(std::bind(std::move(afunc), _1)) {}
|
, isPromise(false)
|
||||||
|
, func(std::bind(std::move(afunc), std::placeholders::_1)) {}
|
||||||
|
|
||||||
Method(std::string aname,
|
Method(std::string aname,
|
||||||
std::function<void(folly::dynamic, Callback)>&& afunc)
|
std::function<void(folly::dynamic, Callback)>&& afunc)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(1)
|
, callbacks(1)
|
||||||
, func(std::bind(std::move(afunc), _1, _2)) {}
|
, isPromise(false)
|
||||||
|
, func(std::bind(std::move(afunc), std::placeholders::_1, std::placeholders::_2)) {}
|
||||||
|
|
||||||
Method(std::string aname,
|
Method(std::string aname,
|
||||||
std::function<void(folly::dynamic, Callback, Callback)>&& afunc)
|
std::function<void(folly::dynamic, Callback, Callback)>&& afunc)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(2)
|
, callbacks(2)
|
||||||
|
, isPromise(true)
|
||||||
|
, func(std::move(afunc)) {}
|
||||||
|
|
||||||
|
Method(std::string aname,
|
||||||
|
std::function<void(folly::dynamic, Callback, Callback)>&& afunc,
|
||||||
|
AsyncTagType)
|
||||||
|
: name(std::move(aname))
|
||||||
|
, callbacks(2)
|
||||||
|
, isPromise(false)
|
||||||
, func(std::move(afunc)) {}
|
, func(std::move(afunc)) {}
|
||||||
|
|
||||||
// method pointer ctors
|
// method pointer ctors
|
||||||
@ -108,25 +121,39 @@ public:
|
|||||||
Method(std::string aname, T* t, void (T::*method)())
|
Method(std::string aname, T* t, void (T::*method)())
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
|
, isPromise(false)
|
||||||
, func(std::bind(method, t)) {}
|
, func(std::bind(method, t)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Method(std::string aname, T* t, void (T::*method)(folly::dynamic))
|
Method(std::string aname, T* t, void (T::*method)(folly::dynamic))
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
, func(std::bind(method, t, _1)) {}
|
, isPromise(false)
|
||||||
|
, func(std::bind(method, t, std::placeholders::_1)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback))
|
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback))
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(1)
|
, callbacks(1)
|
||||||
, func(std::bind(method, t, _1, _2)) {}
|
, isPromise(false)
|
||||||
|
, func(std::bind(method, t, std::placeholders::_1, std::placeholders::_2)) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback, Callback))
|
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback, Callback))
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(2)
|
, callbacks(2)
|
||||||
, func(std::bind(method, t, _1, _2, _3)) {}
|
, 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)
|
||||||
|
: 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
|
// sync std::function/lambda ctors
|
||||||
|
|
||||||
@ -139,6 +166,7 @@ public:
|
|||||||
SyncTagType)
|
SyncTagType)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
|
, isPromise(false)
|
||||||
, syncFunc([afunc=std::move(afunc)] (const folly::dynamic&)
|
, syncFunc([afunc=std::move(afunc)] (const folly::dynamic&)
|
||||||
{ return afunc(); })
|
{ return afunc(); })
|
||||||
{}
|
{}
|
||||||
@ -148,6 +176,7 @@ public:
|
|||||||
SyncTagType)
|
SyncTagType)
|
||||||
: name(std::move(aname))
|
: name(std::move(aname))
|
||||||
, callbacks(0)
|
, callbacks(0)
|
||||||
|
, isPromise(false)
|
||||||
, syncFunc(std::move(afunc))
|
, syncFunc(std::move(afunc))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -114,6 +114,25 @@ auto SampleCxxModule::getMethods() -> std::vector<Method> {
|
|||||||
sample_->hello();
|
sample_->hello();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}, SyncTag),
|
}, SyncTag),
|
||||||
|
Method("addIfPositiveAsPromise", [](dynamic args, Callback cb, Callback cbError) {
|
||||||
|
auto a = jsArgAsDouble(args, 0);
|
||||||
|
auto b = jsArgAsDouble(args, 1);
|
||||||
|
if (a < 0 || b < 0) {
|
||||||
|
cbError({"Negative number!"});
|
||||||
|
} else {
|
||||||
|
cb({a + b});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Method("addIfPositiveAsAsync", [](dynamic args, Callback cb, Callback cbError) {
|
||||||
|
auto a = jsArgAsDouble(args, 0);
|
||||||
|
auto b = jsArgAsDouble(args, 1);
|
||||||
|
if (a < 0 || b < 0) {
|
||||||
|
cbError({"Negative number!"});
|
||||||
|
} else {
|
||||||
|
cb({a + b});
|
||||||
|
}
|
||||||
|
}, AsyncTag),
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user