comparison OrthancStone/Sources/Scene2D/MacroSceneLayer.cpp @ 1802:757987cb5a68

recycling of layers in MacroSceneLayer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 May 2021 13:58:26 +0200
parents 013dec434a84
children 3889ae96d2e9
comparison
equal deleted inserted replaced
1801:64dad1d7aca4 1802:757987cb5a68
22 22
23 #include "MacroSceneLayer.h" 23 #include "MacroSceneLayer.h"
24 24
25 #include <OrthancException.h> 25 #include <OrthancException.h>
26 26
27 #include <cassert>
28
27 namespace OrthancStone 29 namespace OrthancStone
28 { 30 {
31 void MacroSceneLayer::CheckInvariant() const
32 {
33 #if !defined(NDEBUG)
34 // Only run the sanity check in debug mode
35 size_t countRecycled = 0;
36
37 for (size_t i = 0; i < layers_.size(); i++)
38 {
39 if (layers_[i] == NULL)
40 {
41 assert(recycledLayers_.find(i) != recycledLayers_.end());
42 countRecycled++;
43 }
44 else
45 {
46 assert(recycledLayers_.find(i) == recycledLayers_.end());
47 }
48 }
49
50 assert(countRecycled == recycledLayers_.size());
51 #endif
52 }
53
54
29 void MacroSceneLayer::Clear() 55 void MacroSceneLayer::Clear()
30 { 56 {
57 CheckInvariant();
58
31 for (size_t i = 0; i < layers_.size(); i++) 59 for (size_t i = 0; i < layers_.size(); i++)
32 { 60 {
33 if (layers_[i] != NULL) 61 if (layers_[i] != NULL)
34 { 62 {
35 delete layers_[i]; 63 delete layers_[i];
36 } 64 }
37 } 65 }
38 66
39 layers_.clear(); 67 layers_.clear();
68 recycledLayers_.clear();
69
40 BumpRevision(); 70 BumpRevision();
41 } 71 }
42 72
43 73
44 size_t MacroSceneLayer::AddLayer(ISceneLayer* layer) 74 size_t MacroSceneLayer::AddLayer(ISceneLayer* layer)
45 { 75 {
76 CheckInvariant();
77
46 if (layer == NULL) 78 if (layer == NULL)
47 { 79 {
48 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 80 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
49 } 81 }
50 else 82 else
51 { 83 {
52 // TODO - Use recycling list from DeleteLayer() 84 size_t index;
85
86 if (recycledLayers_.empty())
87 {
88 index = layers_.size();
89 layers_.push_back(layer);
90 }
91 else
92 {
93 index = *recycledLayers_.begin();
94 assert(layers_[index] == NULL);
95 layers_[index] = layer;
96 recycledLayers_.erase(index);
97 }
53 98
54 size_t index = layers_.size();
55 layers_.push_back(layer);
56 BumpRevision(); 99 BumpRevision();
57 return index; 100 return index;
58 } 101 }
59 } 102 }
60 103
61 104
62 void MacroSceneLayer::UpdateLayer(size_t index, 105 void MacroSceneLayer::UpdateLayer(size_t index,
63 ISceneLayer* layer) 106 ISceneLayer* layer)
64 { 107 {
108 CheckInvariant();
109
65 if (layer == NULL) 110 if (layer == NULL)
66 { 111 {
67 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); 112 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
68 } 113 }
69 else if (index >= layers_.size()) 114 else if (index >= layers_.size())
70 { 115 {
71 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 116 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
72 } 117 }
73 else 118 else
74 { 119 {
75 if (layers_[index] != NULL) 120 if (layers_[index] == NULL)
76 { 121 {
122 assert(recycledLayers_.find(index) != recycledLayers_.end());
123 recycledLayers_.erase(index);
124 }
125 else
126 {
127 assert(recycledLayers_.find(index) == recycledLayers_.end());
77 delete layers_[index]; 128 delete layers_[index];
78 } 129 }
79 130
80 layers_[index] = layer; 131 layers_[index] = layer;
81 BumpRevision(); 132 BumpRevision();
83 } 134 }
84 135
85 136
86 bool MacroSceneLayer::HasLayer(size_t index) const 137 bool MacroSceneLayer::HasLayer(size_t index) const
87 { 138 {
139 CheckInvariant();
140
88 if (index >= layers_.size()) 141 if (index >= layers_.size())
89 { 142 {
90 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 143 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
91 } 144 }
92 else 145 else
96 } 149 }
97 150
98 151
99 void MacroSceneLayer::DeleteLayer(size_t index) 152 void MacroSceneLayer::DeleteLayer(size_t index)
100 { 153 {
154 CheckInvariant();
155
101 if (index >= layers_.size()) 156 if (index >= layers_.size())
102 { 157 {
103 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 158 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
104 } 159 }
105 else if (layers_[index] == NULL) 160 else if (layers_[index] == NULL)
106 { 161 {
107 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem); 162 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem);
108 } 163 }
109 else 164 else
110 { 165 {
111 // TODO - Add to a recycling list
112
113 delete layers_[index]; 166 delete layers_[index];
114 layers_[index] = NULL; 167 layers_[index] = NULL;
168
169 assert(recycledLayers_.find(index) == recycledLayers_.end());
170 recycledLayers_.insert(index);
115 } 171 }
116 } 172 }
117 173
118 174
119 const ISceneLayer& MacroSceneLayer::GetLayer(size_t index) const 175 const ISceneLayer& MacroSceneLayer::GetLayer(size_t index) const
120 { 176 {
177 CheckInvariant();
178
121 if (index >= layers_.size()) 179 if (index >= layers_.size())
122 { 180 {
123 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 181 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
124 } 182 }
125 else if (layers_[index] == NULL) 183 else if (layers_[index] == NULL)
133 } 191 }
134 192
135 193
136 ISceneLayer* MacroSceneLayer::Clone() const 194 ISceneLayer* MacroSceneLayer::Clone() const
137 { 195 {
196 CheckInvariant();
197
138 std::unique_ptr<MacroSceneLayer> copy(new MacroSceneLayer); 198 std::unique_ptr<MacroSceneLayer> copy(new MacroSceneLayer);
139 199
140 for (size_t i = 0; i < layers_.size(); i++) 200 for (size_t i = 0; i < layers_.size(); i++)
141 { 201 {
142 if (layers_[i] == NULL) 202 if (layers_[i] == NULL)
147 { 207 {
148 copy->layers_.push_back(layers_[i]->Clone()); 208 copy->layers_.push_back(layers_[i]->Clone());
149 } 209 }
150 } 210 }
151 211
152 // TODO - Copy recycling list 212 copy->recycledLayers_ = recycledLayers_;
153 213
154 return copy.release(); 214 return copy.release();
155 } 215 }
156 216
157 217
158 void MacroSceneLayer::GetBoundingBox(Extent2D& target) const 218 void MacroSceneLayer::GetBoundingBox(Extent2D& target) const
159 { 219 {
220 CheckInvariant();
221
160 target.Clear(); 222 target.Clear();
161 223
162 for (size_t i = 0; i < layers_.size(); i++) 224 for (size_t i = 0; i < layers_.size(); i++)
163 { 225 {
164 if (layers_[i] != NULL) 226 if (layers_[i] != NULL)