Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
RenderObjectManager.cpp
1 #include <Engine/Rendering/RenderObjectManager.hpp>
2 
3 #include <Engine/RadiumEngine.hpp>
4 
5 #include <Engine/Scene/Component.hpp>
6 #include <Engine/Scene/Entity.hpp>
7 
8 #include <Engine/Data/Mesh.hpp>
9 #include <Engine/Rendering/RenderObject.hpp>
10 
11 #include <Engine/Scene/SignalManager.hpp>
12 
13 #include <numeric> // for reduce
14 
15 namespace Ra {
16 namespace Engine {
17 namespace Rendering {
18 
19 RenderObjectManager::RenderObjectManager() = default;
20 
21 RenderObjectManager::~RenderObjectManager() = default;
22 
23 bool RenderObjectManager::exists( const Core::Utils::Index& index ) const {
24  return ( index.isValid() && m_renderObjects.contains( index ) );
25 }
26 
27 Core::Utils::Index RenderObjectManager::addRenderObject( Rendering::RenderObject* renderObject ) {
28  // Avoid data race in the std::maps
29  std::lock_guard<std::mutex> lock( m_doubleBufferMutex );
30 
31  std::shared_ptr<Rendering::RenderObject> newRenderObject( renderObject );
32  Core::Utils::Index index = m_renderObjects.insert( newRenderObject );
33 
34  newRenderObject->setIndex( index );
35 
36  auto type = renderObject->getType();
37 
38  m_renderObjectByType[(int)type].insert( index );
39 
40  Engine::RadiumEngine::getInstance()->getSignalManager()->fireRenderObjectAdded(
41  Scene::ItemEntry(
42  renderObject->getComponent()->getEntity(), renderObject->getComponent(), index ) );
43  return index;
44 }
45 
46 void RenderObjectManager::removeRenderObject( const Core::Utils::Index& index ) {
47  CORE_ASSERT( exists( index ), "Trying to access a render object which doesn't exist" );
48 
49  // FIXME : Should we check if the render object is in the double buffer map ?
50  std::shared_ptr<Rendering::RenderObject> renderObject = m_renderObjects.at( index );
51 
52  Engine::RadiumEngine::getInstance()->getSignalManager()->fireRenderObjectRemoved(
53  Scene::ItemEntry(
54  renderObject->getComponent()->getEntity(), renderObject->getComponent(), index ) );
55 
56  // Lock after signal has been fired (as this signal can cause another RO to be deleted)
57  std::lock_guard<std::mutex> lock( m_doubleBufferMutex );
58  m_renderObjects.remove( index );
59 
60  auto type = renderObject->getType();
61  m_renderObjectByType[(int)type].erase( index );
62  renderObject.reset();
63 }
64 
65 size_t RenderObjectManager::getRenderObjectsCount() {
66  return m_renderObjects.size();
67 }
68 
69 std::shared_ptr<Rendering::RenderObject>
70 RenderObjectManager::getRenderObject( const Core::Utils::Index& index ) {
71  CORE_ASSERT( exists( index ), "Trying to access a render object which doesn't exist" );
72  return m_renderObjects.at( index );
73 }
74 
75 const Core::Utils::IndexMap<std::shared_ptr<Rendering::RenderObject>>&
76 RenderObjectManager::getRenderObjects() const {
77  return m_renderObjects;
78 }
79 
80 void RenderObjectManager::getRenderObjectsByType(
81  std::vector<std::shared_ptr<Rendering::RenderObject>>& objectsOut,
82  const Rendering::RenderObjectType& type ) const {
83  // Take the mutex
84  std::lock_guard<std::mutex> lock( m_doubleBufferMutex );
85 
87  std::transform(
88  m_renderObjectByType[(int)type].begin(),
89  m_renderObjectByType[(int)type].end(),
90  std::back_inserter( objectsOut ),
91  [this]( const Core::Utils::Index& i ) { return this->m_renderObjects.at( i ); } );
92 }
93 
94 void RenderObjectManager::renderObjectExpired( const Core::Utils::Index& idx ) {
95  std::lock_guard<std::mutex> lock( m_doubleBufferMutex );
96 
97  auto ro = m_renderObjects.at( idx );
98  m_renderObjects.remove( idx );
99 
100  auto type = ro->getType();
101 
102  m_renderObjectByType[size_t( type )].erase( idx );
103 
104  ro->hasExpired();
105 
106  ro.reset();
107 }
108 
109 size_t RenderObjectManager::getNumFaces() const {
110  // todo : use reduce instead of accumulate to improve performances (since C++17)
111  size_t result = std::accumulate(
112  m_renderObjects.begin(),
113  m_renderObjects.end(),
114  size_t( 0 ),
115  []( size_t a, const std::shared_ptr<Rendering::RenderObject>& ro ) -> size_t {
116  if ( ro->isVisible() && ro->getType() == Rendering::RenderObjectType::Geometry ) {
117  return a + ro->getMesh()->getNumFaces();
118  }
119  else { return a; }
120  } );
121  return result;
122 }
123 
124 size_t RenderObjectManager::getNumVertices() const {
125  // todo : use reduce instead of accumulate to improve performances (since C++17)
126  size_t result = std::accumulate(
127  m_renderObjects.begin(),
128  m_renderObjects.end(),
129  size_t( 0 ),
130  []( size_t a, const std::shared_ptr<Rendering::RenderObject>& ro ) -> size_t {
131  if ( ro->isVisible() && ro->getType() == Rendering::RenderObjectType::Geometry ) {
132  return a + ro->getMesh()->getNumVertices();
133  }
134  else { return a; }
135  } );
136  return result;
137 }
138 
139 } // namespace Rendering
140 } // namespace Engine
141 } // namespace Ra
Definition: Cage.cpp:3