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