Caffa  1.1.0
C++ Application Framework for Embedded Systems with introspection
cafFieldProxyAccessor.h
1 #pragma once
2 
3 #include "cafAssert.h"
4 #include "cafField.h"
5 
6 #include <functional>
7 #include <type_traits>
8 #include <vector>
9 
10 namespace caffa
11 {
12 template <typename DataType>
14 {
15 public:
16  virtual ~SetValueInterface() {}
17  virtual void setValue( const DataType& value ) = 0;
18  virtual std::unique_ptr<SetValueInterface<DataType>> clone() const = 0;
19 };
20 
21 template <typename DataType>
22 class SetterMethodCB : public SetValueInterface<DataType>
23 {
24 public:
25  using SetterMethodType = std::function<void( const DataType& )>;
26 
27  SetterMethodCB( SetterMethodType setterMethod ) { m_setterMethod = setterMethod; }
28 
29  void setValue( const DataType& value )
30  {
31  CAFFA_ASSERT( m_setterMethod );
32  m_setterMethod( value );
33  }
34 
35  virtual std::unique_ptr<SetValueInterface<DataType>> clone() const
36  {
37  return std::make_unique<SetterMethodCB<DataType>>( m_setterMethod );
38  }
39 
40 private:
41  SetterMethodType m_setterMethod;
42 };
43 
44 template <typename DataType>
46 {
47 public:
48  virtual ~GetValueInterface() {}
49  virtual DataType getValue() const = 0;
50  virtual std::unique_ptr<GetValueInterface<DataType>> clone() const = 0;
51 };
52 
53 template <typename DataType>
54 class GetterMethodCB : public GetValueInterface<DataType>
55 {
56 public:
57  using GetterMethodType = std::function<DataType()>;
58 
59  GetterMethodCB( GetterMethodType setterMethod ) { m_getterMethod = setterMethod; }
60 
61  DataType getValue() const { return m_getterMethod(); }
62 
63  virtual std::unique_ptr<GetValueInterface<DataType>> clone() const
64  {
65  return std::make_unique<GetterMethodCB<DataType>>( m_getterMethod );
66  }
67 
68 private:
69  GetterMethodType m_getterMethod;
70 };
71 
72 template <typename DataType>
73 class FieldProxyAccessor : public DataFieldAccessor<DataType>
74 {
75 public:
76  std::unique_ptr<DataFieldAccessor<DataType>> clone() const override
77  {
78  auto copy = std::make_unique<FieldProxyAccessor>();
79  copy->m_valueSetter = std::move( m_valueSetter->clone() );
80  copy->m_valueGetter = std::move( m_valueGetter->clone() );
81  return copy;
82  }
83 
84  DataType value() override
85  {
86  if ( !m_valueGetter ) throw std::runtime_error( "No getter for field" );
87  return m_valueGetter->getValue();
88  }
89 
90  void setValue( const DataType& value ) override
91  {
92  if ( !m_valueSetter ) throw std::runtime_error( "No setter for field" );
93  m_valueSetter->setValue( value );
94  }
95 
96  // Proxy Field stuff to handle the method pointers
97  // The public registering methods must be written below the private classes
98  // For some reason. Forward declaration did some weirdness.
99 private:
100 public:
101  void registerSetMethod( typename SetterMethodCB<DataType>::SetterMethodType setterMethod )
102  {
103  m_valueSetter = std::make_unique<SetterMethodCB<DataType>>( setterMethod );
104  }
105 
106  void registerGetMethod( typename GetterMethodCB<DataType>::GetterMethodType getterMethod )
107  {
108  m_valueGetter = std::make_unique<GetterMethodCB<DataType>>( getterMethod );
109  }
110 
111  bool hasSetter() const { return m_valueSetter != nullptr; }
112  bool hasGetter() const { return m_valueGetter != nullptr; }
113 
114 private:
115  std::unique_ptr<SetValueInterface<DataType>> m_valueSetter;
116  std::unique_ptr<GetValueInterface<DataType>> m_valueGetter;
117 };
118 
119 } // End of namespace caffa
Abstract but typed data field accessor. Inherit to create different storage mechanisms.
Definition: cafDataFieldAccessor.h:43
Definition: cafFieldProxyAccessor.h:74
DataType value() override
Get the field value.
Definition: cafFieldProxyAccessor.h:84
void setValue(const DataType &value) override
Set the value with the accessor. Will throw a std::runtime_exception if the accessor has limits and t...
Definition: cafFieldProxyAccessor.h:90
std::unique_ptr< DataFieldAccessor< DataType > > clone() const override
Clone the accessor using polymorphism.
Definition: cafFieldProxyAccessor.h:76
Definition: cafFieldProxyAccessor.h:46
Definition: cafFieldProxyAccessor.h:55
Definition: cafFieldProxyAccessor.h:14
Definition: cafFieldProxyAccessor.h:23
Main Caffa namespace.
Definition: __init__.py:1