123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "EditorDefs.h"
- #include "Plugin.h"
- #include <QMessageBox>
- CClassFactory* CClassFactory::s_pInstance = nullptr;
- CAutoRegisterClassHelper* CAutoRegisterClassHelper::s_pFirst = nullptr;
- CAutoRegisterClassHelper* CAutoRegisterClassHelper::s_pLast = nullptr;
- CClassFactory::CClassFactory()
- {
- m_classes.reserve(100);
- RegisterAutoTypes();
- }
- CClassFactory::~CClassFactory()
- {
- for (int i = 0; i < m_classes.size(); i++)
- {
- m_classes[i]->Release();
- }
- }
- void CClassFactory::RegisterAutoTypes()
- {
- CAutoRegisterClassHelper* pClass = CAutoRegisterClassHelper::s_pFirst;
- while (pClass)
- {
- RegisterClass(pClass->m_pClassDesc);
- pClass = pClass->m_pNext;
- }
- }
- CClassFactory* CClassFactory::Instance()
- {
- if (!s_pInstance)
- {
- s_pInstance = new CClassFactory;
- }
- return s_pInstance;
- }
- void CClassFactory::RegisterClass(IClassDesc* pClassDesc)
- {
- assert(pClassDesc);
- auto findByGuid = m_guidToClass.find(pClassDesc->ClassID());
- if (findByGuid != m_guidToClass.end())
- {
- // you may not re-use UUIDs!
- // this can happen when someone makes a new plugin or downloads one
- // where the author copied and pasted code. This can also happen if two DLLs exist which are actually the same plugin
- // either way, give info if you can:
- char errorMessageBuffer[512] = { 0 };
- AZ::Uuid newUUID(pClassDesc->ClassID());
- char existingUUIDString[64] = { 0 };
- newUUID.ToString(existingUUIDString, 64, true, true);
- sprintf_s(errorMessageBuffer, 512,
- "Error registering class '%s' - UUID of that class already exists (%s), and belongs to class named '%s.'\n"
- "You may not have duplicate class identifiers.\n"
- "Check for duplicate plugins or copy and pasted code for plugins that duplicates UUIDs returned.",
- pClassDesc->ClassName().toUtf8().data(),
- existingUUIDString,
- findByGuid->second->ClassName().toUtf8().data());
- QMessageBox::critical(nullptr,"Invalid class registration - Duplicate UUID",QString::fromLatin1(errorMessageBuffer));
- return;
- }
- auto findByName = m_nameToClass.find(pClassDesc->ClassName());
- if (findByName != m_nameToClass.end())
- {
- // you may not re-use names, either!
- char errorMessageBuffer[512] = { 0 };
- AZ::Uuid newUUID(pClassDesc->ClassID());
- char newUUIDString[64] = { 0 };
- newUUID.ToString(newUUIDString, 64, true, true);
- AZ::Uuid existingUUID(findByName->second->ClassID());
- char existingUUIDString[64] = { 0 };
- existingUUID.ToString(existingUUIDString, 64, true, true);
- sprintf_s(errorMessageBuffer, 512,
- "Error registering class '%s' - that name is already taken by a different class.\n"
- "New class's UUID is %s\n"
- "Existing class's UUID is %s\n"
- "You may not have duplicate class names.\n"
- "Check for duplicate plugins or copy and pasted code for plugins.",
- pClassDesc->ClassName().toUtf8().constData(),
- newUUIDString,
- existingUUIDString);
- QMessageBox::critical(nullptr, "Invalid class registration - Duplicate Class Name", QString::fromLatin1(errorMessageBuffer));
- return;
- }
- #if defined(DEBUG_CLASS_NAME_REGISTRATION)
- m_debugClassNames.push_back(pClassDesc->ClassName());
- #endif // DEBUG_CLASS_NAME_REGISTRATION
- m_classes.push_back(pClassDesc);
- m_guidToClass[pClassDesc->ClassID()] = pClassDesc;
- m_nameToClass[pClassDesc->ClassName()] = pClassDesc;
- }
- IClassDesc* CClassFactory::FindClass(const char* pClassName) const
- {
- IClassDesc* pClassDesc = stl::find_in_map(m_nameToClass, pClassName, (IClassDesc*)nullptr);
- if (pClassDesc)
- {
- return pClassDesc;
- }
- const char* pSubClassName = strstr(pClassName, "::");
- if (!pSubClassName)
- {
- return nullptr;
- }
- QString name = QString(pClassName).left(static_cast<int>(pSubClassName - pClassName));
- return stl::find_in_map(m_nameToClass, name, (IClassDesc*)nullptr);
- }
- IClassDesc* CClassFactory::FindClass(const GUID& rClassID) const
- {
- IClassDesc* pClassDesc = stl::find_in_map(m_guidToClass, rClassID, (IClassDesc*)nullptr);
- return pClassDesc;
- }
- void CClassFactory::UnregisterClass(const char* pClassName)
- {
- IClassDesc* pClassDesc = FindClass(pClassName);
- if (pClassDesc == nullptr)
- {
- return;
- }
- #if defined(DEBUG_CLASS_NAME_REGISTRATION)
- stl::find_and_erase(m_debugClassNames, pClassDesc->ClassName());
- #endif // DEBUG_CLASS_NAME_REGISTRATION
- stl::find_and_erase(m_classes, pClassDesc);
- stl::member_find_and_erase(m_guidToClass, pClassDesc->ClassID());
- stl::member_find_and_erase(m_nameToClass, pClassDesc->ClassName());
- }
- void CClassFactory::UnregisterClass(const GUID& rClassID)
- {
- IClassDesc* pClassDesc = FindClass(rClassID);
- if (!pClassDesc)
- {
- return;
- }
- #if defined(DEBUG_CLASS_NAME_REGISTRATION)
- stl::find_and_erase(m_debugClassNames, pClassDesc->ClassName());
- #endif // DEBUG_CLASS_NAME_REGISTRATION
- stl::find_and_erase(m_classes, pClassDesc);
- stl::member_find_and_erase(m_guidToClass, pClassDesc->ClassID());
- stl::member_find_and_erase(m_nameToClass, pClassDesc->ClassName());
- }
- bool ClassDescNameCompare(IClassDesc* pArg1, IClassDesc* pArg2)
- {
- return (QString::compare(pArg1->ClassName(), pArg2->ClassName(), Qt::CaseInsensitive) < 0);
- }
- void CClassFactory::GetClassesBySystemID(ESystemClassID aSystemClassID, std::vector<IClassDesc*>& rOutClasses)
- {
- rOutClasses.clear();
- for (size_t i = 0; i < m_classes.size(); ++i)
- {
- if (m_classes[i]->SystemClassID() == aSystemClassID)
- {
- rOutClasses.push_back(m_classes[i]);
- }
- }
- std::sort(rOutClasses.begin(), rOutClasses.end(), ClassDescNameCompare);
- }
- void CClassFactory::GetClassesByCategory(const char* pCategory, std::vector<IClassDesc*>& rOutClasses)
- {
- rOutClasses.clear();
- for (size_t i = 0; i < m_classes.size(); ++i)
- {
- if (!QString::compare(pCategory, m_classes[i]->Category(), Qt::CaseInsensitive))
- {
- rOutClasses.push_back(m_classes[i]);
- }
- }
- std::sort(rOutClasses.begin(), rOutClasses.end(), ClassDescNameCompare);
- }
|