chromium/third_party/mediapipe/src/mediapipe/framework/api2/node.h

#ifndef MEDIAPIPE_FRAMEWORK_API2_NODE_H_
#define MEDIAPIPE_FRAMEWORK_API2_NODE_H_

#include <memory>
#include <type_traits>

#include "absl/status/status.h"
#include "mediapipe/framework/api2/contract.h"
#include "mediapipe/framework/calculator_base.h"
#include "mediapipe/framework/calculator_context.h"
#include "mediapipe/framework/calculator_contract.h"
#include "mediapipe/framework/deps/registration.h"
#include "mediapipe/framework/subgraph.h"

namespace mediapipe {
namespace api2 {

class NodeIntf {};

class Node : public CalculatorBase {};

}  // namespace api2

namespace internal {

template <class T>
class CalculatorBaseFactoryFor<
    T,
    typename std::enable_if<std::is_base_of<mediapipe::api2::Node, T>{}>::type>
    : public CalculatorBaseFactory {
 public:
  absl::Status GetContract(CalculatorContract* cc) final {
    auto status = T::Contract::GetContract(cc);
    if (status.ok()) {
      status = UpdateContract<T>(cc);
    }
    return status;
  }

  std::unique_ptr<CalculatorBase> CreateCalculator(
      CalculatorContext* calculator_context) final {
    return absl::make_unique<T>();
  }

 private:
  template <typename U>
  auto UpdateContract(CalculatorContract* cc)
      -> decltype(U::UpdateContract(cc)) {
    return U::UpdateContract(cc);
  }
  template <typename U>
  absl::Status UpdateContract(...) {
    return {};
  }
};

}  // namespace internal

namespace api2 {
namespace internal {

MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE()

MEDIAPIPE_STATIC_REGISTRATOR_TEMPLATE()

}  // namespace internal

// By passing the Impl parameter, registration is done automatically. No need
// to use MEDIAPIPE_NODE_IMPLEMENTATION.
// For backward compatibility, Impl can be omitted; use
// MEDIAPIPE_NODE_IMPLEMENTATION with this.
// TODO: migrate and remove.
template <class Impl = void>
class RegisteredNode;

template <class Impl>
class RegisteredNode : public Node, private internal::NodeRegistrator<Impl> {};

// No-op version for backwards compatibility.
template <>
class RegisteredNode<void> : public Node {};

template <class Impl>
struct FunctionNode : public RegisteredNode<Impl> {};

template <class Intf, class Impl = void>
class NodeImpl : public RegisteredNode<Impl>, public Intf {};

// This macro is used to define the contract, without also giving the
// node a type name. It can be used directly in pure interfaces.
#define MEDIAPIPE_NODE_CONTRACT(...)

// This macro is used to define the contract and the type name of a node.
// This saves the name of the calculator, making it available to the
// implementation too, and to the registration macro for it. The reason is
// that the name must be available with the contract (so that it can be used
// to build a graph config, for instance); however, it is the implementation
// that needs to be registered.
// TODO: rename to MEDIAPIPE_NODE_DECLARATION?
// TODO: more detailed explanation.
#define MEDIAPIPE_NODE_INTERFACE(name, ...)

// TODO: verify that the subgraph config fully implements the
// declared interface.
template <class Intf, class Impl>
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.
#define MEDIAPIPE_NODE_IMPLEMENTATION(Impl)

// This macro is used to register a non-split-contract calculator. Deprecated.
#define MEDIAPIPE_REGISTER_NODE(name)

// This macro is used to define a subgraph that does not use automatic
// registration. Deprecated.
#define MEDIAPIPE_SUBGRAPH_IMPLEMENTATION(Impl)

}  // namespace api2
}  // namespace mediapipe

#endif  // MEDIAPIPE_FRAMEWORK_API2_NODE_H_