Atlas 0.7.0
Networking protocol for the Worldforge system.
BaseObject.h
1// This file may be redistributed and modified only under the terms of
2// the GNU Lesser General Public License (See COPYING for details).
3// Copyright (C) 2000-2004 Stefanus Du Toit, Aloril and Al Riddoch
4
5// $Id$
6
7#ifndef ATLAS_OBJECTS_BASEOBJECT_H
8#define ATLAS_OBJECTS_BASEOBJECT_H
9
10#include <Atlas/Message/MEncoder.h>
11#include <Atlas/Message/Element.h>
12#include <Atlas/Bridge.h>
13#include <Atlas/Exception.h>
14
15#include <map>
16#include <list>
17#include <string>
18
19#include <cassert>
20#include <mutex>
21
22namespace Atlas {
23
27namespace Objects {
28
29class Factories;
30
36{
38 std::string m_name;
39 public:
40 explicit NoSuchAttrException(const std::string& name) noexcept :
41 Atlas::Exception("No such attribute '" + name + "'."),
42 m_name(name) {}
43
46 m_name(rhs.m_name)
47 { }
48
49 NoSuchAttrException& operator=(NoSuchAttrException&& rhs) noexcept
50 {
51 m_name = std::move(rhs.m_name);
52 Atlas::Exception::operator=(rhs);
53 return *this;
54 }
55
56 ~NoSuchAttrException() noexcept override = default;
58 const std::string & getName() const {
59 return m_name;
60 }
61};
62
63class BaseObjectData;
64
77template <typename T>
78class Allocator {
79protected:
84
85
91
98
99public:
100
104 std::map<std::string, uint32_t> attr_flags_Data;
105
110
115
126
134 T *alloc();
135
143 void free(T *instance);
144
148 void release();
149
150};
151
152template <typename T>
153Allocator<T>::Allocator() : m_begin_Data(nullptr)
154{
155 T::fillDefaultObjectInstance(m_defaults_Data, attr_flags_Data);
156}
157
158template <typename T>
160 release();
161}
162
163template <typename T>
165{
166 return &m_defaults_Data;
167}
168
169template <typename T>
171{
172 {
173 std::unique_lock<std::mutex> lock(m_begin_Data_mutex);
174 if (m_begin_Data) {
175 auto res = m_begin_Data;
176 m_begin_Data = static_cast<T*>(m_begin_Data->m_next);
177 lock.unlock();
178 assert(res->m_refCount == 0);
179 res->m_attrFlags = 0;
180 res->m_attributes.clear();
181 return res;
182 }
183 }
184 return new T(&m_defaults_Data);
185}
186
187template <typename T>
188inline void Allocator<T>::free(T *instance)
189{
190 instance->reset();
191 {
192 std::lock_guard<std::mutex> lock(m_begin_Data_mutex);
193 instance->m_next = m_begin_Data;
194 m_begin_Data = instance;
195 }
196}
197
198template <typename T>
200{
201 //Delete all chained instances. This does not use the mutex as destruction can only happen in one thread,
202 // and trying to use the allocator while it's being destroyed is an illegal state.
203 T* next = m_begin_Data;
204 m_begin_Data = nullptr;
205 while (next) {
206 T* toDelete = next;
207 next = static_cast<T*>(next->m_next);
208 delete toDelete;
209 }
210}
211
212static const int BASE_OBJECT_NO = 0;
213
244{
245public:
246 template <typename>
247 friend class Allocator;
248 template <typename>
249 friend class SmartPtr;
250
255 explicit BaseObjectData(BaseObjectData *defaults);
256
257 virtual ~BaseObjectData();
258
260 int getClassNo() const
261 {
262 return m_class_no;
263 }
264
265 uint32_t getAttrFlags() const
266 {
267 return m_attrFlags;
268 }
269
270 virtual BaseObjectData * copy() const = 0;
271
273 virtual bool instanceOf(int classNo) const;
274
276 bool hasAttr(const std::string& name) const;
278 bool hasAttrFlag(uint32_t flag) const;
281 Atlas::Message::Element getAttr(const std::string& name) const;
284 virtual int copyAttr(const std::string& name,
285 Atlas::Message::Element & attr) const;
287 virtual void setAttr(std::string name,
288 Atlas::Message::Element attr, const Atlas::Objects::Factories* factories = nullptr);
290 virtual void removeAttr(const std::string& name);
292 virtual void removeAttrFlag(uint32_t flag);
293
296 Atlas::Message::MapType asMessage() const;
297
299 virtual void addToMessage(Atlas::Message::MapType &) const;
300
302 virtual void sendContents(Atlas::Bridge & b) const;
303
304protected:
305
310 virtual void free() = 0;
311 virtual void reset() = 0;
312 void incRef();
313 void decRef();
314
316 virtual int getAttrClass(const std::string& name) const;
317
319 virtual bool getAttrFlag(const std::string& name, uint32_t& flag) const;
320
321 template<typename T>
322 static T * copyInstance(const T& instance);
323
324 int m_class_no; //each class has different enum
325 int m_refCount; //how many instances
326
331
336 std::map<std::string, Atlas::Message::Element> m_attributes;
337 // is attribute in this object or in default object?
338 uint32_t m_attrFlags;
339};
340
341inline void BaseObjectData::incRef() {
342 m_refCount++;
343}
344
345inline void BaseObjectData::decRef() {
346 //why zero based refCount? avoids one m_refCount-- ;-)
347 assert( m_refCount >= 0 );
348 if(!m_refCount) {
349 free();
350 return;
351 }
352 m_refCount--;
353}
354
355template<typename T>
356T * BaseObjectData::copyInstance(const T& instance) {
357 T * copied = T::allocator.alloc();
358 *copied = instance;
359 copied->m_refCount = -1;
360 return copied;
361}
362
363} } // namespace Atlas::Objects
364
365#endif
std::mutex m_begin_Data_mutex
Definition: BaseObject.h:90
std::map< std::string, uint32_t > attr_flags_Data
Definition: BaseObject.h:104
void free(T *instance)
Definition: BaseObject.h:188
virtual void addToMessage(Atlas::Message::MapType &) const
Write this object to an existing Element.
Definition: BaseObject.cpp:99
virtual void removeAttr(const std::string &name)
Remove the attribute "name".
Definition: BaseObject.cpp:77
virtual int getAttrClass(const std::string &name) const
Find the class which contains the attribute "name".
Definition: BaseObject.cpp:114
Atlas::Message::MapType asMessage() const
Definition: BaseObject.cpp:92
virtual void free()=0
Free an instance of this class, returning it to the memory pool.
bool hasAttr(const std::string &name) const
Check whether the attribute "name" exists.
Definition: BaseObject.cpp:35
virtual void removeAttrFlag(uint32_t flag)
Remove the attribute "name".
Definition: BaseObject.cpp:87
BaseObjectData * m_defaults
Definition: BaseObject.h:330
virtual bool getAttrFlag(const std::string &name, uint32_t &flag) const
Find the flag for the attribute "name".
Definition: BaseObject.cpp:119
int getClassNo() const
Get class number:
Definition: BaseObject.h:260
Atlas::Message::Element getAttr(const std::string &name) const
Definition: BaseObject.cpp:52
virtual int copyAttr(const std::string &name, Atlas::Message::Element &attr) const
Definition: BaseObject.cpp:62
virtual void setAttr(std::string name, Atlas::Message::Element attr, const Atlas::Objects::Factories *factories=nullptr)
Set the attribute "name" to the value given by "attr".
Definition: BaseObject.cpp:72
virtual void sendContents(Atlas::Bridge &b) const
Send the contents of this object to a Bridge.
Definition: BaseObject.cpp:106
BaseObjectData(BaseObjectData *defaults)
Definition: BaseObject.cpp:14
bool hasAttrFlag(uint32_t flag) const
Check whether the attribute "name" exists.
Definition: BaseObject.cpp:47
virtual bool instanceOf(int classNo) const
Is this instance of some class?
Definition: BaseObject.cpp:30
const std::string & getName() const
Get the name of the attribute which does not exist.
Definition: BaseObject.h:58
Definition: Bridge.h:20