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 api2 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Defining a member of this type causes P to be ODR-used, which forces its
|
MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(
|
||||||
// instantiation if it's a static member of a template.
|
NodeRegistrator, mediapipe::CalculatorBaseRegistry, T::kCalculatorName,
|
||||||
// Previously we depended on the pointer's value to determine whether the size
|
absl::make_unique<mediapipe::internal::CalculatorBaseFactoryFor<T>>)
|
||||||
// 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
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper template for forcing the definition of a static registration token.
|
MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE(SubgraphRegistrator,
|
||||||
template <typename T>
|
mediapipe::SubgraphRegistry,
|
||||||
struct NodeRegistrationStatic {
|
T::kCalculatorName, absl::make_unique<T>)
|
||||||
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());
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
|
@ -127,14 +83,7 @@ template <class Impl = void>
|
||||||
class RegisteredNode;
|
class RegisteredNode;
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
class RegisteredNode : public Node {
|
class RegisteredNode : public Node, private internal::NodeRegistrator<Impl> {};
|
||||||
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_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// No-op version for backwards compatibility.
|
// No-op version for backwards compatibility.
|
||||||
template <>
|
template <>
|
||||||
|
@ -216,10 +165,9 @@ class NodeImpl : public RegisteredNode<Impl>, public Intf {
|
||||||
// TODO: verify that the subgraph config fully implements the
|
// TODO: verify that the subgraph config fully implements the
|
||||||
// declared interface.
|
// declared interface.
|
||||||
template <class Intf, class Impl>
|
template <class Intf, class Impl>
|
||||||
class SubgraphImpl : public Subgraph, public Intf {
|
class SubgraphImpl : public Subgraph,
|
||||||
private:
|
public Intf,
|
||||||
typename internal::SubgraphRegistrationImpl<Impl>::RequireStatics register_;
|
private internal::SubgraphRegistrator<Impl> {};
|
||||||
};
|
|
||||||
|
|
||||||
// This macro is used to register a calculator that does not use automatic
|
// This macro is used to register a calculator that does not use automatic
|
||||||
// registration. Deprecated.
|
// registration. Deprecated.
|
||||||
|
|
|
@ -144,6 +144,23 @@ template <typename T>
|
||||||
struct WrapStatusOr<absl::StatusOr<T>> {
|
struct WrapStatusOr<absl::StatusOr<T>> {
|
||||||
using type = 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
|
} // namespace registration_internal
|
||||||
|
|
||||||
class NamespaceAllowlist {
|
class NamespaceAllowlist {
|
||||||
|
@ -408,6 +425,64 @@ class GlobalFactoryRegistry {
|
||||||
new mediapipe::RegistrationToken( \
|
new mediapipe::RegistrationToken( \
|
||||||
RegistryType::Register(#name, __VA_ARGS__))
|
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
|
} // namespace mediapipe
|
||||||
|
|
||||||
#endif // MEDIAPIPE_DEPS_REGISTRATION_H_
|
#endif // MEDIAPIPE_DEPS_REGISTRATION_H_
|
||||||
|
|
Loading…
Reference in New Issue
Block a user