Generalize non-define registration with MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE
PiperOrigin-RevId: 547929982
This commit is contained in:
parent
c2c67c20fa
commit
723e91cec1
|
@ -64,57 +64,13 @@ class CalculatorBaseFactoryFor<
|
|||
namespace api2 {
|
||||
namespace internal {
|
||||
|
||||
// Defining a member of this type causes P to be ODR-used, which forces its
|
||||
// instantiation if it's a static member of a template.
|
||||
// Previously we depended on the pointer's value to determine whether the size
|
||||
// of a character array is 0 or 1, forcing it to be instantiated so the
|
||||
// compiler can determine the object's layout. But using it as a template
|
||||
// argument is more compact.
|
||||
template <auto* P>
|
||||
struct ForceStaticInstantiation {
|
||||
#ifdef _MSC_VER
|
||||
// Just having it as the template argument does not count as a use for
|
||||
// MSVC.
|
||||
static constexpr bool Use() { return P != nullptr; }
|
||||
char force_static[Use()];
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(
|
||||
NodeRegistrator, mediapipe::CalculatorBaseRegistry, T::kCalculatorName,
|
||||
absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<T>>)
|
||||
|
||||
// Helper template for forcing the definition of a static registration token.
|
||||
template <typename T>
|
||||
struct NodeRegistrationStatic {
|
||||
static NoDestructor<mediapipe::RegistrationToken> registration;
|
||||
|
||||
static mediapipe::RegistrationToken Make() {
|
||||
return mediapipe::CalculatorBaseRegistry::Register(
|
||||
T::kCalculatorName,
|
||||
absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<T>>);
|
||||
}
|
||||
|
||||
using RequireStatics = ForceStaticInstantiation<®istration>;
|
||||
};
|
||||
|
||||
// Static members of template classes can be defined in the header.
|
||||
template <typename T>
|
||||
NoDestructor<mediapipe::RegistrationToken>
|
||||
NodeRegistrationStatic<T>::registration(NodeRegistrationStatic<T>::Make());
|
||||
|
||||
template <typename T>
|
||||
struct SubgraphRegistrationImpl {
|
||||
static NoDestructor<mediapipe::RegistrationToken> registration;
|
||||
|
||||
static mediapipe::RegistrationToken Make() {
|
||||
return mediapipe::SubgraphRegistry::Register(T::kCalculatorName,
|
||||
absl::make_unique<T>);
|
||||
}
|
||||
|
||||
using RequireStatics = ForceStaticInstantiation<®istration>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
NoDestructor<mediapipe::RegistrationToken>
|
||||
SubgraphRegistrationImpl<T>::registration(
|
||||
SubgraphRegistrationImpl<T>::Make());
|
||||
MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(SubgraphRegistrator,
|
||||
mediapipe::SubgraphRegistry,
|
||||
T::kCalculatorName, absl::make_unique<T>)
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
@ -127,14 +83,7 @@ template <class Impl = void>
|
|||
class RegisteredNode;
|
||||
|
||||
template <class Impl>
|
||||
class RegisteredNode : public Node {
|
||||
private:
|
||||
// The member below triggers instantiation of the registration static.
|
||||
// Note that the constructor of calculator subclasses is only invoked through
|
||||
// the registration token, and so we cannot simply use the static in the
|
||||
// constructor.
|
||||
typename internal::NodeRegistrationStatic<Impl>::RequireStatics register_;
|
||||
};
|
||||
class RegisteredNode : public Node, private internal::NodeRegistrator<Impl> {};
|
||||
|
||||
// No-op version for backwards compatibility.
|
||||
template <>
|
||||
|
@ -216,10 +165,9 @@ class NodeImpl : public RegisteredNode<Impl>, public Intf {
|
|||
// TODO: verify that the subgraph config fully implements the
|
||||
// declared interface.
|
||||
template <class Intf, class Impl>
|
||||
class SubgraphImpl : public Subgraph, public Intf {
|
||||
private:
|
||||
typename internal::SubgraphRegistrationImpl<Impl>::RequireStatics register_;
|
||||
};
|
||||
class SubgraphImpl : public Subgraph,
|
||||
public Intf,
|
||||
private internal::SubgraphRegistrator<Impl> {};
|
||||
|
||||
// This macro is used to register a calculator that does not use automatic
|
||||
// registration. Deprecated.
|
||||
|
|
|
@ -144,6 +144,23 @@ template <typename T>
|
|||
struct WrapStatusOr<absl::StatusOr<T>> {
|
||||
using type = absl::StatusOr<T>;
|
||||
};
|
||||
|
||||
// Defining a member of this type causes P to be ODR-used, which forces its
|
||||
// instantiation if it's a static member of a template.
|
||||
// Previously we depended on the pointer's value to determine whether the size
|
||||
// of a character array is 0 or 1, forcing it to be instantiated so the
|
||||
// compiler can determine the object's layout. But using it as a template
|
||||
// argument is more compact.
|
||||
template <auto* P>
|
||||
struct ForceStaticInstantiation {
|
||||
#ifdef _MSC_VER
|
||||
// Just having it as the template argument does not count as a use for
|
||||
// MSVC.
|
||||
static constexpr bool Use() { return P != nullptr; }
|
||||
char force_static[Use()];
|
||||
#endif // _MSC_VER
|
||||
};
|
||||
|
||||
} // namespace registration_internal
|
||||
|
||||
class NamespaceAllowlist {
|
||||
|
@ -408,6 +425,64 @@ class GlobalFactoryRegistry {
|
|||
new mediapipe::RegistrationToken( \
|
||||
RegistryType::Register(#name, __VA_ARGS__))
|
||||
|
||||
// Defines a utility registrator class which can be used to automatically
|
||||
// register factory functions.
|
||||
//
|
||||
// Example:
|
||||
// === Defining a registry ================================================
|
||||
//
|
||||
// class Component {};
|
||||
//
|
||||
// using ComponentRegistry = GlobalFactoryRegistry<std::unique_ptr<Component>>;
|
||||
//
|
||||
// === Defining a registrator =============================================
|
||||
//
|
||||
// MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(ComponentRegistrator,
|
||||
// ComponentRegistry, T::kName,
|
||||
// absl::make_unique<T>);
|
||||
//
|
||||
// === Defining and registering a new component. ==========================
|
||||
//
|
||||
// class MyComponent : public Component,
|
||||
// private ComponentRegistrator<MyComponent> {
|
||||
// public:
|
||||
// static constexpr char kName[] = "MyComponent";
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// NOTE:
|
||||
// - MyComponent is automatically registered in ComponentRegistry by
|
||||
// "MyComponent" name.
|
||||
// - Every component is require to provide its name (T::kName here.)
|
||||
#define MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(RegistratorName, RegistryType, \
|
||||
name, ...) \
|
||||
template <typename T> \
|
||||
struct Internal##RegistratorName { \
|
||||
static NoDestructor<mediapipe::RegistrationToken> registration; \
|
||||
\
|
||||
static mediapipe::RegistrationToken Make() { \
|
||||
return RegistryType::Register(name, __VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
using RequireStatics = \
|
||||
registration_internal::ForceStaticInstantiation<®istration>; \
|
||||
}; \
|
||||
/* Static members of template classes can be defined in the header. */ \
|
||||
template <typename T> \
|
||||
NoDestructor<mediapipe::RegistrationToken> \
|
||||
Internal##RegistratorName<T>::registration( \
|
||||
Internal##RegistratorName<T>::Make()); \
|
||||
\
|
||||
template <typename T> \
|
||||
class RegistratorName { \
|
||||
private: \
|
||||
/* The member below triggers instantiation of the registration static. */ \
|
||||
/* Note that the constructor of calculator subclasses is only invoked */ \
|
||||
/* through the registration token, and so we cannot simply use the */ \
|
||||
/* static in theconstructor. */ \
|
||||
typename Internal##RegistratorName<T>::RequireStatics register_; \
|
||||
};
|
||||
|
||||
} // namespace mediapipe
|
||||
|
||||
#endif // MEDIAPIPE_DEPS_REGISTRATION_H_
|
||||
|
|
Loading…
Reference in New Issue
Block a user