MyGUI  3.2.1
MyGUI_LayerNode.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_LayerNode.h"
00009 #include "MyGUI_ILayerItem.h"
00010 #include "MyGUI_ITexture.h"
00011 #include "MyGUI_ISubWidget.h"
00012 #include "MyGUI_ISubWidgetText.h"
00013 
00014 namespace MyGUI
00015 {
00016 
00017     LayerNode::LayerNode(ILayer* _layer, ILayerNode* _parent) :
00018         mParent(_parent),
00019         mLayer(_layer),
00020         mOutOfDate(false),
00021         mDepth(0.0f)
00022     {
00023     }
00024 
00025     LayerNode::~LayerNode()
00026     {
00027         for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
00028             delete (*iter);
00029         mFirstRenderItems.clear();
00030 
00031         for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
00032             delete (*iter);
00033         mSecondRenderItems.clear();
00034 
00035         for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
00036             delete (*iter);
00037         mChildItems.clear();
00038     }
00039 
00040     ILayerNode* LayerNode::createChildItemNode()
00041     {
00042         LayerNode* layer = new LayerNode(mLayer, this);
00043         mChildItems.push_back(layer);
00044 
00045         mOutOfDate = true;
00046 
00047         return layer;
00048     }
00049 
00050     void LayerNode::destroyChildItemNode(ILayerNode* _node)
00051     {
00052         for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
00053         {
00054             if ((*iter) == _node)
00055             {
00056                 delete _node;
00057                 mChildItems.erase(iter);
00058 
00059                 mOutOfDate = true;
00060 
00061                 return;
00062             }
00063         }
00064         MYGUI_EXCEPT("item node not found");
00065     }
00066 
00067     void LayerNode::upChildItemNode(ILayerNode* _item)
00068     {
00069         for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
00070         {
00071             if ((*iter) == _item)
00072             {
00073                 mChildItems.erase(iter);
00074                 mChildItems.push_back(_item);
00075 
00076                 mOutOfDate = true;
00077 
00078                 return;
00079             }
00080         }
00081         MYGUI_EXCEPT("item node not found");
00082     }
00083 
00084     void LayerNode::renderToTarget(IRenderTarget* _target, bool _update)
00085     {
00086         mDepth = _target->getInfo().maximumDepth;
00087 
00088         // сначала отрисовываем свое
00089         for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
00090             (*iter)->renderToTarget(_target, _update);
00091 
00092         for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
00093             (*iter)->renderToTarget(_target, _update);
00094 
00095         // теперь отрисовываем дочерние узлы
00096         for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
00097             (*iter)->renderToTarget(_target, _update);
00098 
00099         mOutOfDate = false;
00100     }
00101 
00102     void LayerNode::resizeView(const IntSize& _viewSize)
00103     {
00104         IntSize oldSize = mLayer->getSize();
00105 
00106         for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
00107             (*iter)->resizeLayerItemView(oldSize, _viewSize);
00108     }
00109 
00110     ILayerItem* LayerNode::getLayerItemByPoint(int _left, int _top) const
00111     {
00112         // сначала пикаем детей
00113         for (VectorILayerNode::const_iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter)
00114         {
00115             ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
00116             if (nullptr != item)
00117                 return item;
00118         }
00119 
00120         for (VectorLayerItem::const_iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
00121         {
00122             ILayerItem* item = (*iter)->getLayerItemByPoint(_left, _top);
00123             if (nullptr != item)
00124                 return item;
00125         }
00126 
00127         return nullptr;
00128     }
00129 
00130     RenderItem* LayerNode::addToRenderItem(ITexture* _texture, bool _firstQueue, bool _manualRender)
00131     {
00132         RenderItem* item = nullptr;
00133         if (_firstQueue)
00134             item = addToRenderItemFirstQueue(_texture, _manualRender);
00135         else
00136             item = addToRenderItemSecondQueue(_texture, _manualRender);
00137 
00138         mOutOfDate = false;
00139         return item;
00140     }
00141 
00142     RenderItem* LayerNode::addToRenderItemFirstQueue(ITexture* _texture, bool _manualRender)
00143     {
00144         if (mFirstRenderItems.empty() || _manualRender)
00145         {
00146             RenderItem* item = new RenderItem();
00147             item->setTexture(_texture);
00148             item->setManualRender(_manualRender);
00149             mFirstRenderItems.push_back(item);
00150 
00151             return item;
00152         }
00153 
00154         updateCompression();
00155 
00156         // first queue keep order
00157 
00158         // use either first empty buffer
00159         // or last non-empty buffer if it have same texture
00160         VectorRenderItem::reverse_iterator iter = mFirstRenderItems.rbegin();
00161         bool itemFound = false;
00162         while (iter != mFirstRenderItems.rend())
00163         {
00164             if ((*iter)->getNeedVertexCount() == 0)
00165             {
00166                 iter++;
00167                 itemFound = true;
00168                 continue;
00169             }
00170             else if (!(*iter)->getManualRender() && (*iter)->getTexture() == _texture)
00171             {
00172                 iter++;
00173                 itemFound = true;
00174                 break;
00175             }
00176 
00177             break;
00178         }
00179 
00180         if (itemFound)
00181         {
00182             iter--;
00183             (*iter)->setTexture(_texture);
00184 
00185             return (*iter);
00186         }
00187 
00188         // not found, create new
00189         RenderItem* item = new RenderItem();
00190         item->setTexture(_texture);
00191         item->setManualRender(_manualRender);
00192         mFirstRenderItems.push_back(item);
00193 
00194         return item;
00195     }
00196 
00197     RenderItem* LayerNode::addToRenderItemSecondQueue(ITexture* _texture, bool _manualRender)
00198     {
00199         // order is not important in second queue
00200         // use first buffer with same texture or empty buffer
00201         for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter)
00202         {
00203             if ((*iter)->getTexture() == _texture)
00204             {
00205                 return (*iter);
00206             }
00207             else if ((*iter)->getNeedVertexCount() == 0)
00208             {
00209                 (*iter)->setTexture(_texture);
00210 
00211                 return (*iter);
00212             }
00213         }
00214 
00215         // not found, create new
00216         RenderItem* item = new RenderItem();
00217         item->setTexture(_texture);
00218         item->setManualRender(_manualRender);
00219         mSecondRenderItems.push_back(item);
00220 
00221         return item;
00222     }
00223 
00224     void LayerNode::attachLayerItem(ILayerItem* _item)
00225     {
00226         mLayerItems.push_back(_item);
00227         _item->attachItemToNode(mLayer, this);
00228 
00229         mOutOfDate = true;
00230     }
00231 
00232     void LayerNode::detachLayerItem(ILayerItem* _item)
00233     {
00234         for (VectorLayerItem::iterator iter = mLayerItems.begin(); iter != mLayerItems.end(); ++iter)
00235         {
00236             if ((*iter) == _item)
00237             {
00238                 mLayerItems.erase(iter);
00239 
00240                 mOutOfDate = true;
00241 
00242                 return;
00243             }
00244         }
00245         MYGUI_EXCEPT("layer item not found");
00246     }
00247 
00248     void LayerNode::outOfDate(RenderItem* _item)
00249     {
00250         mOutOfDate = true;
00251         if (_item)
00252             _item->outOfDate();
00253     }
00254 
00255     EnumeratorILayerNode LayerNode::getEnumerator() const
00256     {
00257         return EnumeratorILayerNode(mChildItems);
00258     }
00259 
00260     size_t LayerNode::getLayerNodeCount() const
00261     {
00262         return mChildItems.size();
00263     }
00264 
00265     ILayerNode* LayerNode::getLayerNodeAt(size_t _index) const
00266     {
00267         MYGUI_ASSERT_RANGE(_index, mChildItems.size(), "LayerNode::getLayerNodeAt");
00268 
00269         return mChildItems[_index];
00270     }
00271 
00272     void LayerNode::updateCompression()
00273     {
00274         if (mFirstRenderItems.size() <= 1)
00275             return;
00276 
00277         bool need_compression = false;
00278         for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
00279         {
00280             if ((*iter)->getNeedCompression())
00281             {
00282                 need_compression = true;
00283                 break;
00284             }
00285         }
00286 
00287         // pushing all empty buffers to the end of buffers list
00288         if (need_compression)
00289         {
00290             VectorRenderItem nonEmptyItems;
00291             VectorRenderItem emptyItems;
00292 
00293             for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter)
00294             {
00295                 (*iter)->setNeedCompression(false);
00296 
00297                 if ((*iter)->getNeedVertexCount() == 0 && !(*iter)->getManualRender())
00298                     emptyItems.push_back(*iter);
00299                 else
00300                     nonEmptyItems.push_back(*iter);
00301             }
00302             nonEmptyItems.insert(nonEmptyItems.end(), emptyItems.begin(), emptyItems.end());
00303             std::swap(mFirstRenderItems, nonEmptyItems);
00304         }
00305 
00306         mOutOfDate = true;
00307     }
00308 
00309     ILayer* LayerNode::getLayer() const
00310     {
00311         return mLayer;
00312     }
00313 
00314     ILayerNode* LayerNode::getParent() const
00315     {
00316         return mParent;
00317     }
00318 
00319     bool LayerNode::isOutOfDate() const
00320     {
00321         for (VectorRenderItem::const_iterator item = mFirstRenderItems.begin(); item != mFirstRenderItems.end(); ++item)
00322         {
00323             if ((*item)->isOutOfDate())
00324                 return true;
00325         }
00326 
00327         for (VectorRenderItem::const_iterator item = mSecondRenderItems.begin(); item != mSecondRenderItems.end(); ++item)
00328         {
00329             if ((*item)->isOutOfDate())
00330                 return true;
00331         }
00332 
00333         for (VectorILayerNode::const_iterator item = mChildItems.begin(); item != mChildItems.end(); ++item)
00334         {
00335             if (static_cast<const LayerNode*>(*item)->isOutOfDate())
00336                 return true;
00337         }
00338 
00339         return mOutOfDate;
00340     }
00341 
00342     float LayerNode::getNodeDepth()
00343     {
00344         return mDepth;
00345     }
00346 
00347 } // namespace MyGUI