Atlas 0.7.0
Networking protocol for the Worldforge system.
Factories.cpp
1/*
2 Copyright 2000-2001 Aloril.
3 Copyright 2001-2005 Alistair Riddoch.
4 Copyright (C) 2019 Erik Ogenvik
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "Factories.h"
22
23#include "Atlas/Objects/Anonymous.h"
24#include "Atlas/Objects/Generic.h"
25
26namespace Atlas {
27namespace Objects {
28
30using Atlas::Message::ListType;
31using Atlas::Message::MapType;
32
33SmartPtr<RootData> generic_factory(const std::string& name, int no) {
34 Operation::Generic obj;
35 obj->setType(name, no);
36 return obj;
37}
38
39SmartPtr<RootData> anonymous_factory(const std::string& name, int no) {
40 Entity::Anonymous obj;
41 obj->setType(name, no);
42 return obj;
43}
44
45Factories::Factories() {
46 installStandardTypes();
47}
48
49Factories::~Factories() = default;
50
51bool Factories::hasFactory(const std::string& name) const {
52 auto I = m_factories.find(name);
53 return I != m_factories.end();
54}
55
56Root Factories::createObject(const std::string& name) const {
57 auto I = m_factories.find(name);
58 if (I == m_factories.end()) {
59 return Root(nullptr);
60 } else {
61 return (*I).second.factory_method(name, (*I).second.classno);
62 }
63}
64
65Root Factories::createObject(const MapType& msg_map) const {
66 Root obj = instantiateObject(msg_map);
67
68 for (auto& entry : msg_map) {
69 obj->setAttr(entry.first, entry.second, this);
70 }
71 return obj;
72}
73
74Root Factories::createObject(Atlas::Message::MapType&& msg_map) const {
75 Root obj = instantiateObject(msg_map);
76
77 for (auto& entry : msg_map) {
78 obj->setAttr(entry.first, std::move(entry.second), this);
79 }
80 return obj;
81}
82
83
84Root Factories::instantiateObject(const Atlas::Message::MapType& msg_map) const {
85 // is this instance of entity or operation?
86 auto I = msg_map.find(Atlas::Objects::OBJTYPE_ATTR);
87 auto Iend = msg_map.end();
88 if (I != Iend && I->second.isString()) {
89 auto& objtype = I->second.String();
90 if (objtype == "op" || objtype == "obj" || objtype == "object") {
91 // get parent
92 I = msg_map.find(Atlas::Objects::PARENT_ATTR);
93 if (I != Iend && I->second.isString()) {
94 auto& parent = I->second.String();
95 // objtype and parent ok, try to create it:
96 auto J = m_factories.find(parent);
97 if (J != m_factories.end()) {
98 return J->second.factory_method(parent, J->second.classno);
99 } else {
100 if (objtype == "op") {
102 } else {
104 }
105 }
106 // FIXME We might want to do something different here.
107 } // has parent attr?
108 } // has known objtype
109 } // has objtype attr
110 // Should we really use factory? Why not just instantiate by hand?
112}
113
114
115Root Factories::getDefaultInstance(const std::string& name) const {
116 auto I = m_factories.find(name);
117 if (I == m_factories.end()) {
118 //perhaps throw something instead?
119 return Root(nullptr);
120 } else {
121 return (*I).second.default_instance_method(name, (*I).second.classno);
122 }
123}
124
125std::list<std::string> Factories::getKeys() const {
126 std::list<std::string> keys;
127 for (const auto& factory : m_factories) {
128 keys.push_back(factory.first);
129 }
130 return keys;
131}
132
133void Factories::addFactory(const std::string& name, FactoryMethod method, DefaultInstanceMethod defaultInstanceMethod, int classno) {
134 Factory factory{};
135 factory.classno = classno;
136 factory.default_instance_method = defaultInstanceMethod;
137 factory.factory_method = method;
138 m_factories[name] = factory;
139}
140
141int Factories::addFactory(const std::string& name, FactoryMethod method, DefaultInstanceMethod defaultInstanceMethod) {
142 int classno = ++enumMax;
143 Factory factory{};
144 factory.classno = classno;
145 factory.default_instance_method = defaultInstanceMethod;
146 factory.factory_method = method;
147 m_factories[name] = factory;
148 return classno;
149}
150
151std::vector<Root> Factories::parseListOfObjects(const Atlas::Message::ListType& val) const {
152 std::vector<Root> objects;
153 objects.reserve(val.size());
154 for (const auto& entry : val) {
155 if (entry.isMap()) {
156 objects.emplace_back(createObject(entry.Map()));
157 }
158 }
159 return objects;
160}
161
162std::vector<Root> Factories::parseListOfObjects(Atlas::Message::ListType&& val) const {
163 std::vector<Root> objects;
164 objects.reserve(val.size());
165 for (auto& entry : val) {
166 if (entry.isMap()) {
167 objects.emplace_back(createObject(entry.moveMap()));
168 }
169 }
170 return objects;
171}
172
173}
174} // namespace Atlas::Objects
std::vector< Root > parseListOfObjects(const Atlas::Message::ListType &val) const
Definition: Factories.cpp:151
Definition: Bridge.h:20