Marine systems simulation
ObjectFactoryStack.h
1#pragma once
2
3#include <atomic>
4#include <iostream>
5#include <list>
6#include <mutex>
7#include <thread>
8
9namespace CoRiBoDynamics
10{
11
22template <class _ObjectType_> class ObjectFactoryStack{
23public:
24 ObjectFactoryStack(){setBufferSize(1);}
25 explicit ObjectFactoryStack(unsigned int bufferSize){setBufferSize(bufferSize);}
26
27 void setBufferSize(unsigned int BufferSize){
28 destroyAllBuffers();
29 m_BufferSize = BufferSize;
30 m_sizeConvergenceCounter = BufferSize;
31 m_ObjectCounter = 0;
32 createNewBuffer();
33 }
34
35 unsigned int getObjectCounter(){
36 return m_ObjectCounter;
37 }
38
40 destroyAllBuffers();
41 }
42
43 void restart(){
44 m_sizeConvergenceCounter = m_ObjectCounter >= m_sizeConvergenceCounter ? m_ObjectCounter : (m_sizeConvergenceCounter+m_ObjectCounter)/2;
45 if(m_sizeConvergenceCounter < (m_buffers.size()-1)*m_BufferSize){
46 destroyBuffer();
47 }
48 m_currentBuffer = m_buffers.begin();
49 m_ObjectCounter = 0;
50 m_currentBufferIndex = 0;
51 }
52
53 _ObjectType_* getNewObject(){
54 m_ObjectCounter++;
55 if(m_currentBufferIndex >= m_BufferSize){ // if current buffer is full
56 m_currentBufferIndex = 0;
57 if(++m_currentBuffer == m_buffers.end()) // if current buffer is last
58 createNewBuffer();
59 }
60 return static_cast<_ObjectType_*>(*m_currentBuffer) + (m_currentBufferIndex++);
61 }
62
63 _ObjectType_* getNewObjectThreadSafe(){
64 std::scoped_lock lock(m_Lock);
65 return getNewObject();
66 }
67
68private:
70 ObjectFactoryStack& operator=( const ObjectFactoryStack& );
71
72 void createNewBuffer(){
73 m_currentBufferIndex = 0;
74 try
75 {
76 _ObjectType_* buffer = new _ObjectType_[m_BufferSize];
77 m_buffers.push_back(buffer);
78 m_currentBuffer = m_buffers.end();
79 --m_currentBuffer;
80 }
81 catch (const std::bad_alloc& error)
82 {
83 std::cerr << "ERROR: Bad memory allocation in ObjectFactoryStack<" << typeid(_ObjectType_).name() << ">" << std::endl;
84 std::cerr << error.what() << std::endl;
85 throw error;
86 }
87 }
88
89 void destroyBuffer(){
90 delete [] static_cast<_ObjectType_*>(m_buffers.back());
91 m_buffers.pop_back();
92 }
93
94 void destroyAllBuffers(){
95 for(std::list<void*>::iterator i = m_buffers.begin(); i != m_buffers.end(); ++i){
96 delete [] static_cast<_ObjectType_*>(*i);
97 }
98 m_buffers.clear();
99 m_ObjectCounter = 0;
100 }
101
102 unsigned int m_ObjectCounter;
103 unsigned int m_sizeConvergenceCounter;
104
105 unsigned int m_BufferSize;
106 std::list<void*>::iterator m_currentBuffer;
107 unsigned int m_currentBufferIndex;
108 std::list<void*> m_buffers;
109
110 std::mutex m_Lock;
111};
112}
Definition: ObjectFactoryStack.h:22
Definition: CollisionManager.h:6