nx_metadata_sdk  1.0
Metadata SDK
interface.h
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2 
3 #pragma once
4 
5 #include <cstring>
6 
7 #include <nx/sdk/uuid.h>
8 
9 #include "i_ref_countable.h"
10 
11 namespace nx::sdk {
12 
47 template<class DerivedInterface, class BaseInterface = IRefCountable>
48 class Interface: public BaseInterface
49 {
50 public:
51  using IRefCountable::queryInterface; //< Needed to enable overloaded template versions.
52 
53 protected:
54  virtual IRefCountable* queryInterface(const IRefCountable::InterfaceId* id) override
55  {
56  return doQueryInterface(id);
57  }
58 
62  const Uuid& deprecatedInterfaceId)
63  {
64  static_assert(Uuid::size() == IRefCountable::InterfaceId::minSize(),
65  "Broken compatibility with old SDK");
66  if (memcmp(id, deprecatedInterfaceId.data(), Uuid::size()) == 0)
67  {
68  this->addRef();
69  // The cast is needed to shift the pointer in case of multiple inheritance.
70  return static_cast<DerivedInterface*>(this);
71  }
72  return doQueryInterface(id);
73  }
74 
75 private:
76  static_assert(std::is_base_of<IRefCountable, BaseInterface>::value,
77  "Template parameter BaseInterface should be derived from IRefCountable");
78 
83  Interface()
84  {
85  // Assure that DerivedInterface has interfaceId().
86  (void) &DerivedInterface::interfaceId;
87  }
88 
89  friend DerivedInterface;
90 
91  IRefCountable* doQueryInterface(const IRefCountable::InterfaceId* id)
92  {
93  const auto interfaceSupported =
94  [this]()
95  {
96  this->addRef();
97  // The cast is needed to shift the pointer in case of multiple inheritance.
98  return static_cast<DerivedInterface*>(this);
99  };
100 
101  if (*DerivedInterface::interfaceId() == *id)
102  return interfaceSupported();
103 
104  if constexpr (IRefCountable::hasAlternativeInterfaceId<DerivedInterface>)
105  {
106  if (*DerivedInterface::alternativeInterfaceId() == *id)
107  return interfaceSupported();
108  }
109 
110  return BaseInterface::queryInterface(id);
111  }
112 };
113 
114 } // namespace nx::sdk
IRefCountable * queryInterfaceSupportingDeprecatedId(const IRefCountable::InterfaceId *id, const Uuid &deprecatedInterfaceId)
Definition: interface.h:60
Definition: i_ref_countable.h:60
Definition: interface.h:48
Definition: uuid.h:22
Definition: device_agent.h:12
Definition: i_ref_countable.h:48