Choreonoid  1.8
PolymorphicFunctionSet.h
Go to the documentation of this file.
1 
5 #ifndef CNOID_UTIL_POLYMORPHIC_FUNCTION_SET_H
6 #define CNOID_UTIL_POLYMORPHIC_FUNCTION_SET_H
7 
8 #include <functional>
10 #include <vector>
11 
12 namespace cnoid {
13 
14 template<class ObjectBase>
16 {
17 public:
18  typedef std::function<void(ObjectBase* obj)> Function;
19 
20 private:
22  int validDispatchTableSize;
23  std::vector<Function> dispatchTable;
24  std::vector<bool> isFixed;
25 
26 public:
28  : registry(registry)
29  {
30  validDispatchTableSize = 0;
31  }
32 
33  bool empty() const {
34  return dispatchTable.empty();
35  }
36 
37  void setFunction(const std::type_info& type, Function func)
38  {
39  int id = registry.classId(type);
40  if(id >= 0){
41  if(validDispatchTableSize > id + 1){
42  validDispatchTableSize = id + 1;
43  }
44  if(id >= static_cast<int>(dispatchTable.size())){
45  dispatchTable.resize(id + 1);
46  isFixed.resize(id + 1, false);
47  }
48  dispatchTable[id] = func;
49  isFixed[id] = true;
50  }
51  }
52 
53  template <class Object>
54  void setFunction(Function func)
55  {
56  setFunction(typeid(Object), func);
57  }
58 
59  template <class Object>
60  void setFunction(std::function<void(Object* obj)> func)
61  {
62  setFunction<Object>([func](ObjectBase* obj){ func(static_cast<Object*>(obj)); });
63  }
64 
65  template <class Object>
66  void resetFunction(bool doUpdate = false)
67  {
68  int id = registry.template classId<Object>();
69  if(id >= 0 && id < dispatchTable.size()){
70  if(validDispatchTableSize > id){
71  validDispatchTableSize = id;
72  }
73  dispatchTable[id] = nullptr;
74  isFixed[id] = false;
75  if(doUpdate){
77  }
78  }
79  }
80 
81  bool updateDispatchTable(int idToCheck = 0)
82  {
83  const size_t numClasses = registry.numRegisteredClasses();
84  if(numClasses == validDispatchTableSize){
85  return idToCheck < numClasses;
86  }
87 
88  if(dispatchTable.size() != numClasses){
89  dispatchTable.resize(numClasses);
90  isFixed.resize(numClasses, false);
91  }
92 
93  const int n = dispatchTable.size();
94  for(int i = validDispatchTableSize; i < n; ++i){
95  if(!isFixed[i]){
96  dispatchTable[i] = nullptr;
97  }
98  }
99 
100  for(int i = validDispatchTableSize; i < n; ++i){
102  }
103  validDispatchTableSize = n;
104 
105  return idToCheck < validDispatchTableSize;
106  }
107 
109  {
110  if(dispatchTable[id]){
111  return id;
112  }
113  int superClassId = registry.superClassId(id);
114  if(superClassId < 0){
115  return -1;
116  }
117  int functionId = setSuperClassFunction(superClassId);
118  if(functionId >= 0){
119  dispatchTable[id] = dispatchTable[functionId];
120  }
121  return functionId;
122  }
123 
124  bool hasFunctionFor(ObjectBase* obj) const
125  {
126  auto id = obj->classId();
127  if(id >= validDispatchTableSize){
128  if(!const_cast<PolymorphicFunctionSet*>(this)->updateDispatchTable(id)){
129  return false;
130  }
131  }
132  return dispatchTable[id] != nullptr;
133  }
134 
135  inline void dispatch(ObjectBase* obj, const int id) const
136  {
137  if(id >= validDispatchTableSize){
138  if(!const_cast<PolymorphicFunctionSet*>(this)->updateDispatchTable(id)){
139  return;
140  }
141  }
142  auto& function = dispatchTable[id];
143  if(function){
144  function(obj);
145  }
146  }
147 
148  inline void dispatch(ObjectBase* obj) const
149  {
150  dispatch(obj, obj->classId());
151  }
152 
153  template <class Object>
154  inline void dispatchAs(Object* obj) const
155  {
156  dispatch(obj, registry.template classId<Object>(0));
157  }
158 
159  class Dispatcher {
160  public:
162  template<class Object> void dispatchAs(Object* obj) const {
163  pfs.dispatchAs<Object>(obj);
164  }
165  private:
167  };
168 
169  Dispatcher dispatcher() const {
170  return Dispatcher(*this);
171  }
172 };
173 
174 }
175 
176 #endif
cnoid::HierarchicalClassRegistry< ObjectBase >
cnoid::PolymorphicFunctionSet::empty
bool empty() const
Definition: PolymorphicFunctionSet.h:33
cnoid::PolymorphicFunctionSet::dispatcher
Dispatcher dispatcher() const
Definition: PolymorphicFunctionSet.h:169
cnoid::PolymorphicFunctionSet::setFunction
void setFunction(std::function< void(Object *obj)> func)
Definition: PolymorphicFunctionSet.h:60
cnoid::PolymorphicFunctionSet::Function
std::function< void(ObjectBase *obj)> Function
Definition: PolymorphicFunctionSet.h:18
cnoid::HierarchicalClassRegistryBase::superClassId
int superClassId(int classId) const
Definition: HierarchicalClassRegistry.cpp:88
cnoid::HierarchicalClassRegistry::classId
int classId(int unknownClassId=-1) const
Definition: HierarchicalClassRegistry.h:51
cnoid::PolymorphicFunctionSet::resetFunction
void resetFunction(bool doUpdate=false)
Definition: PolymorphicFunctionSet.h:66
cnoid::PolymorphicFunctionSet::Dispatcher::dispatchAs
void dispatchAs(Object *obj) const
Definition: PolymorphicFunctionSet.h:162
cnoid
Definition: AbstractSceneLoader.h:11
cnoid::PolymorphicFunctionSet::updateDispatchTable
bool updateDispatchTable(int idToCheck=0)
Definition: PolymorphicFunctionSet.h:81
cnoid::PolymorphicFunctionSet::setFunction
void setFunction(const std::type_info &type, Function func)
Definition: PolymorphicFunctionSet.h:37
cnoid::PolymorphicFunctionSet::setFunction
void setFunction(Function func)
Definition: PolymorphicFunctionSet.h:54
cnoid::HierarchicalClassRegistryBase::numRegisteredClasses
int numRegisteredClasses() const
Definition: HierarchicalClassRegistry.cpp:95
cnoid::PolymorphicFunctionSet::Dispatcher::Dispatcher
Dispatcher(const PolymorphicFunctionSet< ObjectBase > &pfs)
Definition: PolymorphicFunctionSet.h:161
HierarchicalClassRegistry.h
cnoid::PolymorphicFunctionSet::Dispatcher
Definition: PolymorphicFunctionSet.h:159
cnoid::PolymorphicFunctionSet::dispatch
void dispatch(ObjectBase *obj, const int id) const
Definition: PolymorphicFunctionSet.h:135
cnoid::PolymorphicFunctionSet::dispatch
void dispatch(ObjectBase *obj) const
Definition: PolymorphicFunctionSet.h:148
cnoid::PolymorphicFunctionSet::dispatchAs
void dispatchAs(Object *obj) const
Definition: PolymorphicFunctionSet.h:154
cnoid::PolymorphicFunctionSet
Definition: PolymorphicFunctionSet.h:15
cnoid::PolymorphicFunctionSet::PolymorphicFunctionSet
PolymorphicFunctionSet(HierarchicalClassRegistry< ObjectBase > &registry)
Definition: PolymorphicFunctionSet.h:27
cnoid::PolymorphicFunctionSet::hasFunctionFor
bool hasFunctionFor(ObjectBase *obj) const
Definition: PolymorphicFunctionSet.h:124
cnoid::PolymorphicFunctionSet::setSuperClassFunction
int setSuperClassFunction(int id)
Definition: PolymorphicFunctionSet.h:108