MyGUI 3.0.1

MyGUI_LayerNode.cpp

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