GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/dgraph/factory.cpp Lines: 39 47 83.0 %
Date: 2023-03-15 12:04:10 Branches: 28 80 35.0 %

Line Branch Exec Source
1
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
2
// JRL, CNRS/AIST.
3
//
4
5
#include "dynamic-graph/factory.h"
6
7
#include <boost/foreach.hpp>
8
9
#include "dynamic-graph/debug.h"
10
11
using namespace std;
12
using namespace dynamicgraph;
13
14
namespace dynamicgraph {
15
54
FactoryStorage *FactoryStorage::getInstance() {
16
54
  if (instance_ == 0) {
17
11
    instance_ = new FactoryStorage;
18
  }
19
54
  return instance_;
20
}
21
22
1
void FactoryStorage::destroy() {
23
1
  delete instance_;
24
1
  instance_ = NULL;
25
1
}
26
27
11
FactoryStorage::FactoryStorage() : entityMap() {}
28
29
2
FactoryStorage::~FactoryStorage() {
30
1
  instance_ = 0;
31
  dgDEBUGINOUT(25);
32
1
}
33
34
16
void FactoryStorage::registerEntity(const std::string &entname,
35
                                    FactoryStorage::EntityConstructor_ptr ent) {
36
  dgDEBUGIN(25);
37
16
  if (existEntity(entname)) {
38
    DG_THROW ExceptionFactory(
39
        ExceptionFactory::OBJECT_CONFLICT,
40
        "Another entity class already defined with the same name. ",
41
        "(while adding entity class <%s> inside the factory).",
42

2
        entname.c_str());
43
    dgERRORF(
44
        "Another entity class already defined with the same name. "
45
        "(while adding entity class <%s> inside the factory).",
46
        entname.c_str());
47
  } else {
48
14
    if (!ent) {
49
      // FIXME: we should have a better error code for that.
50
      DG_THROW ExceptionFactory(ExceptionFactory::OBJECT_CONFLICT,
51
                                "Bad entity constructor.");
52
    }
53
54
    dgDEBUG(30) << "Register entity <" << entname << "> in the factory."
55
                << std::endl;
56
14
    entityMap[entname] = ent;
57
  }
58
  dgDEBUGOUT(25);
59
14
}
60
61
16
void FactoryStorage::deregisterEntity(const std::string &entname) {
62
  dgDEBUGIN(25);
63
16
  if (!existEntity(entname)) {
64
    DG_THROW ExceptionFactory(
65
        ExceptionFactory::OBJECT_CONFLICT, "Entity class not defined yet. ",
66

3
        "(while removing entity class <%s>).", entname.c_str());
67
    dgERRORF(ExceptionFactory::OBJECT_CONFLICT,
68
             "Entity class not defined yet. "
69
             "(while removing entity class <%s>).",
70
             entname.c_str());
71
  } else {
72
    dgDEBUG(30) << "Deregister entity <" << entname << "> from the factory."
73
                << std::endl;
74
13
    entityMap.erase(entname);
75
  }
76
  dgDEBUGOUT(25);
77
13
}
78
79
17
Entity *FactoryStorage::newEntity(const std::string &classname,
80
                                  const std::string &objname) const {
81
  dgDEBUG(15) << "New <" << classname << ">Entity <" << objname << ">"
82
              << std::endl;
83
84
17
  EntityMap::const_iterator entPtr = entityMap.find(classname);
85
17
  if (entPtr == entityMap.end()) {
86
    DG_THROW ExceptionFactory(
87
        ExceptionFactory::UNREFERED_OBJECT, "Unknown entity.",
88

1
        " (while calling new_entity <%s>)", classname.c_str());
89
  }
90
31
  return entPtr->second(objname);
91
}
92
93
// This checks efficiently if a key exists in an STL map using the
94
// approach suggested by Scott Meyer's Effective STL (item 24).
95
35
bool FactoryStorage::existEntity(const std::string &name) const {
96
35
  EntityMap::const_iterator lb = entityMap.lower_bound(name);
97

35
  return lb != entityMap.end() && !(entityMap.key_comp()(name, lb->first));
98
}
99
100
// FIXME: this should be removed at some point.
101
void FactoryStorage::listEntities(std::vector<std::string> &outList) const {
102
  typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
103
  BOOST_FOREACH (const iter_t &entity, entityMap)
104
    outList.push_back(entity.first);
105
}
106
107
12
EntityRegisterer::EntityRegisterer(const std::string &entityClassName,
108
12
                                   FactoryStorage::EntityConstructor_ptr maker)
109
12
    : entityName(entityClassName) {
110
  dgDEBUGIN(15);
111

12
  FactoryStorage::getInstance()->registerEntity(entityClassName, maker);
112
  dgDEBUGOUT(15);
113
12
}
114
115
12
EntityRegisterer::~EntityRegisterer() {
116
  dgDEBUGIN(15);
117
12
  FactoryStorage::getInstance()->deregisterEntity(entityName);
118
  dgDEBUGOUT(15);
119
12
}
120
121
// The global factory.
122
FactoryStorage *FactoryStorage::instance_ = NULL;
123
}  // end of namespace dynamicgraph.