// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include #include namespace zen { static std::atomic CustomTagCounter = 257; // NOTE: hard-coded TRACE_TAG = 257 static const int32_t TagNamesBaseIndex = 256; static const int32_t TrackedTagNameCount = 256; static const char* TagNames[TrackedTagNameCount]; static uint32_t TagNameHashes[TrackedTagNameCount]; static int32_t ParentTags[TrackedTagNameCount]; static RwLock TableLock; FLLMTag::FLLMTag(const char* TagName) { // NOTE: should add verification to prevent multiple definitions of same name? AssignAndAnnounceNewTag(TagName); } FLLMTag::FLLMTag(const char* TagName, const FLLMTag& ParentTag) { // NOTE: should add verification to prevent multiple definitions of same name? m_ParentTag = ParentTag.GetTag(); AssignAndAnnounceNewTag(TagName); } void FLLMTag::AssignAndAnnounceNewTag(const char* TagName) { const uint32_t TagNameHash = HashStringDjb2(TagName); { RwLock::ExclusiveLockScope _(TableLock); const int32_t CurrentMaxTagIndex = CustomTagCounter - TagNamesBaseIndex; for (int TagIndex = 0; TagIndex <= CurrentMaxTagIndex; ++TagIndex) { if (TagNameHashes[TagIndex] == TagNameHash && ParentTags[TagIndex] == m_ParentTag) { m_Tag = TagIndex + TagNamesBaseIndex; // could verify the string matches here to catch hash collisions // return early, no need to announce the tag as it is already known return; } } m_Tag = ++CustomTagCounter; const int TagIndex = m_Tag - TagNamesBaseIndex; if (TagIndex < TrackedTagNameCount) { TagNameHashes[TagIndex] = TagNameHash; TagNames[TagIndex] = TagName; ParentTags[TagIndex] = m_ParentTag; } else { // should really let user know there's an overflow } } MemoryTrace_AnnounceCustomTag(m_Tag, m_ParentTag, TagName); } } // namespace zen