Caffa  1.1.0
C++ Application Framework for Embedded Systems with introspection
cafObjectHandle.h
1 // ##################################################################################################
2 //
3 // Custom Visualization Core library
4 // Copyright (C) 2011-2013 Ceetron AS
5 // Copyright (C) 2013- Ceetron Solutions AS
6 // Copyright (C) 2021-2022 3D-Radar AS
7 // Copyright (C) 2022- Kontur AS
8 //
9 // GNU Lesser General Public License Usage
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation; either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.
18 //
19 // See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
20 // for more details.
21 //
22 // ##################################################################################################
23 
24 #pragma once
25 
26 #include "cafAssert.h"
27 #include "cafFieldHandle.h"
28 #include "cafMethodHandle.h"
29 #include "cafStringTools.h"
30 
31 #include <algorithm>
32 #include <map>
33 #include <memory>
34 #include <string_view>
35 #include <type_traits>
36 #include <vector>
37 
38 namespace caffa
39 {
40 class FieldCapability;
41 class Inspector;
42 class Editor;
43 
48 {
49 public:
50  using InheritanceStackType = std::vector<std::string>;
51 
52  ObjectHandle( bool generateUuid = true );
53  virtual ~ObjectHandle() noexcept;
54 
55  // TODO: Once compilers support constexpr std::vector and std::string these can be made constexpr
56  static std::string classKeywordStatic() { return "ObjectHandle"; }
57  virtual std::string classKeyword() const { return classKeywordStatic(); }
58 
59  virtual InheritanceStackType classInheritanceStack() const { return { classKeywordStatic() }; }
65  std::string parentClassKeyword() const
66  {
67  // ObjectHandle is abstract and cannot be instantiated.
68  // Any child class will have a minimum of 2 items in stack.
69  auto stack = classInheritanceStack();
70  CAFFA_ASSERT( stack.size() >= 2 );
71  return stack[1];
72  }
73 
74  static bool matchesClassKeyword( const std::string& classKeyword, const InheritanceStackType& inheritanceStack )
75  {
76  return std::any_of( inheritanceStack.begin(),
77  inheritanceStack.end(),
78  [&classKeyword]( const std::string& testKeyword ) { return classKeyword == testKeyword; } );
79  }
80 
81  static constexpr bool isValidCharacter( char c )
82  {
83  return caffa::StringTools::isalpha( c ) || caffa::StringTools::isdigit( c ) || c == '_' || c == ':';
84  }
85 
90  static constexpr bool isValidKeyword( const std::string_view& type )
91  {
92  if ( type == "keyword" ) return false;
93 
94  if ( caffa::StringTools::isdigit( type[0] ) ) return false;
95 
96  auto end = std::find( type.begin(), type.end(), '\0' );
97 
98  auto validCount = std::count_if( type.cbegin(), end, ObjectHandle::isValidCharacter );
99  auto invalidCount =
100  std::count_if( type.cbegin(), end, []( auto c ) { return !ObjectHandle::isValidCharacter( c ); } );
101 
102  return validCount > 0u && invalidCount == 0u;
103  }
104 
105  virtual std::string classDocumentation() const { return ""; }
106 
111  std::vector<FieldHandle*> fields() const;
112 
117  std::vector<MethodHandle*> methods() const;
118 
124  FieldHandle* findField( const std::string& keyword ) const;
125 
131  MethodHandle* findMethod( const std::string& keyword ) const;
132 
133  const std::string& uuid() const;
134  void setUuid( const std::string& );
135 
138  virtual void initAfterRead() {};
139 
144  void accept( Inspector* visitor ) const;
145 
150  void accept( Editor* editor );
151 
152 protected:
156  void addField( FieldHandle* field, const std::string& keyword );
157 
161  void addMethod( MethodHandle* method, const std::string& keyword );
162 
163 private:
164  ObjectHandle( const ObjectHandle& ) = delete;
165  ObjectHandle& operator=( const ObjectHandle& ) = delete;
166 
167  std::string m_uuid;
168 
169  // Fields
170  std::map<std::string, FieldHandle*> m_fields;
171 
172  // Methods
173  std::map<std::string, MethodHandle*> m_methods;
174 };
175 
176 template <typename T>
177 concept DerivesFromObjectHandle = std::is_base_of<ObjectHandle, T>::value;
178 
179 template <typename T>
180 struct is_shared_ptr : std::false_type
181 {
182 };
183 template <typename T>
184 struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
185 {
186 };
187 
188 template <typename T>
189 concept IsSharedPtr = is_shared_ptr<T>::value;
190 
191 } // namespace caffa
Definition: cafObjectHandle.h:180
void accept(Inspector *visitor) const
Definition: cafObjectHandle.cpp:126
Definition: cafMethodHandle.h:52
virtual void initAfterRead()
Definition: cafObjectHandle.h:138
std::vector< MethodHandle * > methods() const
Definition: cafObjectHandle.cpp:67
void addField(FieldHandle *field, const std::string &keyword)
Definition: cafObjectHandle.cpp:80
std::vector< FieldHandle * > fields() const
Definition: cafObjectHandle.cpp:54
Definition: cafVisitor.h:49
Definition: cafObjectHandle.h:47
Base class for all fields, making it possible to handle them generically.
Definition: cafFieldHandle.h:19
void addMethod(MethodHandle *method, const std::string &keyword)
Definition: cafObjectHandle.cpp:95
FieldHandle * findField(const std::string &keyword) const
Definition: cafObjectHandle.cpp:108
static constexpr bool isValidKeyword(const std::string_view &type)
Definition: cafObjectHandle.h:90
std::string parentClassKeyword() const
Get the parent class keyword.
Definition: cafObjectHandle.h:65
Definition: cafVisitor.h:32
MethodHandle * findMethod(const std::string &keyword) const
Definition: cafObjectHandle.cpp:117
Main Caffa namespace.
Definition: cafApplication.h:30