MyGUI  3.2.1
MyGUI_LayerNode.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_LayerNode.h"
9 #include "MyGUI_ILayerItem.h"
10 #include "MyGUI_ITexture.h"
11 #include "MyGUI_ISubWidget.h"
12 #include "MyGUI_ISubWidgetText.h"
13 
14 namespace MyGUI
15 {
16 
17  LayerNode::LayerNode(ILayer* _layer, ILayerNode* _parent) :
18  mParent(_parent),
19  mLayer(_layer),
20  mOutOfDate(false),
21  mDepth(0.0f)
22  {
23  }
24 
26  {
27  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
28  delete (*iter);
29  mFirstRenderItems.clear();
30 
31  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
32  delete (*iter);
33  mSecondRenderItems.clear();
34 
35  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
36  delete (*iter);
37  mChildItems.clear();
38  }
39 
41  {
42  LayerNode* layer = new LayerNode(mLayer, this);
43  mChildItems.push_back(layer);
44 
45  mOutOfDate = true;
46 
47  return layer;
48  }
49 
51  {
52  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
53  {
54  if ((*iter) == _node)
55  {
56  delete _node;
57  mChildItems.erase(iter);
58 
59  mOutOfDate = true;
60 
61  return;
62  }
63  }
64  MYGUI_EXCEPT("item node not found");
65  }
66 
68  {
69  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
70  {
71  if ((*iter) == _item)
72  {
73  mChildItems.erase(iter);
74  mChildItems.push_back(_item);
75 
76  mOutOfDate = true;
77 
78  return;
79  }
80  }
81  MYGUI_EXCEPT("item node not found");
82  }
83 
84  void LayerNode::renderToTarget(IRenderTarget* _target, bool _update)
85  {
86  mDepth = _target->getInfo().maximumDepth;
87 
88  // проверяем на сжатие пустот
89  bool need_compression = false;
90  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
91  {
92  if ((*iter)->getCompression())
93  {
94  need_compression = true;
95  break;
96  }
97  }
98 
99  if (need_compression)
101 
102  // сначала отрисовываем свое
103  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
104  (*iter)->renderToTarget(_target, _update);
105 
106  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
107  (*iter)->renderToTarget(_target, _update);
108 
109  // теперь отрисовываем дочерние узлы
110  for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
111  (*iter)->renderToTarget(_target, _update);
112 
113  mOutOfDate = false;
114  }
115 
116  void LayerNode::resizeView(const IntSize& _viewSize)
117  {
118  IntSize oldSize = mLayer->getSize();
119 
120  for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
121  (*iter)->resizeLayerItemView(oldSize, _viewSize);
122  }
123 
124  ILayerItem* LayerNode::getLayerItemByPoint(int _left, int _top) const
125  {
126  // сначала пикаем детей
127  for (VectorILayerNode::const_iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
128  {
129  ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
130  if (nullptr != item)
131  return item;
132  }
133 
134  for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
135  {
136  ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
137  if (nullptr != item)
138  return item;
139  }
140 
141  return nullptr;
142  }
143 
144  RenderItem* LayerNode::addToRenderItem(ITexture* _texture, bool _firstQueue, bool _manualRender)
145  {
146  // для первичной очереди нужен порядок
147  if (_firstQueue)
148  {
149  if (mFirstRenderItems.empty() || _manualRender)
150  {
151  // создаем новый буфер
152  RenderItem* item = new RenderItem();
153  item->setTexture(_texture);
154  item->setManualRender(_manualRender);
155  mFirstRenderItems.push_back(item);
156 
157  mOutOfDate = false;
158 
159  return item;
160  }
161 
162  // если в конце пустой буфер, то нуна найти последний пустой с краю
163  // либо с нужной текстурой за пустым
164  VectorRenderItem::reverse_iterator iter = mFirstRenderItems.rbegin();
165  if ((*iter)->getNeedVertexCount() == 0)
166  {
167  while (true)
168  {
169  VectorRenderItem::reverse_iterator next = iter + 1;
170  if (next != mFirstRenderItems.rend())
171  {
172  if ((*next)->getNeedVertexCount() == 0)
173  {
174  iter = next;
175  continue;
176  }
177  else if (!(*next)->getManualRender() && (*next)->getTexture() == _texture)
178  {
179  iter = next;
180  }
181  }
182 
183  break;
184  }
185 
186  (*iter)->setTexture(_texture);
187 
188  mOutOfDate = false;
189 
190  return (*iter);
191  }
192  // последний буфер с нужной текстурой
193  else if (!(*iter)->getManualRender() && (*iter)->getTexture() == _texture)
194  {
195  mOutOfDate = false;
196 
197  return *iter;
198  }
199 
200  // создаем новый буфер
201  RenderItem* item = new RenderItem();
202  item->setTexture(_texture);
203  item->setManualRender(_manualRender);
204  mFirstRenderItems.push_back(item);
205 
206  mOutOfDate = false;
207 
208  return item;
209  }
210 
211  // для второй очереди порядок неважен
212  for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
213  {
214  // либо такая же текстура, либо пустой буфер
215  if ((*iter)->getTexture() == _texture)
216  {
217  mOutOfDate = false;
218 
219  return (*iter);
220  }
221  else if ((*iter)->getNeedVertexCount() == 0)
222  {
223  (*iter)->setTexture(_texture);
224 
225  mOutOfDate = false;
226 
227  return (*iter);
228  }
229  }
230  // не найденно создадим новый
231  RenderItem* item = new RenderItem();
232  item->setTexture(_texture);
233  item->setManualRender(_manualRender);
234 
235  mSecondRenderItems.push_back(item);
236 
237  mOutOfDate = false;
238 
239  return mSecondRenderItems.back();
240  }
241 
243  {
244  mLayerItems.push_back(_item);
245  _item->attachItemToNode(mLayer, this);
246 
247  mOutOfDate = true;
248  }
249 
251  {
252  for (VectorLayerItem::iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
253  {
254  if ((*iter) == _item)
255  {
256  mLayerItems.erase(iter);
257 
258  mOutOfDate = true;
259 
260  return;
261  }
262  }
263  MYGUI_EXCEPT("layer item not found");
264  }
265 
267  {
268  mOutOfDate = true;
269  if (_item)
270  _item->outOfDate();
271  }
272 
274  {
276  }
277 
279  {
280  return mChildItems.size();
281  }
282 
283  ILayerNode* LayerNode::getLayerNodeAt(size_t _index) const
284  {
285  MYGUI_ASSERT_RANGE(_index, mChildItems.size(), "LayerNode::getLayerNodeAt");
286 
287  return mChildItems[_index];
288  }
289 
291  {
292  // pushing all empty buffers to the end of buffers list
293  if (mFirstRenderItems.size() > 1)
294  {
295  VectorRenderItem nonEmptyItems;
296  VectorRenderItem emptyItems;
297 
298  for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
299  {
300  if ((*iter)->getNeedVertexCount() == 0 && !(*iter)->getManualRender())
301  emptyItems.push_back(*iter);
302  else
303  nonEmptyItems.push_back(*iter);
304  }
305  nonEmptyItems.insert(nonEmptyItems.end(), emptyItems.begin(), emptyItems.end());
306  std::swap(mFirstRenderItems, nonEmptyItems);
307  }
308 
309  mOutOfDate = true;
310  }
311 
313  {
314  return mLayer;
315  }
316 
318  {
319  return mParent;
320  }
321 
323  {
324  for (VectorRenderItem::const_iterator item = mFirstRenderItems.begin(); item != mFirstRenderItems.end(); ++item)
325  {
326  if ((*item)->isOutOfDate())
327  return true;
328  }
329 
330  for (VectorRenderItem::const_iterator item = mSecondRenderItems.begin(); item != mSecondRenderItems.end(); ++item)
331  {
332  if ((*item)->isOutOfDate())
333  return true;
334  }
335 
336  for (VectorILayerNode::const_iterator item = mChildItems.begin(); item != mChildItems.end(); ++item)
337  {
338  if (static_cast<const LayerNode*>(*item)->isOutOfDate())
339  return true;
340  }
341 
342  return mOutOfDate;
343  }
344 
346  {
347  return mDepth;
348  }
349 
350 } // namespace MyGUI