diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-09-08 10:46:16 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-12-21 01:11:34 +0100 |
commit | 742e27ad2f037205285e475be487ec9ed874ca91 (patch) | |
tree | 3218d3c2791e823c88a294ba7fdb10035c8fbb9b /src/Bindings/BlockTypeRegistry.cpp | |
parent | Enable LOS checks for Hostile Mobs. (diff) | |
download | cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.gz cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.bz2 cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.lz cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.xz cuberite-742e27ad2f037205285e475be487ec9ed874ca91.tar.zst cuberite-742e27ad2f037205285e475be487ec9ed874ca91.zip |
Diffstat (limited to 'src/Bindings/BlockTypeRegistry.cpp')
-rw-r--r-- | src/Bindings/BlockTypeRegistry.cpp | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/Bindings/BlockTypeRegistry.cpp b/src/Bindings/BlockTypeRegistry.cpp new file mode 100644 index 000000000..491e03593 --- /dev/null +++ b/src/Bindings/BlockTypeRegistry.cpp @@ -0,0 +1,240 @@ + +#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 +): + m_PluginName(aPluginName), + m_BlockTypeName(aBlockTypeName), + m_Handler(std::move(aHandler)), + m_Hints(aHints), + m_HintCallbacks(aHintCallbacks) +{ +} + + + + + +AString BlockInfo::hintValue( + const AString & aHintName, + const BlockState & aBlockState +) +{ + // Search the hint callbacks first: + auto itrC = m_HintCallbacks.find(aHintName); + if (itrC != m_HintCallbacks.end()) + { + // Hint callback found, use it: + return itrC->second(m_BlockTypeName, aBlockState); + } + + // Search the static hints: + auto itr = m_Hints.find(aHintName); + if (itr != m_Hints.end()) + { + // Hint found, use it: + return itr->second; + } + + // Nothing found, return empty string: + return AString(); +} + + + + + +void BlockInfo::setHint(const AString & aHintKey, const AString & aHintValue) +{ + m_Hints[aHintKey] = aHintValue; + + // Warn if the hint is already provided by a callback (aHintValue will be ignored when evaluating the hint): + auto itrC = m_HintCallbacks.find(aHintKey); + if (itrC != m_HintCallbacks.end()) + { + LOGINFO("Setting a static hint %s for block type %s, but there's already a callback for that hint. The static hint will be ignored.", + aHintKey.c_str(), m_BlockTypeName.c_str() + ); + } +} + + + + + +void BlockInfo::removeHint(const AString & aHintKey) +{ + m_Hints.erase(aHintKey); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// 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, std::move(aHandler), aHints, aHintCallbacks + ); + + // Check previous registrations: + cCSLock lock(m_CSRegistry); + auto itr = m_Registry.find(aBlockTypeName); + if (itr != m_Registry.end()) + { + if (itr->second->pluginName() != aPluginName) + { + throw AlreadyRegisteredException(itr->second, blockInfo); + } + } + + // Store the registration: + m_Registry[aBlockTypeName] = blockInfo; +} + + + + + +std::shared_ptr<BlockInfo> BlockTypeRegistry::blockInfo(const AString & aBlockTypeName) +{ + cCSLock lock(m_CSRegistry); + auto itr = m_Registry.find(aBlockTypeName); + if (itr == m_Registry.end()) + { + return nullptr; + } + return itr->second; +} + + + + + +void BlockTypeRegistry::removeAllByPlugin(const AString & aPluginName) +{ + cCSLock lock(m_CSRegistry); + for (auto itr = m_Registry.begin(); itr != m_Registry.end();) + { + if (itr->second->pluginName() == aPluginName) + { + itr = m_Registry.erase(itr); + } + else + { + ++itr; + } + } +} + + + + + +void BlockTypeRegistry::setBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey, + const AString & aHintValue +) +{ + cCSLock lock(m_CSRegistry); + auto blockInfo = m_Registry.find(aBlockTypeName); + if (blockInfo == m_Registry.end()) + { + throw NotRegisteredException(aBlockTypeName, aHintKey, aHintValue); + } + blockInfo->second->setHint(aHintKey, aHintValue); +} + + + + + +void BlockTypeRegistry::removeBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey +) +{ + cCSLock lock(m_CSRegistry); + auto blockInfo = m_Registry.find(aBlockTypeName); + if (blockInfo == m_Registry.end()) + { + return; + } + blockInfo->second->removeHint(aHintKey); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BlockTypeRegistry::AlreadyRegisteredException: + +BlockTypeRegistry::AlreadyRegisteredException::AlreadyRegisteredException( + const std::shared_ptr<BlockInfo> & aPreviousRegistration, + const std::shared_ptr<BlockInfo> & aNewRegistration +) : + Super(message(aPreviousRegistration, aNewRegistration)), + m_PreviousRegistration(aPreviousRegistration), + m_NewRegistration(aNewRegistration) +{ +} + + + + + +AString BlockTypeRegistry::AlreadyRegisteredException::message( + const std::shared_ptr<BlockInfo> & aPreviousRegistration, + const 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() + ); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BlockTypeRegistry::NotRegisteredException: + +BlockTypeRegistry::NotRegisteredException::NotRegisteredException( + const AString & aBlockTypeName, + const AString & aHintKey, + const AString & aHintValue +): + Super(Printf( + "Attempting to set a hint of nonexistent BlockTypeName.\n\tBlockTypeName = %s\n\tHintKey = %s\n\tHintValue = %s", + aBlockTypeName.c_str(), + aHintKey.c_str(), + aHintValue.c_str() + )) +{ +} |