diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index f9c73a20a..13c8f649d 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -33,207 +33,115 @@ #include "linden_common.h" #include "llassettype.h" +#include "lldictionary.h" +#include "llmemory.h" -#include "llstring.h" -#include "lltimer.h" - -// I added lookups for exact text of asset type enums in addition to the ones below, so shoot me. -Steve - -struct asset_info_t +///---------------------------------------------------------------------------- +/// Class LLAssetType +///---------------------------------------------------------------------------- +struct AssetEntry : public LLDictionaryEntry { - LLAssetType::EType type; - const char* desc; + AssetEntry(const char *desc_name, + const char *type_name, // 8 character limit! + const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one + bool can_link, // can you create a link to this type? + bool can_fetch, // can you fetch this asset by ID? + bool can_know) // can you see this asset's ID? + : + LLDictionaryEntry(desc_name), + mTypeName(type_name), + mHumanName(human_name), + mCanLink(can_link), + mCanFetch(can_fetch), + mCanKnow(can_know) + { + llassert(strlen(mTypeName) <= 8); + } + + const char *mTypeName; + const char *mHumanName; + bool mCanLink; + bool mCanFetch; + bool mCanKnow; }; -asset_info_t asset_types[] = +class LLAssetDictionary : public LLSingleton, + public LLDictionary { - { LLAssetType::AT_TEXTURE, "TEXTURE" }, - { LLAssetType::AT_SOUND, "SOUND" }, - { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, - { LLAssetType::AT_LANDMARK, "LANDMARK" }, - { LLAssetType::AT_SCRIPT, "SCRIPT" }, - { LLAssetType::AT_CLOTHING, "CLOTHING" }, - { LLAssetType::AT_OBJECT, "OBJECT" }, - { LLAssetType::AT_NOTECARD, "NOTECARD" }, - { LLAssetType::AT_CATEGORY, "CATEGORY" }, - { LLAssetType::AT_ROOT_CATEGORY, "ROOT_CATEGORY" }, - { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, - { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, - { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, - { LLAssetType::AT_BODYPART, "BODYPART" }, - { LLAssetType::AT_TRASH, "TRASH" }, - { LLAssetType::AT_SNAPSHOT_CATEGORY, "SNAPSHOT_CATEGORY" }, - { LLAssetType::AT_LOST_AND_FOUND, "LOST_AND_FOUND" }, - { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, - { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, - { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, - { LLAssetType::AT_ANIMATION, "ANIMATION" }, - { LLAssetType::AT_GESTURE, "GESTURE" }, - { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, - { LLAssetType::AT_FAVORITE, "FAVORITE" }, - { LLAssetType::AT_LINK, "LINK" }, - { LLAssetType::AT_LINK_FOLDER, "CURRENT" }, - { LLAssetType::AT_CURRENT_OUTFIT, "FOLDER_LINK" }, - { LLAssetType::AT_OUTFIT, "OUTFIT" }, - { LLAssetType::AT_MY_OUTFITS, "MY_OUTFITS" }, - { LLAssetType::AT_NONE, "NONE" } +public: + LLAssetDictionary(); }; -LLAssetType::EType LLAssetType::getType(const std::string& sin) +LLAssetDictionary::LLAssetDictionary() { - std::string s = sin; + // DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW? + // |--------------------|-----------|-------------------|-----------|-----------|---------| + addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true)); + addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true)); + addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false)); + addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true)); + addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false)); + addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true)); + addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false)); + addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true)); + addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false)); + addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", false, false, false)); + addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false)); + addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false)); + addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false)); + addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true)); + addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", false, false, false)); + addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", false, false, false)); + addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", false, false, false)); + addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false)); + addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false)); + addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true)); + addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true)); + addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false)); + addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "", false, false, false)); + addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); + addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); + addEntry(LLAssetType::AT_CURRENT_OUTFIT, new AssetEntry("FOLDER_LINK", "current", "current outfit", false, false, false)); + addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", false, false, false)); + addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", false, false, false)); + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false)); +}; + +// static +LLAssetType::EType LLAssetType::getType(const std::string& desc_name) +{ + std::string s = desc_name; LLStringUtil::toUpper(s); - for (S32 idx = 0; ;idx++) - { - asset_info_t* info = asset_types + idx; - if (info->type == LLAssetType::AT_NONE) - break; - if (s == info->desc) - return info->type; - } - return LLAssetType::AT_NONE; + return LLAssetDictionary::getInstance()->lookup(s); } -std::string LLAssetType::getDesc(LLAssetType::EType type) -{ - for (S32 idx = 0; ;idx++) - { - asset_info_t* info = asset_types + idx; - if (type == info->type) - return info->desc; - if (info->type == LLAssetType::AT_NONE) - break; - } - return "BAD TYPE"; -} - -//============================================================================ - -// The asset type names are limited to 8 characters. // static -const char* LLAssetType::mAssetTypeNames[LLAssetType::AT_COUNT] = -{ - "texture", - "sound", - "callcard", - "landmark", - "script", - "clothing", - "object", - "notecard", - "category", - "root", - "lsltext", - "lslbyte", - "txtr_tga",// Intentionally spelled this way. Limited to eight characters. - "bodypart", - "trash", - "snapshot", - "lstndfnd", - "snd_wav", - "img_tga", - "jpeg", - "animatn", - "gesture", - "simstate", - "favorite", - "link", - "link_f", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "current", - "outfit", - "my_otfts" -}; - -// This table is meant for decoding to human readable form. Put any -// and as many printable characters you want in each one. -// See also llinventory.cpp INVENTORY_TYPE_HUMAN_NAMES -const char* LLAssetType::mAssetTypeHumanNames[LLAssetType::AT_COUNT] = -{ - "texture", - "sound", - "calling card", - "landmark", - "legacy script", - "clothing", - "object", - "note card", - "folder", - "root", - "lsl2 script", - "lsl bytecode", - "tga texture", - "body part", - "trash", - "snapshot", - "lost and found", - "sound", - "targa image", - "jpeg image", - "animation", - "gesture", - "simstate", - "", - "symbolic link", - "symbolic folder link" - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "current outfit", - "outfit", - "my outfits" -}; - -///---------------------------------------------------------------------------- -/// class LLAssetType -///---------------------------------------------------------------------------- - -// static -const char* LLAssetType::lookup( LLAssetType::EType type ) +const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type) { - if( (type >= 0) && (type < AT_COUNT )) + const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type); + if (entry) { - return mAssetTypeNames[ S32( type ) ]; + return entry->mName; } else { - return "-1"; + return badLookup(); + } +} + +// static +const char *LLAssetType::lookup(LLAssetType::EType asset_type) +{ + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mTypeName; + } + else + { + return badLookup().c_str(); } } @@ -243,29 +151,35 @@ LLAssetType::EType LLAssetType::lookup( const char* name ) return lookup(ll_safe_string(name)); } -LLAssetType::EType LLAssetType::lookup( const std::string& name ) +// static +LLAssetType::EType LLAssetType::lookup(const std::string& type_name) { - for( S32 i = 0; i < AT_COUNT; i++ ) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + for (LLAssetDictionary::const_iterator iter = dict->begin(); + iter != dict->end(); + iter++) { - if( name == mAssetTypeNames[i] ) + const AssetEntry *entry = iter->second; + if (type_name == entry->mTypeName) { - // match - return (EType)i; + return iter->first; } } return AT_NONE; } // static -const char* LLAssetType::lookupHumanReadable(LLAssetType::EType type) +const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type) { - if( (type >= 0) && (type < AT_COUNT )) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - return mAssetTypeHumanNames[S32(type)]; + return entry->mHumanName; } else { - return NULL; + return badLookup().c_str(); } } @@ -275,14 +189,18 @@ LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name ) return lookupHumanReadable(ll_safe_string(name)); } -LLAssetType::EType LLAssetType::lookupHumanReadable( const std::string& name ) +// static +LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_name) { - for( S32 i = 0; i < AT_COUNT; i++ ) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + for (LLAssetDictionary::const_iterator iter = dict->begin(); + iter != dict->end(); + iter++) { - if( name == mAssetTypeHumanNames[i] ) + const AssetEntry *entry = iter->second; + if (entry->mHumanName && (readable_name == entry->mHumanName)) { - // match - return (EType)i; + return iter->first; } } return AT_NONE; @@ -333,6 +251,16 @@ void LLAssetType::generateDescriptionFor(LLAssetType::EType type, // static bool LLAssetType::lookupCanLink(EType asset_type) { + //Check that enabling all these other types as linkable doesn't break things. + /*const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) + { + return entry->mCanLink; + } + return false; + */ + return (asset_type == AT_CLOTHING || asset_type == AT_OBJECT || asset_type == AT_CATEGORY || asset_type == AT_BODYPART || asset_type == AT_GESTURE); } @@ -341,45 +269,42 @@ bool LLAssetType::lookupCanLink(EType asset_type) // Not adding this to dictionary since we probably will only have these two types bool LLAssetType::lookupIsLinkType(EType asset_type) { - return (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER); + if (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER) + { + return true; + } + return false; +} + +// static +const std::string &LLAssetType::badLookup() +{ + static const std::string sBadLookup = "llassettype_bad_lookup"; + return sBadLookup; + } // static bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type) { - // *FIX: Make this list smaller. - switch(asset_type) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - return true; - default: - return false; + return entry->mCanFetch; } + return false; } // static bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type) { - switch(asset_type) + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + const AssetEntry *entry = dict->lookup(asset_type); + if (entry) { - case LLAssetType::AT_TEXTURE: - case LLAssetType::AT_SOUND: - case LLAssetType::AT_LANDMARK: - case LLAssetType::AT_CLOTHING: - case LLAssetType::AT_NOTECARD: - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_ANIMATION: - case LLAssetType::AT_GESTURE: - case LLAssetType::AT_LINK: - case LLAssetType::AT_LINK_FOLDER: - return true; - default: - return false; + return entry->mCanKnow; } + return false; } diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index a769e165c..b4f8ce4cf 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -160,39 +160,36 @@ public: }; // machine transation between type and strings - static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate - static EType lookup(const std::string& name); - static const char* lookup(EType type); + static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate + static EType lookup(const std::string& type_name); + static const char* lookup(EType asset_type); // translation from a type to a human readable form. - static EType lookupHumanReadable( const char* name ); // safe conversion to std::string, *TODO: deprecate - static EType lookupHumanReadable( const std::string& name ); - static const char* lookupHumanReadable(EType type); + static EType lookupHumanReadable(const char* desc_name); // safe conversion to std::string, *TODO: deprecate + static EType lookupHumanReadable(const std::string& readable_name); + static const char* lookupHumanReadable(EType asset_type); - static EDragAndDropType lookupDragAndDropType( EType ); + static EDragAndDropType lookupDragAndDropType( EType ); // Generate a good default description. You may want to add a verb // or agent name after this depending on your application. static void generateDescriptionFor(LLAssetType::EType type, std::string& desc); - static EType getType(const std::string& sin); - static std::string getDesc(EType type); - + static EType getType(const std::string& desc_name); + static const std::string& getDesc(EType asset_type); + static bool lookupCanLink(EType asset_type); static bool lookupIsLinkType(EType asset_type); static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer -private: - // don't instantiate or derive one of these objects - LLAssetType( void ) {} - ~LLAssetType( void ) {} + static const std::string& badLookup(); // error string when a lookup fails -private: - static const char* mAssetTypeNames[]; - static const char* mAssetTypeHumanNames[]; +protected: + LLAssetType() {} + ~LLAssetType() {} }; #endif // LL_LLASSETTYPE diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 910d94baf..009d7c5b0 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1972,6 +1972,23 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) //llinfos << "LLInventoryModel::addItem()" << llendl; if(item) { + // This can happen if assettype enums from llassettype.h ever change. + // For example, there is a known backwards compatibility issue in some viewer prototypes prior to when + // the AT_LINK enum changed from 23 to 24. + if ((item->getType() == LLAssetType::AT_NONE) + || LLAssetType::lookup(item->getType()) == LLAssetType::badLookup()) + { + llwarns << "Got bad asset type for item [ name: " << item->getName() << " type: " << item->getType() << " inv-type: " << item->getInventoryType() << " ], ignoring." << llendl; + return; + } + + // This condition means that we tried to add a link without the baseobj being in memory. + // The item will show up as a broken link. + if (item->getIsBrokenLink()) + { + llinfos << "Adding broken link [ name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << llendl; + } + mItemMap[item->getUUID()] = item; } }