pw_rpc: Make Service independent of Method
Rather than depending on the concrete Method implementation, store a
BaseMethod* and the method implementation's size.
Change-Id: Ic52a9a7526f542ab872ed6a14be5c93e93dd95f1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/18240
Commit-Queue: Wyatt Hepler <hepler@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
diff --git a/pw_rpc/public/pw_rpc/service.h b/pw_rpc/public/pw_rpc/service.h
index 2076896..dd05c0c 100644
--- a/pw_rpc/public/pw_rpc/service.h
+++ b/pw_rpc/public/pw_rpc/service.h
@@ -14,37 +14,50 @@
#pragma once
#include <cstdint>
+#include <limits>
#include <span>
-#include <utility>
#include "pw_containers/intrusive_list.h"
+#include "pw_rpc/internal/base_method.h"
namespace pw::rpc {
-namespace internal {
-
-class Method;
-
-} // namespace internal
// Base class for all RPC services. This cannot be instantiated directly; use a
// generated subclass instead.
+//
+// Services store a span of concrete method classes. To support different Method
+// implementations, Service stores as base Method* and the size of the concrete
+// method object.
class Service : public IntrusiveList<Service>::Item {
public:
uint32_t id() const { return id_; }
protected:
+ template <typename T, size_t method_count>
+ constexpr Service(uint32_t id, const std::array<T, method_count>& methods)
+ : id_(id),
+ methods_(methods.data()),
+ method_size_(sizeof(T)),
+ method_count_(static_cast<uint16_t>(method_count)) {
+ static_assert(method_count <= std::numeric_limits<uint16_t>::max());
+ }
+
+ // For use by tests with only one method.
template <typename T>
- constexpr Service(uint32_t id, T&& methods)
- : id_(id), methods_(std::forward<T>(methods)) {}
+ constexpr Service(uint32_t id, const T& method)
+ : id_(id), methods_(&method), method_size_(sizeof(T)), method_count_(1) {}
private:
friend class Server;
+ friend class ServiceTestHelper;
// Finds the method with the provided method_id. Returns nullptr if no match.
- const internal::Method* FindMethod(uint32_t method_id) const;
+ const internal::BaseMethod* FindMethod(uint32_t method_id) const;
- uint32_t id_;
- std::span<const internal::Method> methods_;
+ const uint32_t id_;
+ const internal::BaseMethod* const methods_;
+ const uint16_t method_size_;
+ const uint16_t method_count_;
};
} // namespace pw::rpc