Caffa  1.1.0
C++ Application Framework for Embedded Systems with introspection
cafChildField.h
1 // ##################################################################################################
2 //
3 // Caffa
4 // Copyright (C) 2011-2013 Ceetron AS
5 // Copyright (C) 2013- Ceetron Solutions AS
6 // Copyright (C) 2022- Kontur AS
7 //
8 // GNU Lesser General Public License Usage
9 // This library is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Lesser General Public License as published by
11 // the Free Software Foundation; either version 2.1 of the License, or
12 // (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful, but WITHOUT ANY
15 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 // FITNESS FOR A PARTICULAR PURPOSE.
17 //
18 // See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
19 // for more details.
20 //
21 // ##################################################################################################
22 #pragma once
23 
24 #include "cafChildFieldAccessor.h"
25 #include "cafChildFieldHandle.h"
26 #include "cafFieldHandle.h"
27 #include "cafObjectHandle.h"
28 #include "cafObjectHandlePortableDataType.h"
29 
30 #include <concepts>
31 #include <memory>
32 #include <type_traits>
33 
34 namespace caffa
35 {
36 
42 template <typename DataTypePtr>
43  requires is_pointer<DataTypePtr>
45 {
46 public:
47  using DataType = typename std::remove_pointer<DataTypePtr>::type;
48  using Ptr = std::shared_ptr<DataType>;
49  using ConstPtr = std::shared_ptr<const DataType>;
50  using FieldDataType = DataTypePtr;
51 
52 public:
53  ChildField()
54  : m_fieldDataAccessor( std::make_unique<ChildFieldDirectStorageAccessor>( this ) )
55  {
56  static_assert( DerivesFromObjectHandle<DataType> &&
57  "Child fields can only contain ObjectHandle-derived objects" );
58  }
59 
60  virtual ~ChildField();
61 
62  bool empty() const override { return !object(); }
63 
64  // Assignment
65 
66  ChildField& operator=( Ptr object );
67  bool operator==( std::shared_ptr<const ObjectHandle> object ) const;
68  bool operator==( const ObjectHandle* object ) const;
69 
70  // Basic access
71 
72  std::shared_ptr<DataType> object()
73  {
74  if ( !m_fieldDataAccessor )
75  {
76  std::string errorMessage = "Failed to get object for '" + this->keyword() + "': Field is not accessible";
77  CAFFA_ERROR( errorMessage );
78  throw std::runtime_error( errorMessage );
79  }
80 
81  return std::dynamic_pointer_cast<DataType>( m_fieldDataAccessor->object() );
82  }
83  std::shared_ptr<const DataType> object() const
84  {
85  if ( !m_fieldDataAccessor )
86  {
87  std::string errorMessage = "Failed to get object for '" + this->keyword() + "': Field is not accessible";
88  CAFFA_ERROR( errorMessage );
89  throw std::runtime_error( errorMessage );
90  }
91 
92  return std::dynamic_pointer_cast<const DataType>( m_fieldDataAccessor->object() );
93  }
94  void setObject( Ptr object );
95 
96  // Access operators
97  operator std::shared_ptr<DataType>() { return this->object(); }
98  operator std::shared_ptr<const DataType>() const { return this->object(); }
99 
100  operator bool() const { return !!this->object(); }
101 
102  std::shared_ptr<DataType> operator->() { return this->object(); }
103  std::shared_ptr<const DataType> operator->() const { return this->object(); }
104 
105  std::shared_ptr<DataType> operator()() { return this->object(); }
106  std::shared_ptr<const DataType> operator()() const { return this->object(); }
107 
108  // Child objects
109  std::vector<std::shared_ptr<ObjectHandle>> childObjects() override;
110  std::vector<std::shared_ptr<const ObjectHandle>> childObjects() const override;
111  void clear() override;
112  void removeChildObject( std::shared_ptr<const ObjectHandle> object );
113  void setChildObject( std::shared_ptr<ObjectHandle> object ) override;
114 
115  std::string dataType() const override { return PortableDataType<DataType>::name(); }
116 
117  bool isReadable() const override { return m_fieldDataAccessor != nullptr && m_fieldDataAccessor->hasGetter(); }
118  bool isWritable() const override { return m_fieldDataAccessor != nullptr && m_fieldDataAccessor->hasSetter(); }
119 
120  void setAccessor( std::unique_ptr<ChildFieldAccessor> accessor ) override
121  {
122  m_fieldDataAccessor = std::move( accessor );
123  }
124 
125  std::string childClassKeyword() const override { return std::string( DataType::classKeywordStatic() ); }
126 
127 private:
128  ChildField( const ChildField& ) = delete;
129  ChildField& operator=( const ChildField& ) = delete;
130 
131  mutable std::unique_ptr<ChildFieldAccessor> m_fieldDataAccessor;
132 };
133 
134 } // End of namespace caffa
135 
136 #include "cafChildField.inl"
Field class to handle a pointer to a caffa Object.
Definition: cafChildField.h:44
Definition: cafChildFieldHandle.h:53
bool isWritable() const override
Definition: cafChildField.h:118
bool isReadable() const override
Definition: cafChildField.h:117
Definition: cafObjectHandle.h:47
Definition: cafPortableDataType.h:35
std::string childClassKeyword() const override
Get the class keyword of the contained child(ren)
Definition: cafChildField.h:125
Main Caffa namespace.
Definition: cafApplication.h:30