From e35f3b7db4803c287e95fb5aaa563e8432e71349 Mon Sep 17 00:00:00 2001 From: MartinRJ Fayray Date: Mon, 25 Jun 2012 05:09:22 +0200 Subject: STORM-1879: Inventory gear menu remains on screen after floater is closed --- indra/llui/llfloater.cpp | 4 ++++ indra/llui/lltoggleablemenu.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/llui') diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..90251ac7c6 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -748,6 +748,10 @@ void LLFloater::closeFloater(bool app_quitting) dependee->setFocus(TRUE); } } + + // STORM-1879: since this floater has focus, treat the closeFloater- call + // like a click on the close-button, and close gear- and contextmenus + LLMenuGL::sMenuContainer->hideMenus(); } dirtyRect(); diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index d29260750f..e4d1a37569 100644 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -57,7 +57,9 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn) S32 x,y; LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y); - if (!curVisibilityIn && mButtonRect.pointInRect(x, y)) + // STORM-1879: also check MouseCapture to see if the button was really + // clicked (otherwise the VisibilityChange was triggered via keyboard shortcut) + if (!curVisibilityIn && mButtonRect.pointInRect(x, y) && gFocusMgr.getMouseCapture()) { mClosedByButtonClick = true; } -- cgit v1.3 From 0ee53b21d2a7bf2cd37c7bcdc2a86e0f079fbefc Mon Sep 17 00:00:00 2001 From: Kelly Washington Date: Mon, 25 Jun 2012 13:41:53 -0700 Subject: MAINT-30 Estate access lists for groups and residents are blank when "Allow public access" is checked. MAINT-1200 Resident names not sorted in About Land (or Estate management) floater's allowed/banned boxes reviewed with Simon --- indra/llui/llscrolllistctrl.cpp | 5 ++ indra/llui/llscrolllistctrl.h | 1 + indra/newview/llfloaterland.cpp | 23 +++--- indra/newview/llfloaterregioninfo.cpp | 147 +++++++++------------------------- indra/newview/llfloaterregioninfo.h | 4 - indra/newview/llnamelistctrl.cpp | 8 +- indra/newview/llnamelistctrl.h | 2 + 7 files changed, 64 insertions(+), 126 deletions(-) (limited to 'indra/llui') diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index b3e1b63db5..82a914a30a 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2704,6 +2704,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const return !mSortColumns.empty(); } +void LLScrollListCtrl::clearSortOrder() +{ + mSortColumns.clear(); +} + void LLScrollListCtrl::clearColumns() { column_map_t::iterator itor; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index ae8aea9245..6660c07b8e 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -373,6 +373,7 @@ public: std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } BOOL hasSortOrder() const; + void clearSortOrder(); S32 selectMultiple( uuid_vec_t ids ); // conceptually const, but mutates mItemList diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index ee18c95b34..5515e93d0e 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -2371,12 +2371,6 @@ LLPanelLandAccess::~LLPanelLandAccess() void LLPanelLandAccess::refresh() { LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - if (mListAccess) - mListAccess->deleteAllItems(); - if (mListBanned) - mListBanned->deleteAllItems(); - LLParcel *parcel = mParcel->getParcel(); // Display options @@ -2394,7 +2388,11 @@ void LLPanelLandAccess::refresh() getChild("GroupCheck")->setLabelArg("[GROUP]", group_name ); // Allow list + if (mListAccess) { + // Clear the sort order so we don't re-sort on every add. + mListAccess->clearSortOrder(); + mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); getChild("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); getChild("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); @@ -2429,13 +2427,17 @@ void LLPanelLandAccess::refresh() } suffix.append(" " + parent_floater->getString("Remaining") + ")"); } - if (mListAccess) - mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); + mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } + mListAccess->sortByName(TRUE); } // Ban List + if(mListBanned) { + // Clear the sort order so we don't re-sort on every add. + mListBanned->clearSortOrder(); + mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); getChild("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); @@ -2473,6 +2475,7 @@ void LLPanelLandAccess::refresh() } mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix); } + mListBanned->sortByName(TRUE); } if(parcel->getRegionDenyAnonymousOverride()) @@ -2608,13 +2611,13 @@ void LLPanelLandAccess::refresh_ui() getChildView("AccessList")->setEnabled(can_manage_allowed); S32 allowed_list_count = parcel->mAccessList.size(); getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); - BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0; + BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected); getChildView("BannedList")->setEnabled(can_manage_banned); S32 banned_list_count = parcel->mBanList.size(); getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); - has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0; + has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected); } } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 17850ff35d..fe29bb38c7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -287,8 +287,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) //dispatch the message dispatch.dispatch(request, invoice, strings); - LLViewerRegion* region = gAgent.getRegion(); - panel->updateControls(region); + panel->updateControls(gAgent.getRegion()); } @@ -1924,10 +1923,18 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) BOOL manager = (region && region->isEstateManager()); setCtrlsEnabled(god || owner || manager); + BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager)); + getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager); + getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) ); + getChildView("allowed_group_name_list")->setEnabled(god || owner || manager); // Can't ban people from mainland, orientation islands, etc. because this // creates much network traffic and server load. @@ -1935,14 +1942,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) bool linden_estate = isLindenEstate(); bool enable_ban = (god || owner || manager) && !linden_estate; getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); // estate managers can't add estate managers getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); getChildView("estate_manager_name_list")->setEnabled(god || owner); refresh(); @@ -1979,10 +1987,8 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl) { - if (checkRemovalButton(child_ctrl->getName())) - { - // do nothing - } + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); } bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg) @@ -2080,23 +2086,8 @@ void LLPanelEstateInfo::refreshFromEstate() getChild("limit_payment")->setValue(estate_info.getDenyAnonymous()); getChild("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); - // If visible from mainland, disable the access allowed - // UI, as anyone can teleport there. - // However, gods need to be able to edit the access list for - // linden estates, regardless of visibility, to allow object - // and L$ transfers. - { - bool visible_from_mainland = estate_info.getIsExternallyVisible(); - bool god = gAgent.isGodlike(); - bool linden_estate = isLindenEstate(); - - bool enable_agent = (!visible_from_mainland || (god && linden_estate)); - bool enable_group = enable_agent; - bool enable_ban = !linden_estate; - - setAccessAllowedEnabled(enable_agent, enable_group, enable_ban); - } - + // Ensure appriopriate state of the management UI + updateControls(gAgent.getRegion()); refresh(); } @@ -2225,47 +2216,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) getChild("estate_owner")->setValue(LLSD(name)); } -void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent, - bool enable_group, - bool enable_ban) -{ - getChildView("allow_resident_label")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setEnabled(enable_agent); - getChildView("allowed_avatar_name_list")->setVisible( enable_agent); - getChildView("add_allowed_avatar_btn")->setEnabled(enable_agent); - getChildView("remove_allowed_avatar_btn")->setEnabled(enable_agent); - - // Groups - getChildView("allow_group_label")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setEnabled(enable_group); - getChildView("allowed_group_name_list")->setVisible( enable_group); - getChildView("add_allowed_group_btn")->setEnabled(enable_group); - getChildView("remove_allowed_group_btn")->setEnabled(enable_group); - - // Ban - getChildView("ban_resident_label")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(enable_ban); - getChildView("banned_avatar_name_list")->setVisible( enable_ban); - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban); - - // Update removal buttons if needed - if (enable_agent) - { - checkRemovalButton("allowed_avatar_name_list"); - } - - if (enable_group) - { - checkRemovalButton("allowed_group_name_list"); - } - - if (enable_ban) - { - checkRemovalButton("banned_avatar_name_list"); - } -} - void LLPanelEstateInfo::clearAccessLists() { LLNameListCtrl* name_list = getChild("allowed_avatar_name_list"); @@ -2279,39 +2229,7 @@ void LLPanelEstateInfo::clearAccessLists() { name_list->deleteAllItems(); } -} - -// enables/disables the "remove" button for the various allow/ban lists -BOOL LLPanelEstateInfo::checkRemovalButton(std::string name) -{ - std::string btn_name = ""; - if (name == "allowed_avatar_name_list") - { - btn_name = "remove_allowed_avatar_btn"; - } - else if (name == "allowed_group_name_list") - { - btn_name = "remove_allowed_group_btn"; - } - else if (name == "banned_avatar_name_list") - { - btn_name = "remove_banned_avatar_btn"; - } - else if (name == "estate_manager_name_list") - { - //ONLY OWNER CAN ADD /DELET ESTATE MANAGER - LLViewerRegion* region = gAgent.getRegion(); - if (region && (region->getOwner() == gAgent.getID())) - { - btn_name = "remove_estate_manager_btn"; - } - } - - // enable the remove button if something is selected - LLNameListCtrl* name_list = getChild(name); - getChildView(btn_name)->setEnabled(name_list && name_list->getFirstSelected() ? TRUE : FALSE); - - return (btn_name != ""); + updateControls(gAgent.getRegion()); } // static @@ -2792,15 +2710,15 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_agent_name_list) { - //allowed_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + allowed_agent_name_list->clearSortOrder(); for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_agent_name_list->addNameItem(id); } - panel->getChildView("remove_allowed_avatar_btn")->setEnabled(allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_agent_name_list->sortByColumnIndex(0, TRUE); + allowed_agent_name_list->sortByName(TRUE); } } @@ -2817,6 +2735,8 @@ bool LLDispatchSetEstateAccess::operator()( if (allowed_group_name_list) { + // Don't sort these as we add them, sort them when we are done. + allowed_group_name_list->clearSortOrder(); allowed_group_name_list->deleteAllItems(); for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) { @@ -2824,8 +2744,7 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ allowed_group_name_list->addGroupNameItem(id); } - panel->getChildView("remove_allowed_group_btn")->setEnabled(allowed_group_name_list->getFirstSelected() ? TRUE : FALSE); - allowed_group_name_list->sortByColumnIndex(0, TRUE); + allowed_group_name_list->sortByName(TRUE); } } @@ -2849,15 +2768,16 @@ bool LLDispatchSetEstateAccess::operator()( if (banned_agent_name_list) { - //banned_agent_name_list->deleteAllItems(); + // Don't sort these as we add them, sort them when we are done. + banned_agent_name_list->clearSortOrder(); + for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ banned_agent_name_list->addNameItem(id); } - panel->getChildView("remove_banned_avatar_btn")->setEnabled(banned_agent_name_list->getFirstSelected() ? TRUE : FALSE); - banned_agent_name_list->sortByColumnIndex(0, TRUE); + banned_agent_name_list->sortByName(TRUE); } } @@ -2872,6 +2792,9 @@ bool LLDispatchSetEstateAccess::operator()( panel->getChild("estate_manager_name_list"); if (estate_manager_name_list) { + // Don't sort these as we add them, sort them when we are done. + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); // Clear existing entries // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't @@ -2883,11 +2806,13 @@ bool LLDispatchSetEstateAccess::operator()( memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ estate_manager_name_list->addNameItem(id); } - panel->getChildView("remove_estate_manager_btn")->setEnabled(estate_manager_name_list->getFirstSelected() ? TRUE : FALSE); - estate_manager_name_list->sortByColumnIndex(0, TRUE); + estate_manager_name_list->sortByName(TRUE); } } + // Update the buttons which may change based on the list contents but also needs to account for general access features. + panel->updateControls(gAgent.getRegion()); + return true; } diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index e36ef4604b..f0499f1903 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -312,9 +312,6 @@ public: const std::string getOwnerName() const; void setOwnerName(const std::string& name); - // If visible from mainland, allowed agent and allowed groups - // are ignored, so must disable UI. - void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban); protected: virtual BOOL sendUpdate(); // confirmation dialog callback @@ -324,7 +321,6 @@ protected: void commitEstateManagers(); void clearAccessLists(); - BOOL checkRemovalButton(std::string name); BOOL checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 4e28d1f526..11b057eb0d 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -401,7 +401,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, name = av_name.getCompleteName(); item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); iter++) + for (iter = getItemList().begin(); iter != getItemList().end(); ++iter) { LLScrollListItem* item = *iter; if (item->getUUID() == agent_id) @@ -410,6 +410,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, if (cell) { cell->setValue(name); + setNeedsSort(); } } } @@ -431,3 +432,8 @@ void LLNameListCtrl::updateColumns() } } } + +void LLNameListCtrl::sortByName(BOOL ascending) +{ + sortByColumnIndex(mNameColumnIndex,ascending); +} diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index ca9956dc53..77c21f92e2 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -110,6 +110,8 @@ public: void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } + void sortByName(BOOL ascending); + /*virtual*/ void updateColumns(); /*virtual*/ void mouseOverHighlightNthItem( S32 index ); -- cgit v1.3 From 18bd525d00ee3ce16164900293ee6ea8c2204589 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Jul 2012 08:14:34 -0400 Subject: MAINT-1175: Forbid LLRegistry[Singleton]. Back out code that selects LLTypeInfoLookup for the underlying map implementation when KEY = [const] std::type_info*, because LLTypeInfoLookup's API is changing to become incompatible with std::map. Instead, fail with STATIC_ASSERT when LLRegistry's KEY is [const] std::type_info*. Fix all existing uses to use std::type_info::name() string instead. --- indra/llcommon/llregistry.h | 30 ++++++++++-------------------- indra/llui/llfloater.cpp | 2 +- indra/llui/llradiogroup.cpp | 2 +- indra/llui/llrngwriter.cpp | 2 +- indra/llui/llscrolllistcolumn.cpp | 2 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltooltip.cpp | 2 +- indra/llui/lluictrlfactory.cpp | 6 +++--- indra/llui/lluictrlfactory.h | 4 ++-- indra/llui/llxuiparser.cpp | 2 +- indra/llui/llxuiparser.h | 3 ++- indra/newview/llavatarlistitem.cpp | 2 +- indra/newview/llinventorylistitem.cpp | 2 +- indra/newview/llwearableitemslist.cpp | 8 ++++---- 14 files changed, 30 insertions(+), 39 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 36d7f7a44c..843c169f3d 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -30,8 +30,8 @@ #include #include +#include #include "llsingleton.h" -#include "lltypeinfolookup.h" template class LLRegistryDefaultComparator @@ -39,27 +39,17 @@ class LLRegistryDefaultComparator bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; } }; -template -struct LLRegistryMapSelector -{ - typedef std::map type; -}; - -template -struct LLRegistryMapSelector -{ - typedef LLTypeInfoLookup type; -}; - -template -struct LLRegistryMapSelector -{ - typedef LLTypeInfoLookup type; -}; - template > class LLRegistry { + // Do not use LLRegistry with KEY = std::type_info* or KEY = const std::type_info*. + // This is known to fail on Linux. + // If you must use LLRegistry with dynamic type info, use KEY = const char* + // and pass std::type_info::name(); this works across load modules. + // Disallow both std::type_info* and const std::type_info*. First remove + // the pointer, then remove const, then compare is_same. + BOOST_STATIC_ASSERT(! (boost::is_same::type>::type, std::type_info>::value)); + public: typedef LLRegistry registry_t; typedef typename boost::add_reference::type>::type ref_const_key_t; @@ -72,7 +62,7 @@ public: { friend class LLRegistry; public: - typedef typename LLRegistryMapSelector::type registry_map_t; + typedef std::map registry_map_t; bool add(ref_const_key_t key, ref_const_value_t value) { diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..f20cc2452f 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -232,7 +232,7 @@ void LLFloater::initClass() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params).name(), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), // intentionally do not pass params here, see initFromParams diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 95a7d09382..71bbcd8ade 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -66,7 +66,7 @@ protected: LLSD mPayload; // stores data that this item represents in the radio group }; -static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); +static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams).name(), "radio_item"); LLRadioGroup::Params::Params() : allow_deselect("allow_deselect"), diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 5e6840d7df..90a1e77b1a 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -92,7 +92,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam: // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); // add include declarations for all valid children for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index 07a6dfaa10..d132d0cc7e 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -39,7 +39,7 @@ const S32 MIN_COLUMN_WIDTH = 20; // defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params).name(), "scroll_column_header"); //--------------------------------------------------------------------------- // LLScrollColumnHeader diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7aeeae298f..8314386632 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -131,7 +131,7 @@ struct LLTextBase::line_end_compare // // register LLTextBase::Params under name "textbase" -static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params).name(), "textbase"); LLTextBase::LineSpacingParams::LineSpacingParams() : multiple("multiple", 1.f), diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index f737d48abf..0723dbec70 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params).name(), "inspector"); // // LLToolTip diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 25e7a31e90..fe3b470722 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -281,7 +281,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag) { // associate parameter block type with template .xml file - std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type); + std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type->name()); if (existing_tag != NULL) { if(*existing_tag != tag) @@ -297,7 +297,7 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st return; } } - LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag); + LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type->name(), tag); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block); @@ -306,6 +306,6 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st //static const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type) { - return LLWidgetNameRegistry::instance().getValue(widget_type); + return LLWidgetNameRegistry::instance().getValue(widget_type->name()); } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index d612ad5005..1f7a8e08ce 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -69,9 +69,9 @@ protected: friend class LLSingleton; }; -// lookup widget name by type +// lookup widget name by type (actually by std::type_info::name()) class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index afc76024d1..c3a246b9a5 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -606,7 +606,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); // add choices for valid children if (widget_registryp) diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index d7cd256967..3c092afdd6 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -55,8 +55,9 @@ typedef boost::function widget_registry_t; +// const char* key used for std::type_info::name() string class LLChildRegistryRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 30eecfe323..c07fec8e5e 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -44,7 +44,7 @@ S32 LLAvatarListItem::sLeftPadding = 0; S32 LLAvatarListItem::sNameRightPadding = 0; S32 LLAvatarListItem::sChildrenWidths[LLAvatarListItem::ALIC_COUNT]; -static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(&typeid(LLAvatarListItem::Params), "avatar_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(typeid(LLAvatarListItem::Params).name(), "avatar_list_item"); LLAvatarListItem::Params::Params() : default_style("default_style"), diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index 3e0849a795..5489671430 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -40,7 +40,7 @@ #include "llinventorymodel.h" #include "llviewerinventory.h" -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(typeid(LLPanelInventoryListItemBase::Params).name(), "inventory_list_item"); static const S32 WIDGET_SPACING = 3; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 92697fb2eb..abb53301a6 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -135,7 +135,7 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(&typeid(LLPanelClothingListItem::Params), "clothing_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(typeid(LLPanelClothingListItem::Params).name(), "clothing_list_item"); LLPanelClothingListItem::Params::Params() @@ -222,7 +222,7 @@ BOOL LLPanelClothingListItem::postBuild() ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(&typeid(LLPanelBodyPartsListItem::Params), "bodyparts_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(typeid(LLPanelBodyPartsListItem::Params).name(), "bodyparts_list_item"); LLPanelBodyPartsListItem::Params::Params() @@ -293,7 +293,7 @@ BOOL LLPanelBodyPartsListItem::postBuild() return TRUE; } -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(&typeid(LLPanelDeletableWearableListItem::Params), "deletable_wearable_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(typeid(LLPanelDeletableWearableListItem::Params).name(), "deletable_wearable_list_item"); LLPanelDeletableWearableListItem::Params::Params() : delete_btn("delete_btn") @@ -373,7 +373,7 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name, ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(&typeid(LLPanelDummyClothingListItem::Params), "dummy_clothing_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(typeid(LLPanelDummyClothingListItem::Params).name(), "dummy_clothing_list_item"); LLPanelDummyClothingListItem::Params::Params() : add_panel("add_panel"), -- cgit v1.3 From 709c1eeae90dae106800e3742f3655bd7b590b7b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Jul 2012 14:13:45 -0400 Subject: MAINT-1175: Properly pass LLRegistry's COMPARATOR to underlying map. Although LLRegistry and LLRegistrySingleton have always defined a COMPARATOR template parameter, it wasn't used for the underlying map. Therefore every type, including any pointer type, was being compared using std::less. This happens to work most of the time -- but is tripping us up now. Pass COMPARATOR to underlying std::map. Fix a couple minor bugs in LLRegistryDefaultComparator (never before used!). Specialize for const char*. Remove CompareTypeID and LLCompareTypeID because we now actively forbid using LLRegistry; remove only known reference (LLWidgetNameRegistry definition). --- indra/llcommon/llinitparam.h | 8 -------- indra/llcommon/llregistry.h | 16 +++++++++++++--- indra/llui/lluictrlfactory.h | 11 +---------- 3 files changed, 14 insertions(+), 21 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index c0170e533b..66c72c2d9f 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -212,14 +212,6 @@ namespace LLInitParam public: - struct CompareTypeID - { - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } - }; - typedef std::vector > name_stack_t; typedef std::pair name_stack_range_t; typedef std::vector possible_values_t; diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 843c169f3d..8eeab59024 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -34,9 +34,19 @@ #include "llsingleton.h" template -class LLRegistryDefaultComparator +struct LLRegistryDefaultComparator { - bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; } + bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } +}; + +// comparator for const char* registry keys +template <> +struct LLRegistryDefaultComparator +{ + bool operator()(const char* lhs, const char* rhs) const + { + return strcmp(lhs, rhs) < 0; + } }; template > @@ -62,7 +72,7 @@ public: { friend class LLRegistry; public: - typedef std::map registry_map_t; + typedef std::map registry_map_t; bool add(ref_const_key_t key, ref_const_value_t value) { diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1f7a8e08ce..a5fd83e555 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -34,15 +34,6 @@ class LLView; -// sort functor for typeid maps -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } -}; - // lookup widget constructor funcs by widget name template class LLChildRegistry : public LLRegistrySingleton @@ -71,7 +62,7 @@ protected: // lookup widget name by type (actually by std::type_info::name()) class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type -- cgit v1.3 From 7f609b6a6958f519bb1becb604132b583ada3fad Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Jul 2012 15:51:34 -0400 Subject: Backed out changeset a25bfa87418d (using std::type_info::name()) The changeset above touched every consumer of the two LLRegistrySingletons originally defined with std::type_info* as keys. Those two LLRegistrySingletons were changed to use const char* as keys, then all consumers were changed to pass std::type_info::name() instead of the plain std::type_info* pointer -- to deal with the observed fact that on Linux, a given type might produce different std::type_info* pointers in different load modules. Since then, Richard turned up the fascinating fact that at least some implementations of gcc's std::type_info::before() method already accommodate this peculiarity. It seems worth backing out the (dismayingly pervasive) change to see if properly using std::type_info::before() as the map comparator will work just as well, with conceptually simpler source code. This backout is transitional: we don't expect things to build/run properly until we've cherry-picked certain other pertinent changes. --- indra/llcommon/llregistry.h | 30 ++++++++++++++++++++---------- indra/llui/llfloater.cpp | 2 +- indra/llui/llradiogroup.cpp | 2 +- indra/llui/llrngwriter.cpp | 2 +- indra/llui/llscrolllistcolumn.cpp | 2 +- indra/llui/lltextbase.cpp | 2 +- indra/llui/lltooltip.cpp | 2 +- indra/llui/lluictrlfactory.cpp | 6 +++--- indra/llui/lluictrlfactory.h | 4 ++-- indra/llui/llxuiparser.cpp | 2 +- indra/llui/llxuiparser.h | 3 +-- indra/newview/llavatarlistitem.cpp | 2 +- indra/newview/llinventorylistitem.cpp | 2 +- indra/newview/llwearableitemslist.cpp | 8 ++++---- 14 files changed, 39 insertions(+), 30 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 843c169f3d..36d7f7a44c 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -30,8 +30,8 @@ #include #include -#include #include "llsingleton.h" +#include "lltypeinfolookup.h" template class LLRegistryDefaultComparator @@ -39,17 +39,27 @@ class LLRegistryDefaultComparator bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; } }; +template +struct LLRegistryMapSelector +{ + typedef std::map type; +}; + +template +struct LLRegistryMapSelector +{ + typedef LLTypeInfoLookup type; +}; + +template +struct LLRegistryMapSelector +{ + typedef LLTypeInfoLookup type; +}; + template > class LLRegistry { - // Do not use LLRegistry with KEY = std::type_info* or KEY = const std::type_info*. - // This is known to fail on Linux. - // If you must use LLRegistry with dynamic type info, use KEY = const char* - // and pass std::type_info::name(); this works across load modules. - // Disallow both std::type_info* and const std::type_info*. First remove - // the pointer, then remove const, then compare is_same. - BOOST_STATIC_ASSERT(! (boost::is_same::type>::type, std::type_info>::value)); - public: typedef LLRegistry registry_t; typedef typename boost::add_reference::type>::type ref_const_key_t; @@ -62,7 +72,7 @@ public: { friend class LLRegistry; public: - typedef std::map registry_map_t; + typedef typename LLRegistryMapSelector::type registry_map_t; bool add(ref_const_key_t key, ref_const_value_t value) { diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index f20cc2452f..8ca1e685a9 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -232,7 +232,7 @@ void LLFloater::initClass() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(typeid(LLFloater::Params).name(), "floater"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFloater::Params), "floater"); LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) : LLPanel(), // intentionally do not pass params here, see initFromParams diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp index 71bbcd8ade..95a7d09382 100644 --- a/indra/llui/llradiogroup.cpp +++ b/indra/llui/llradiogroup.cpp @@ -66,7 +66,7 @@ protected: LLSD mPayload; // stores data that this item represents in the radio group }; -static LLWidgetNameRegistry::StaticRegistrar register_radio_item(typeid(LLRadioGroup::ItemParams).name(), "radio_item"); +static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item"); LLRadioGroup::Params::Params() : allow_deselect("allow_deselect"), diff --git a/indra/llui/llrngwriter.cpp b/indra/llui/llrngwriter.cpp index 90a1e77b1a..5e6840d7df 100644 --- a/indra/llui/llrngwriter.cpp +++ b/indra/llui/llrngwriter.cpp @@ -92,7 +92,7 @@ void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam: // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add include declarations for all valid children for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index d132d0cc7e..07a6dfaa10 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -39,7 +39,7 @@ const S32 MIN_COLUMN_WIDTH = 20; // defaults for LLScrollColumnHeader param block pulled from widgets/scroll_column_header.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(typeid(LLScrollColumnHeader::Params).name(), "scroll_column_header"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterColumnHeaderParams(&typeid(LLScrollColumnHeader::Params), "scroll_column_header"); //--------------------------------------------------------------------------- // LLScrollColumnHeader diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8314386632..7aeeae298f 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -131,7 +131,7 @@ struct LLTextBase::line_end_compare // // register LLTextBase::Params under name "textbase" -static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(typeid(LLTextBase::Params).name(), "textbase"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase"); LLTextBase::LineSpacingParams::LineSpacingParams() : multiple("multiple", 1.f), diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 0723dbec70..f737d48abf 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -129,7 +129,7 @@ void LLToolTipView::drawStickyRect() } // defaults for floater param block pulled from widgets/floater.xml -static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(typeid(LLInspector::Params).name(), "inspector"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterInspectorParams(&typeid(LLInspector::Params), "inspector"); // // LLToolTip diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index fe3b470722..25e7a31e90 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -281,7 +281,7 @@ const LLInitParam::BaseBlock& get_empty_param_block() void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag) { // associate parameter block type with template .xml file - std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type->name()); + std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type); if (existing_tag != NULL) { if(*existing_tag != tag) @@ -297,7 +297,7 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st return; } } - LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type->name(), tag); + LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag); //FIXME: comment this in when working on schema generation //LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type); //LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block); @@ -306,6 +306,6 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st //static const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type) { - return LLWidgetNameRegistry::instance().getValue(widget_type->name()); + return LLWidgetNameRegistry::instance().getValue(widget_type); } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1f7a8e08ce..d612ad5005 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -69,9 +69,9 @@ protected: friend class LLSingleton; }; -// lookup widget name by type (actually by std::type_info::name()) +// lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index c3a246b9a5..afc76024d1 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -606,7 +606,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); - const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type->name()); + const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add choices for valid children if (widget_registryp) diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index 3c092afdd6..d7cd256967 100644 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -55,9 +55,8 @@ typedef boost::function widget_registry_t; -// const char* key used for std::type_info::name() string class LLChildRegistryRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index c07fec8e5e..30eecfe323 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -44,7 +44,7 @@ S32 LLAvatarListItem::sLeftPadding = 0; S32 LLAvatarListItem::sNameRightPadding = 0; S32 LLAvatarListItem::sChildrenWidths[LLAvatarListItem::ALIC_COUNT]; -static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(typeid(LLAvatarListItem::Params).name(), "avatar_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterAvatarListItemParams(&typeid(LLAvatarListItem::Params), "avatar_list_item"); LLAvatarListItem::Params::Params() : default_style("default_style"), diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index 5489671430..3e0849a795 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -40,7 +40,7 @@ #include "llinventorymodel.h" #include "llviewerinventory.h" -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(typeid(LLPanelInventoryListItemBase::Params).name(), "inventory_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item"); static const S32 WIDGET_SPACING = 3; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index abb53301a6..92697fb2eb 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -135,7 +135,7 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(typeid(LLPanelClothingListItem::Params).name(), "clothing_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelClothingListItem(&typeid(LLPanelClothingListItem::Params), "clothing_list_item"); LLPanelClothingListItem::Params::Params() @@ -222,7 +222,7 @@ BOOL LLPanelClothingListItem::postBuild() ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(typeid(LLPanelBodyPartsListItem::Params).name(), "bodyparts_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelBodyPartsListItem(&typeid(LLPanelBodyPartsListItem::Params), "bodyparts_list_item"); LLPanelBodyPartsListItem::Params::Params() @@ -293,7 +293,7 @@ BOOL LLPanelBodyPartsListItem::postBuild() return TRUE; } -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(typeid(LLPanelDeletableWearableListItem::Params).name(), "deletable_wearable_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDeletableWearableListItem(&typeid(LLPanelDeletableWearableListItem::Params), "deletable_wearable_list_item"); LLPanelDeletableWearableListItem::Params::Params() : delete_btn("delete_btn") @@ -373,7 +373,7 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name, ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(typeid(LLPanelDummyClothingListItem::Params).name(), "dummy_clothing_list_item"); +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelDummyClothingListItem(&typeid(LLPanelDummyClothingListItem::Params), "dummy_clothing_list_item"); LLPanelDummyClothingListItem::Params::Params() : add_panel("add_panel"), -- cgit v1.3 From 2e83dfa217feb90e7b94e499346ad9b98fa711b2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Jul 2012 20:33:54 -0400 Subject: MAINT-1175: Ditch LLTypeInfoLookup, make map work. Instead of forbidding std::map outright (which includes LLRegistry and LLRegistrySingleton), try to make it work by specializing std::less to use std::type_info::before(). Make LLRegistryDefaultComparator use std::less so it can capitalize on that specialization. --- indra/llcommon/llinitparam.h | 32 ++++++++++++++++---------------- indra/llcommon/llregistry.h | 34 ++++------------------------------ indra/llcommon/llstl.h | 30 ++++++++++++++++++++++++++++++ indra/llui/lluictrlfactory.h | 5 +++-- 4 files changed, 53 insertions(+), 48 deletions(-) (limited to 'indra/llui') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 66c72c2d9f..9a6d1eff5c 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -35,7 +35,7 @@ #include #include "llerror.h" -#include "lltypeinfolookup.h" +#include "llstl.h" namespace LLInitParam { @@ -220,9 +220,9 @@ namespace LLInitParam typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&); typedef boost::function parser_inspect_func_t; - typedef LLTypeInfoLookup parser_read_func_map_t; - typedef LLTypeInfoLookup parser_write_func_map_t; - typedef LLTypeInfoLookup parser_inspect_func_map_t; + typedef std::map parser_read_func_map_t; + typedef std::map parser_write_func_map_t; + typedef std::map parser_inspect_func_map_t; Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), @@ -234,20 +234,20 @@ namespace LLInitParam template bool readValue(T& param) { - boost::optional found_it = mParserReadFuncs->find(); - if (found_it) + parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); + if (found_it != mParserReadFuncs->end()) { - return (*found_it)(*this, (void*)¶m); + return found_it->second(*this, (void*)¶m); } return false; } template bool writeValue(const T& param, name_stack_t& name_stack) { - boost::optional found_it = mParserWriteFuncs->find(); - if (found_it) + parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); + if (found_it != mParserWriteFuncs->end()) { - return (*found_it)(*this, (const void*)¶m, name_stack); + return found_it->second(*this, (const void*)¶m, name_stack); } return false; } @@ -255,10 +255,10 @@ namespace LLInitParam // dispatch inspection to registered inspection functions, for each parameter in a param block template bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values) { - boost::optional found_it = mParserInspectFuncs->find(); - if (found_it) + parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T)); + if (found_it != mParserInspectFuncs->end()) { - (*found_it)(name_stack, min_count, max_count, possible_values); + found_it->second(name_stack, min_count, max_count, possible_values); return true; } return false; @@ -273,14 +273,14 @@ namespace LLInitParam template void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL) { - mParserReadFuncs->insert(read_func); - mParserWriteFuncs->insert(write_func); + mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func)); + mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func)); } template void registerInspectFunc(parser_inspect_func_t inspect_func) { - mParserInspectFuncs->insert(inspect_func); + mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func)); } bool mParseSilently; diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 2df9bc6541..853c427a13 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -31,44 +31,18 @@ #include #include "llsingleton.h" -#include "lltypeinfolookup.h" +#include "llstl.h" template struct LLRegistryDefaultComparator { - // It would be Bad if this comparison were used for const char* - BOOST_STATIC_ASSERT(! (boost::is_same::type>::type, char>::value)); - bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } -}; - -// comparator for const char* registry keys -template <> -struct LLRegistryDefaultComparator -{ - bool operator()(const char* lhs, const char* rhs) const + bool operator()(const T& lhs, const T& rhs) const { - return strcmp(lhs, rhs) < 0; + using std::less; + return less()(lhs, rhs); } }; -template -struct LLRegistryMapSelector -{ - typedef std::map type; -}; - -template -struct LLRegistryMapSelector -{ - typedef LLTypeInfoLookup type; -}; - -template -struct LLRegistryMapSelector -{ - typedef LLTypeInfoLookup type; -}; - template > class LLRegistry { diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 8ad12c9a03..6109b21546 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -33,6 +33,7 @@ #include #include #include +#include // Use to compare the first element only of a pair // e.g. typedef std::set, compare_pair > some_pair_set_t; @@ -470,4 +471,33 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); } +/** + * Specialize std::less to use std::type_info::before(). + * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* + * because, on Linux, you might get different std::type_info* pointers for the + * same type (from different load modules)! + */ +namespace std +{ + template <> + struct less: + public std::binary_function + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return lhs->before(*rhs); + } + }; + + template <> + struct less: + public std::binary_function + { + bool operator()(std::type_info* lhs, std::type_info* rhs) const + { + return lhs->before(*rhs); + } + }; +} // std + #endif // LL_LLSTL_H diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index ab16805cb1..4e54354731 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -31,6 +31,7 @@ #include "llinitparam.h" #include "llregistry.h" #include "llxuiparser.h" +#include "llstl.h" class LLView; @@ -62,14 +63,14 @@ protected: // lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton +: public LLRegistrySingleton {}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry -//: public LLRegistrySingleton +//: public LLRegistrySingleton //{}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; -- cgit v1.3 From 50f3e227a2ba511a1110b3e5a214db73ba3cc4e8 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 8 Aug 2012 13:23:02 -0400 Subject: Move llhandle.h into llcommon; same generality as llpointer.h. Leaving llhandle.h in llui restricts the set of viewer project directories which could potentially use it, and there's nothing whatsoever UI-specific about it. --- indra/llcommon/CMakeLists.txt | 1 + indra/llcommon/llhandle.h | 181 ++++++++++++++++++++++++++++++++++++++++++ indra/llui/CMakeLists.txt | 1 - indra/llui/llhandle.h | 181 ------------------------------------------ 4 files changed, 182 insertions(+), 182 deletions(-) create mode 100644 indra/llcommon/llhandle.h delete mode 100644 indra/llui/llhandle.h (limited to 'indra/llui') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index dd7b8c6eb8..36a8319189 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -174,6 +174,7 @@ set(llcommon_HEADER_FILES llfoldertype.h llformat.h llframetimer.h + llhandle.h llhash.h llheartbeat.h llhttpstatuscodes.h diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h new file mode 100644 index 0000000000..37c657dd92 --- /dev/null +++ b/indra/llcommon/llhandle.h @@ -0,0 +1,181 @@ +/** +* @file llhandle.h +* @brief "Handle" to an object (usually a floater) whose lifetime you don't +* control. +* +* $LicenseInfo:firstyear=2001&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LLHANDLE_H +#define LLHANDLE_H + +#include "llpointer.h" +#include +#include + +class LLTombStone : public LLRefCount +{ +public: + LLTombStone(void* target = NULL) : mTarget(target) {} + + void setTarget(void* target) { mTarget = target; } + void* getTarget() const { return mTarget; } +private: + mutable void* mTarget; +}; + +// LLHandles are used to refer to objects whose lifetime you do not control or influence. +// Calling get() on a handle will return a pointer to the referenced object or NULL, +// if the object no longer exists. Note that during the lifetime of the returned pointer, +// you are assuming that the object will not be deleted by any action you perform, +// or any other thread, as normal when using pointers, so avoid using that pointer outside of +// the local code block. +// +// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 + +template +class LLHandle +{ + template friend class LLHandle; + template friend class LLHandleProvider; +public: + LLHandle() : mTombStone(getDefaultTombStone()) {} + + template + LLHandle(const LLHandle& other, typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) + : mTombStone(other.mTombStone) + {} + + bool isDead() const + { + return mTombStone->getTarget() == NULL; + } + + void markDead() + { + mTombStone = getDefaultTombStone(); + } + + T* get() const + { + return reinterpret_cast(mTombStone->getTarget()); + } + + friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone == rhs.mTombStone; + } + friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) + { + return !(lhs == rhs); + } + friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone < rhs.mTombStone; + } + friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) + { + return lhs.mTombStone > rhs.mTombStone; + } + +protected: + LLPointer mTombStone; + +private: + typedef T* pointer_t; + static LLPointer& getDefaultTombStone() + { + static LLPointer sDefaultTombStone = new LLTombStone; + return sDefaultTombStone; + } +}; + +template +class LLRootHandle : public LLHandle +{ +public: + typedef LLRootHandle self_t; + typedef LLHandle base_t; + + LLRootHandle(T* object) { bind(object); } + LLRootHandle() {}; + ~LLRootHandle() { unbind(); } + + // this is redundant, since an LLRootHandle *is* an LLHandle + //LLHandle getHandle() { return LLHandle(*this); } + + void bind(T* object) + { + // unbind existing tombstone + if (LLHandle::mTombStone.notNull()) + { + if (LLHandle::mTombStone->getTarget() == (void*)object) return; + LLHandle::mTombStone->setTarget(NULL); + } + // tombstone reference counted, so no paired delete + LLHandle::mTombStone = new LLTombStone((void*)object); + } + + void unbind() + { + LLHandle::mTombStone->setTarget(NULL); + } + + //don't allow copying of root handles, since there should only be one +private: + LLRootHandle(const LLRootHandle& other) {}; +}; + +// Use this as a mixin for simple classes that need handles and when you don't +// want handles at multiple points of the inheritance hierarchy +template +class LLHandleProvider +{ +public: + LLHandle getHandle() const + { + // perform lazy binding to avoid small tombstone allocations for handle + // providers whose handles are never referenced + mHandle.bind(static_cast(const_cast* >(this))); + return mHandle; + } + +protected: + typedef LLHandle handle_type_t; + LLHandleProvider() + { + // provided here to enforce T deriving from LLHandleProvider + } + + template + LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const + { + LLHandle downcast_handle; + downcast_handle.mTombStone = getHandle().mTombStone; + return downcast_handle; + } + + +private: + mutable LLRootHandle mHandle; +}; + +#endif diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cca4ca3981..d92b6aa1c0 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -155,7 +155,6 @@ set(llui_HEADER_FILES llflyoutbutton.h llfocusmgr.h llfunctorregistry.h - llhandle.h llhelp.h lliconctrl.h llkeywords.h diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h deleted file mode 100644 index 37c657dd92..0000000000 --- a/indra/llui/llhandle.h +++ /dev/null @@ -1,181 +0,0 @@ -/** -* @file llhandle.h -* @brief "Handle" to an object (usually a floater) whose lifetime you don't -* control. -* -* $LicenseInfo:firstyear=2001&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ -#ifndef LLHANDLE_H -#define LLHANDLE_H - -#include "llpointer.h" -#include -#include - -class LLTombStone : public LLRefCount -{ -public: - LLTombStone(void* target = NULL) : mTarget(target) {} - - void setTarget(void* target) { mTarget = target; } - void* getTarget() const { return mTarget; } -private: - mutable void* mTarget; -}; - -// LLHandles are used to refer to objects whose lifetime you do not control or influence. -// Calling get() on a handle will return a pointer to the referenced object or NULL, -// if the object no longer exists. Note that during the lifetime of the returned pointer, -// you are assuming that the object will not be deleted by any action you perform, -// or any other thread, as normal when using pointers, so avoid using that pointer outside of -// the local code block. -// -// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669 - -template -class LLHandle -{ - template friend class LLHandle; - template friend class LLHandleProvider; -public: - LLHandle() : mTombStone(getDefaultTombStone()) {} - - template - LLHandle(const LLHandle& other, typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) - : mTombStone(other.mTombStone) - {} - - bool isDead() const - { - return mTombStone->getTarget() == NULL; - } - - void markDead() - { - mTombStone = getDefaultTombStone(); - } - - T* get() const - { - return reinterpret_cast(mTombStone->getTarget()); - } - - friend bool operator== (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone == rhs.mTombStone; - } - friend bool operator!= (const LLHandle& lhs, const LLHandle& rhs) - { - return !(lhs == rhs); - } - friend bool operator< (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone < rhs.mTombStone; - } - friend bool operator> (const LLHandle& lhs, const LLHandle& rhs) - { - return lhs.mTombStone > rhs.mTombStone; - } - -protected: - LLPointer mTombStone; - -private: - typedef T* pointer_t; - static LLPointer& getDefaultTombStone() - { - static LLPointer sDefaultTombStone = new LLTombStone; - return sDefaultTombStone; - } -}; - -template -class LLRootHandle : public LLHandle -{ -public: - typedef LLRootHandle self_t; - typedef LLHandle base_t; - - LLRootHandle(T* object) { bind(object); } - LLRootHandle() {}; - ~LLRootHandle() { unbind(); } - - // this is redundant, since an LLRootHandle *is* an LLHandle - //LLHandle getHandle() { return LLHandle(*this); } - - void bind(T* object) - { - // unbind existing tombstone - if (LLHandle::mTombStone.notNull()) - { - if (LLHandle::mTombStone->getTarget() == (void*)object) return; - LLHandle::mTombStone->setTarget(NULL); - } - // tombstone reference counted, so no paired delete - LLHandle::mTombStone = new LLTombStone((void*)object); - } - - void unbind() - { - LLHandle::mTombStone->setTarget(NULL); - } - - //don't allow copying of root handles, since there should only be one -private: - LLRootHandle(const LLRootHandle& other) {}; -}; - -// Use this as a mixin for simple classes that need handles and when you don't -// want handles at multiple points of the inheritance hierarchy -template -class LLHandleProvider -{ -public: - LLHandle getHandle() const - { - // perform lazy binding to avoid small tombstone allocations for handle - // providers whose handles are never referenced - mHandle.bind(static_cast(const_cast* >(this))); - return mHandle; - } - -protected: - typedef LLHandle handle_type_t; - LLHandleProvider() - { - // provided here to enforce T deriving from LLHandleProvider - } - - template - LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const - { - LLHandle downcast_handle; - downcast_handle.mTombStone = getHandle().mTombStone; - return downcast_handle; - } - - -private: - mutable LLRootHandle mHandle; -}; - -#endif -- cgit v1.3