MyGUI 3.4.3
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"
13
14namespace MyGUI
15{
16
18 mParent(_parent),
19 mLayer(_layer)
20 {
21 }
22
24 {
25 for (auto& firstRenderItem : mFirstRenderItems)
26 delete firstRenderItem;
27 mFirstRenderItems.clear();
28
29 for (auto& secondRenderItem : mSecondRenderItems)
30 delete secondRenderItem;
31 mSecondRenderItems.clear();
32
33 for (auto& childItem : mChildItems)
34 delete childItem;
35 mChildItems.clear();
36 }
37
39 {
40 LayerNode* layer = new LayerNode(mLayer, this);
41 mChildItems.push_back(layer);
42
43 mOutOfDate = true;
44
45 return layer;
46 }
47
49 {
50 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
51 {
52 if ((*iter) == _node)
53 {
54 delete _node;
55 mChildItems.erase(iter);
56
57 mOutOfDate = true;
58
59 return;
60 }
61 }
62 MYGUI_EXCEPT("item node not found");
63 }
64
66 {
67 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
68 {
69 if ((*iter) == _item)
70 {
71 mChildItems.erase(iter);
72 mChildItems.push_back(_item);
73
74 mOutOfDate = true;
75
76 return;
77 }
78 }
79 MYGUI_EXCEPT("item node not found");
80 }
81
82 void LayerNode::renderToTarget(IRenderTarget* _target, bool _update)
83 {
84 mDepth = _target->getInfo().maximumDepth;
85
87 {
90 }
91
92 // сначала отрисовываем свое
93 for (auto& firstRenderItem : mFirstRenderItems)
94 firstRenderItem->renderToTarget(_target, _update);
95
96 for (auto& secondRenderItem : mSecondRenderItems)
97 secondRenderItem->renderToTarget(_target, _update);
98
99 // теперь отрисовываем дочерние узлы
100 for (auto& childItem : mChildItems)
101 childItem->renderToTarget(_target, _update);
102
103 mOutOfDate = false;
104 }
105
106 void LayerNode::resizeView(const IntSize& _viewSize)
107 {
108 IntSize oldSize = mLayer->getSize();
109
110 for (const auto& item : mLayerItems)
111 item->resizeLayerItemView(oldSize, _viewSize);
112 }
113
114 ILayerItem* LayerNode::getLayerItemByPoint(int _left, int _top) const
115 {
116 // сначала пикаем детей
117 for (const auto& childItem : mChildItems)
118 {
119 ILayerItem* item = childItem->getLayerItemByPoint(_left, _top);
120 if (nullptr != item)
121 return item;
122 }
123
124 for (const auto& layerItem : mLayerItems)
125 {
126 ILayerItem* item = layerItem->getLayerItemByPoint(_left, _top);
127 if (nullptr != item)
128 return item;
129 }
130
131 return nullptr;
132 }
133
134 RenderItem* LayerNode::addToRenderItem(ITexture* _texture, bool _firstQueue, bool _manualRender)
135 {
136 RenderItem* item = nullptr;
137 if (_firstQueue)
138 item = addToRenderItemFirstQueue(_texture, _manualRender);
139 else
140 item = addToRenderItemSecondQueue(_texture, _manualRender);
141
142 mOutOfDate = false;
143 return item;
144 }
145
147 {
148 if (mFirstRenderItems.empty() || _manualRender)
149 {
150 RenderItem* item = new RenderItem();
151 item->setTexture(_texture);
152 item->setManualRender(_manualRender);
154 mFirstRenderItems.push_back(item);
155
156 return item;
157 }
158
160 mOutOfDate = true;
161
162 // first queue keep order
163
164 // use either last non-empty buffer if it have same texture
165 // or empty buffer (if found in the end)
167 {
169 if (!item->getManualRender() && item->getTexture() == _texture)
170 {
171 return item;
172 }
173 }
174
175 if (mLastNotEmptyItem + 1 < mFirstRenderItems.size())
176 {
178 mFirstRenderItems[mLastNotEmptyItem]->setTexture(_texture);
180 }
181
182 // not found, create new
183 RenderItem* item = new RenderItem();
184 item->setTexture(_texture);
185 item->setManualRender(_manualRender);
187 mFirstRenderItems.push_back(item);
188
189 return item;
190 }
191
193 {
194 // order is not important in second queue
195 // use first buffer with same texture or empty buffer
196 for (auto& secondRenderItem : mSecondRenderItems)
197 {
198 if (secondRenderItem->getTexture() == _texture)
199 {
200 return secondRenderItem;
201 }
202 if (secondRenderItem->getNeedVertexCount() == 0)
203 {
204 secondRenderItem->setTexture(_texture);
205
206 return secondRenderItem;
207 }
208 }
209
210 // not found, create new
211 RenderItem* item = new RenderItem();
212 item->setTexture(_texture);
213 item->setManualRender(_manualRender);
214 mSecondRenderItems.push_back(item);
215
216 return item;
217 }
218
220 {
221 mLayerItems.push_back(_item);
222 _item->attachItemToNode(mLayer, this);
223
224 mOutOfDate = true;
225 }
226
228 {
229 for (VectorLayerItem::iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
230 {
231 if ((*iter) == _item)
232 {
233 mLayerItems.erase(iter);
234
235 mOutOfDate = true;
236
237 return;
238 }
239 }
240 MYGUI_EXCEPT("layer item not found");
241 }
242
244 {
245 mOutOfDate = true;
246 if (_item)
247 _item->outOfDate();
248 }
249
254
256 {
257 return mChildItems.size();
258 }
259
261 {
262 MYGUI_ASSERT_RANGE(_index, mChildItems.size(), "LayerNode::getLayerNodeAt");
263
264 return mChildItems[_index];
265 }
266
268 {
269 if (mFirstRenderItems.size() <= 1)
270 return;
271
272 bool need_compression = false;
273 for (const auto& firstRenderItem : mFirstRenderItems)
274 {
275 if (firstRenderItem->getNeedCompression())
276 {
277 firstRenderItem->setNeedCompression(false);
278 need_compression = true;
279 break;
280 }
281 }
282
283 if (!need_compression)
284 {
286 }
287 else
288 {
289 // pushing all empty buffers to the end of buffers list
290 VectorRenderItem nonEmptyItems;
291 nonEmptyItems.reserve(mFirstRenderItems.size());
292 VectorRenderItem emptyItems;
293
294 for (const auto& item : mFirstRenderItems)
295 {
296 if (item->getNeedVertexCount() == 0 && !item->getManualRender())
297 emptyItems.push_back(item);
298 else
299 nonEmptyItems.push_back(item);
300 }
301 mLastNotEmptyItem = nonEmptyItems.size() - 1;
302 nonEmptyItems.insert(nonEmptyItems.end(), emptyItems.begin(), emptyItems.end());
303 std::swap(mFirstRenderItems, nonEmptyItems);
304 }
305 }
306
308 {
309 return mLayer;
310 }
311
313 {
314 return mParent;
315 }
316
318 {
319 for (const auto& firstRenderItem : mFirstRenderItems)
320 {
321 if (firstRenderItem->isOutOfDate())
322 return true;
323 }
324
325 for (const auto& secondRenderItem : mSecondRenderItems)
326 {
327 if (secondRenderItem->isOutOfDate())
328 return true;
329 }
330
331 for (const auto& childItem : mChildItems)
332 {
333 if (static_cast<const LayerNode*>(childItem)->isOutOfDate())
334 return true;
335 }
336
337 return mOutOfDate;
338 }
339
341 {
342 return mDepth;
343 }
344
345} // namespace MyGUI
#define MYGUI_EXCEPT(dest)
#define MYGUI_ASSERT_RANGE(index, size, owner)
virtual void attachItemToNode(ILayer *_layer, ILayerNode *_node)=0
virtual ILayerItem * getLayerItemByPoint(int _left, int _top) const =0
virtual const RenderTargetInfo & getInfo() const =0
float getNodeDepth() const override
bool isOutOfDate() const
ILayerNode * getParent() const override
VectorRenderItem mSecondRenderItems
ILayerNode * createChildItemNode() override
VectorLayerItem mLayerItems
ILayer * getLayer() const override
size_t getLayerNodeCount() const override
void attachLayerItem(ILayerItem *_item) override
void detachLayerItem(ILayerItem *_item) override
void upChildItemNode(ILayerNode *_item) override
void destroyChildItemNode(ILayerNode *_node) override
VectorRenderItem mFirstRenderItems
ILayerNode * mParent
EnumeratorILayerNode getEnumerator() const override
void renderToTarget(IRenderTarget *_target, bool _update) override
void resizeView(const IntSize &_viewSize) override
RenderItem * addToRenderItem(ITexture *_texture, bool _firstQueue, bool _manualRender) override
VectorILayerNode mChildItems
ILayerItem * getLayerItemByPoint(int _left, int _top) const override
void outOfDate(RenderItem *_item) override
RenderItem * addToRenderItemFirstQueue(ITexture *_texture, bool _manualRender)
LayerNode(ILayer *_layer, ILayerNode *_parent=nullptr)
RenderItem * addToRenderItemSecondQueue(ITexture *_texture, bool _manualRender)
ILayerNode * getLayerNodeAt(size_t _index) const override
void setManualRender(bool _value)
void setTexture(ITexture *_value)
bool getManualRender() const
ITexture * getTexture() const
Enumerator< VectorILayerNode > EnumeratorILayerNode
std::vector< RenderItem * > VectorRenderItem
types::TSize< int > IntSize
Definition MyGUI_Types.h:30