OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ClassServer.cc
Go to the documentation of this file.
1 /*
2  * opencog/atomspace/ClassServer.cc
3  *
4  * Copyright (C) 2002-2007 Novamente LLC
5  * Copyright (C) 2008 by OpenCog Foundation
6  * Copyright (C) 2009 Linas Vepstas <linasvepstas@gmail.com>
7  * All Rights Reserved
8  *
9  * Written by Thiago Maia <thiago@vettatech.com>
10  * Andre Senna <senna@vettalabs.com>
11  * Gustavo Gama <gama@vettalabs.com>
12  * Linas Vepstas <linasvepstas@gmail.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Affero General Public License v3 as
16  * published by the Free Software Foundation and including the exceptions
17  * at http://opencog.org/wiki/Licenses
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU Affero General Public License
25  * along with this program; if not, write to:
26  * Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28  */
29 
30 #include "ClassServer.h"
31 
32 #include <exception>
33 #include <boost/bind.hpp>
34 
35 #include <opencog/atomspace/atom_types.h>
36 #include "types.h"
37 #include <opencog/util/Logger.h>
38 
39 #include "opencog/atomspace/atom_types.definitions"
40 
41 //#define DPRINTF printf
42 #define DPRINTF(...)
43 
44 using namespace opencog;
45 
47 {
48  logger().info("Initializing ClassServer");
49  nTypes = 0;
50  // autogenerated code to initialize all atom types defined in
51  // atom_types.script file:
52  #include "opencog/atomspace/atom_types.inheritance"
53 }
54 
56 {
57  return new ClassServer();
58 }
59 
60 Type ClassServer::addType(const Type parent, const std::string& name)
61 {
62  // Check if a type with this name already exists. If it does, then
63  // the second and subsequent calls are to be interpreted as defining
64  // multiple inheritance for this type. A real-life example is the
65  // GroundedSchemeNode, which inherits from several types.
66  Type type = getType(name);
67  if (type != NOTYPE) {
68  std::lock_guard<std::mutex> l(type_mutex);
69  DPRINTF("Type \"%s\" has already been added (%d)\n", name.c_str(), type);
70  inheritanceMap[parent][type] = true;
71  setParentRecursively(parent, type);
72  return type;
73  }
74 
75  std::unique_lock<std::mutex> l(type_mutex);
76  // Assign type code and increment type counter.
77  type = nTypes++;
78 
79  // Resize inheritanceMap container.
80  inheritanceMap.resize(nTypes);
81  recursiveMap.resize(nTypes);
82 
83  std::for_each(inheritanceMap.begin(), inheritanceMap.end(),
84  boost::bind(&std::vector<bool>::resize, _1, nTypes, false));
85 
86  std::for_each(recursiveMap.begin(), recursiveMap.end(),
87  boost::bind(&std::vector<bool>::resize, _1, nTypes, false));
88 
89  inheritanceMap[type][type] = true;
90  inheritanceMap[parent][type] = true;
91  recursiveMap[type][type] = true;
92  setParentRecursively(parent, type);
93  name2CodeMap[name] = type;
94  code2NameMap[type] = &(name2CodeMap.find(name)->first);
95 
96  // unlock mutex before sending signal which could call
97  l.unlock();
98 
99  // Emit add type signal.
100  _addTypeSignal(type);
101 
102  return type;
103 }
104 
106 {
107  recursiveMap[parent][type] = true;
108  for (Type i = 0; i < nTypes; ++i) {
109  if ((recursiveMap[i][parent]) && (i != parent)) {
110  setParentRecursively(i, type);
111  }
112  }
113 }
114 
115 boost::signals2::signal<void (Type)>& ClassServer::addTypeSignal()
116 {
117  return _addTypeSignal;
118 }
119 
121 {
122  return nTypes;
123 }
124 
126 {
127  std::lock_guard<std::mutex> l(type_mutex);
128  if ((type >= nTypes) || (parent >= nTypes)) return false;
129  return inheritanceMap[parent][type];
130 }
131 
132 bool ClassServer::isDefined(const std::string& typeName)
133 {
134  std::lock_guard<std::mutex> l(type_mutex);
135  return name2CodeMap.find(typeName) != name2CodeMap.end();
136 }
137 
138 Type ClassServer::getType(const std::string& typeName)
139 {
140  std::lock_guard<std::mutex> l(type_mutex);
141  std::unordered_map<std::string, Type>::iterator it = name2CodeMap.find(typeName);
142  if (it == name2CodeMap.end()) {
143  return NOTYPE;
144  }
145  return it->second;
146 }
147 
148 const std::string& ClassServer::getTypeName(Type type)
149 {
150  static std::string nullString = "*** Unknown Type! ***";
151 
152  std::lock_guard<std::mutex> l(type_mutex);
153  std::unordered_map<Type, const std::string*>::iterator it;
154  if ((it = code2NameMap.find(type)) != code2NameMap.end())
155  return *(it->second);
156  return nullString;
157 }
158 
160 {
161  static std::unique_ptr<ClassServer> instance((*factory)());
162  return *instance;
163 }
164 
165 // This runs when the shared lib is loaded. We have to make
166 // sure that all of the core types are initialized before
167 // anything else happens, as otherwise weird symptoms manifest.
168 static __attribute__ ((constructor)) void init(void)
169 {
170  classserver();
171 }
std::unordered_map< std::string, Type > name2CodeMap
Definition: ClassServer.h:72
std::vector< std::vector< bool > > recursiveMap
Definition: ClassServer.h:71
std::mutex type_mutex
Definition: ClassServer.h:66
Type addType(const Type parent, const std::string &name)
Definition: ClassServer.cc:60
ClassServer & classserver(ClassServerFactory *=ClassServer::createInstance)
Definition: ClassServer.cc:159
static ClassServer * createInstance(void)
Definition: ClassServer.cc:55
bool isDefined(const std::string &typeName)
Definition: ClassServer.cc:132
ClassServer * ClassServerFactory(void)
Definition: ClassServer.h:43
TypeSignal & addTypeSignal()
Definition: ClassServer.cc:115
const std::string & getTypeName(Type type)
Definition: ClassServer.cc:148
#define DPRINTF(...)
Definition: ClassServer.cc:42
void setParentRecursively(Type parent, Type type)
Definition: ClassServer.cc:105
std::unordered_map< Type, const std::string * > code2NameMap
Definition: ClassServer.h:73
bool isA_non_recursive(Type sub, Type super)
Definition: ClassServer.cc:125
Type getType(const std::string &typeName)
Definition: ClassServer.cc:138
unsigned short Type
type of Atoms, represented as short integer (16 bits)
Definition: types.h:40
std::vector< std::vector< bool > > inheritanceMap
Definition: ClassServer.h:70
static __attribute__((constructor)) void init(void)
Definition: ClassServer.cc:168
TypeSignal _addTypeSignal
Definition: ClassServer.h:74