疑问为何LayerManager作为IUnlinkWidget 的derived class
而且在initialise()中将自己的this指针传递给WidgetManager
void LayerManager::initialise() { MYGUI_ASSERT(!mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice"); MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME); WidgetManager::getInstance().registerUnlinker(this); ResourceManager::getInstance().registerLoadXmlDelegate(XML_TYPE) = newDelegate(this, &LayerManager::_load); FactoryManager::getInstance().registerFactory<SharedLayer>(XML_TYPE); FactoryManager::getInstance().registerFactory<OverlappedLayer>(XML_TYPE); MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized"); mIsInitialise = true; }
对应于WidgetManager 中的成员函数
void WidgetManager::registerUnlinker(IUnlinkWidget * _unlink) { unregisterUnlinker(_unlink); mVectorIUnlinkWidget.push_back(_unlink); }
registerUnlinker 与 unregisterUnlinker 对应的事件逻辑是什么?
void WidgetManager::unregisterUnlinker(IUnlinkWidget * _unlink) { for (size_t pos=0; pos<mVectorIUnlinkWidget.size(); pos++) { if (mVectorIUnlinkWidget[pos] == _unlink) { mVectorIUnlinkWidget[pos] = mVectorIUnlinkWidget[mVectorIUnlinkWidget.size()-1]; mVectorIUnlinkWidget.pop_back(); break; } } }
Widget 与node 建立起关系的函数:??
void LayerManager::attachToLayerNode(const std::string& _name, Widget* _item) { MYGUI_ASSERT(nullptr != _item, "pointer must be valid"); MYGUI_ASSERT(_item->isRootWidget(), "attached widget must be root"); // сначала отсоединяем?? 先断开连接 _item->detachFromLayer(); // а теперь аттачим遍历layer 找到widget 所在的layer 将widget的layer item 添加到相应的layer中 for (VectorLayer::iterator iter=mLayerNodes.begin(); iter!=mLayerNodes.end(); ++iter) { if (_name == (*iter)->getName()) { ILayerNode* node = (*iter)->createChildItemNode(); node->attachLayerItem(_item); return; } } MYGUI_LOG(Error, "Layer '" << _name << "' is not found"); //MYGUI_EXCEPT("Layer '" << _name << "' is not found"); }
**** 重点,
LayerItem 多重继承的Widget 如图:
分析下列函数的作用:
void LayerItem::detachFromLayer() { // 禧 箧?铗溴蜞麇睇 ?漕耜? if (nullptr == mLayer) return; // 蜞觐泐 猁螯 礤 漕腈眍 MYGUI_ASSERT(mLayerNode, "_item->mLayerNode == nullptr"); // 铗镨覃忄屐? 铗 镨觋桧汔 mLayerNode->detachLayerItem(this); // 镳?溴蜞麇 钺眢腓螯? ILayerNode * save = mLayerNode; // 翳玷麇耜?铗耦邃桧屐 detachFromLayerItemNode(true); // 铗耦邃桧屐 脲屦 ?钺眢?屐 ?痼蝾忸泐 忤滏弪? mLayer->destroyChildItemNode(save); mLayerNode = nullptr; mLayer = nullptr; }
还是先分析 怎么attach上 layer的 吧;)
LayerItem attach
Widget 与LayerManger的关系很近因为Widget所需要的render item 都被组织在layer中进行集中渲染管理
从MyGui 中的widget的可以看懂的注释。
/** Set widget style. @param _layer Attach to specified layer (if any) @note When choosing WidgetStyle::Popup style you also need attach widget to layer see LayerManager::attachToLayerNode */ void setWidgetStyle(WidgetStyle _style, const std::string& _layer = "");
从工程项目的搜索中得到:
Find all "attachToLayerNode", Subfolders, Find Results 1, "Entire Solution" H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\include\MyGUI_LayerManager.h(54): void attachToLayerNode(const std::string& _name, Widget* _item); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\include\MyGUI_Widget.h(282): see LayerManager::attachToLayerNode H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Gui.cpp(196): if (!_layer.empty()) LayerManager::getInstance().attachToLayerNode(_layer, widget); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_LayerManager.cpp(135): void LayerManager::attachToLayerNode(const std::string& _name, Widget* _item) H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_PointerManager.cpp(247): LayerManager::getInstance().attachToLayerNode(_layer, widget); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_PointerManager.cpp(310): LayerManager::getInstance().attachToLayerNode(mLayerName, mMousePointer); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Message.cpp(333): if (_layer.empty()) LayerManager::getInstance().attachToLayerNode(mess->getDefaultLayer(), mess); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Widget.cpp(367): if (!_layer.empty() && widget->isRootWidget()) LayerManager::getInstance().attachToLayerNode(_layer, widget); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Widget.cpp(1287): LayerManager::getInstance().attachToLayerNode(_layer, this); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Widget.cpp(1291): LayerManager::getInstance().attachToLayerNode(oldlayer, this); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Widget.cpp(1333): LayerManager::getInstance().attachToLayerNode(_layer, this); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\MyGUIEngine\src\MyGUI_Widget.cpp(1476): LayerManager::getInstance().attachToLayerNode(layername, root); H:\MyGui\MyGUI_3.0.1_source\MyGUI3.0\UnitTests\UnitTest_AttachDetach\DemoKeeper.cpp(93): MyGUI::LayerManager::getInstance().attachToLayerNode(layername, widget); Matching lines: 13 Matching files: 8 Total files searched: 620
下面把,Ilayer,ILayerNode类的静态关系,