diff options
Diffstat (limited to 'src/BlockTypeRegistry.cpp')
-rw-r--r-- | src/BlockTypeRegistry.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/BlockTypeRegistry.cpp b/src/BlockTypeRegistry.cpp new file mode 100644 index 000000000..45ad20082 --- /dev/null +++ b/src/BlockTypeRegistry.cpp @@ -0,0 +1,153 @@ + +#include "Globals.h" +#include "BlockTypeRegistry.h" + + + + +//////////////////////////////////////////////////////////////////////////////// +// BlockInfo: + +BlockInfo::BlockInfo( + const AString & aPluginName, + const AString & aBlockTypeName, + std::shared_ptr<cBlockHandler> aHandler, + const std::map<AString, AString> & aHints, + const std::map<AString, BlockInfo::HintCallback> & aHintCallbacks +): + mPluginName(aPluginName), + mBlockTypeName(aBlockTypeName), + mHandler(aHandler), + mHints(aHints), + mHintCallbacks(aHintCallbacks) +{ +} + + + + + +AString BlockInfo::hintValue( + const AString & aHintName, + const BlockState & aBlockState +) +{ + // Search the hint callbacks first: + auto itrC = mHintCallbacks.find(aHintName); + if (itrC != mHintCallbacks.end()) + { + // Hint callback found, use it: + return itrC->second(mBlockTypeName, aBlockState); + } + + // Search the static hints: + auto itr = mHints.find(aHintName); + if (itr != mHints.end()) + { + // Hint found, use it: + return itr->second; + } + + // Nothing found, return empty string: + return AString(); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BlockTypeRegistry: + +void BlockTypeRegistry::registerBlockType( + const AString & aPluginName, + const AString & aBlockTypeName, + std::shared_ptr<cBlockHandler> aHandler, + const std::map<AString, AString> & aHints, + const std::map<AString, BlockInfo::HintCallback> & aHintCallbacks +) +{ + auto blockInfo = std::make_shared<BlockInfo>(aPluginName, aBlockTypeName, aHandler, aHints, aHintCallbacks); + + // Check previous registrations: + cCSLock lock(mCSRegistry); + auto itr = mRegistry.find(aBlockTypeName); + if (itr != mRegistry.end()) + { + if (itr->second->pluginName() != aPluginName) + { + throw AlreadyRegisteredException(itr->second, blockInfo); + } + } + + // Store the registration: + mRegistry[aBlockTypeName] = blockInfo; +} + + + + + +std::shared_ptr<BlockInfo> BlockTypeRegistry::blockInfo(const AString & aBlockTypeName) +{ + cCSLock lock(mCSRegistry); + auto itr = mRegistry.find(aBlockTypeName); + if (itr == mRegistry.end()) + { + return nullptr; + } + return itr->second; +} + + + + + +void BlockTypeRegistry::removeAllByPlugin(const AString & aPluginName) +{ + cCSLock lock(mCSRegistry); + for (auto itr = mRegistry.begin(); itr != mRegistry.end();) + { + if (itr->second->pluginName() == aPluginName) + { + itr = mRegistry.erase(itr); + } + else + { + ++itr; + } + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BlockTypeRegistry::AlreadyRegisteredException: + +BlockTypeRegistry::AlreadyRegisteredException::AlreadyRegisteredException( + std::shared_ptr<BlockInfo> aPreviousRegistration, + std::shared_ptr<BlockInfo> aNewRegistration +) : + Super(message(aPreviousRegistration, aNewRegistration)), + mPreviousRegistration(aPreviousRegistration), + mNewRegistration(aNewRegistration) +{ +} + + + + + +AString BlockTypeRegistry::AlreadyRegisteredException::message( + std::shared_ptr<BlockInfo> aPreviousRegistration, + std::shared_ptr<BlockInfo> aNewRegistration +) +{ + return Printf("Attempting to register BlockTypeName %s from plugin %s, while it is already registered in plugin %s", + aNewRegistration->blockTypeName().c_str(), + aNewRegistration->pluginName().c_str(), + aPreviousRegistration->pluginName().c_str() + ); +} |