diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/BlockTypeRegistry.cpp | 85 | ||||
-rw-r--r-- | src/BlockTypeRegistry.h | 62 |
2 files changed, 144 insertions, 3 deletions
diff --git a/src/BlockTypeRegistry.cpp b/src/BlockTypeRegistry.cpp index 45ad20082..cc6945e27 100644 --- a/src/BlockTypeRegistry.cpp +++ b/src/BlockTypeRegistry.cpp @@ -56,6 +56,33 @@ AString BlockInfo::hintValue( +void BlockInfo::setHint(const AString & aHintKey, const AString & aHintValue) +{ + mHints[aHintKey] = aHintValue; + + // Warn if the hint is already provided by a callback (aHintValue will be ignored when evaluating the hint): + auto itrC = mHintCallbacks.find(aHintKey); + if (itrC != mHintCallbacks.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(), mBlockTypeName.c_str() + ); + } +} + + + + + +void BlockInfo::removeHint(const AString & aHintKey) +{ + mHints.erase(aHintKey); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // BlockTypeRegistry: @@ -123,6 +150,43 @@ void BlockTypeRegistry::removeAllByPlugin(const AString & aPluginName) +void BlockTypeRegistry::setBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey, + const AString & aHintValue +) +{ + cCSLock lock(mCSRegistry); + auto blockInfo = mRegistry.find(aBlockTypeName); + if (blockInfo == mRegistry.end()) + { + throw NotRegisteredException(aBlockTypeName, aHintKey, aHintValue); + } + blockInfo->second->setHint(aHintKey, aHintValue); +} + + + + + +void BlockTypeRegistry::removeBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey +) +{ + cCSLock lock(mCSRegistry); + auto blockInfo = mRegistry.find(aBlockTypeName); + if (blockInfo == mRegistry.end()) + { + return; + } + blockInfo->second->removeHint(aHintKey); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // BlockTypeRegistry::AlreadyRegisteredException: @@ -151,3 +215,24 @@ AString BlockTypeRegistry::AlreadyRegisteredException::message( 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() + )) +{ +} diff --git a/src/BlockTypeRegistry.h b/src/BlockTypeRegistry.h index 6a24445c5..3fbcc44c2 100644 --- a/src/BlockTypeRegistry.h +++ b/src/BlockTypeRegistry.h @@ -40,7 +40,7 @@ public: /** Retrieves the value associated with the specified hint for this specific BlockTypeName and BlockState. - Queries callbacks first, then hints if a callback doesn't exist. + Queries hint callbacks first, then static hints if a callback doesn't exist. Returns an empty string if hint not found at all. */ AString hintValue( const AString & aHintName, @@ -52,6 +52,15 @@ public: const AString & blockTypeName() const { return mBlockTypeName; } std::shared_ptr<cBlockHandler> handler() const { return mHandler; } + /** Sets (creates or updates) a static hint. + Hints provided by callbacks are unaffected by this - callbacks are "higher priority", they overwrite anything set here. + Logs an info message if the hint is already provided by a hint callback. */ + void setHint(const AString & aHintKey, const AString & aHintValue); + + /** Removes a hint. + Silently ignored if the hint hasn't been previously set. */ + void removeHint(const AString & aHintKey); + private: @@ -64,10 +73,12 @@ private: /** The callbacks to call for various interaction. */ std::shared_ptr<cBlockHandler> mHandler; - /** Optional hints for any subsystem to use, such as "IsSnowable" -> "1". */ + /** Optional static hints for any subsystem to use, such as "IsSnowable" -> "1". + Hint callbacks are of higher priority than mHints - if a hint is provided by a mHintCallback, its value in mHints is ignored. */ std::map<AString, AString> mHints; - /** The callbacks for dynamic evaluation of hints, such as "LightValue" -> function(BlockTypeName, BlockState). */ + /** The callbacks for dynamic evaluation of hints, such as "LightValue" -> function(BlockTypeName, BlockState). + Hint callbacks are of higher priority than mHints - if a hint is provided by a mHintCallback, its value in mHints is ignored. */ std::map<AString, HintCallback> mHintCallbacks; }; @@ -86,6 +97,7 @@ class BlockTypeRegistry public: // fwd: class AlreadyRegisteredException; + class NotRegisteredException; /** Creates an empty new instance of the block type registry */ @@ -109,6 +121,22 @@ public: /** Removes all registrations done by the specified plugin. */ void removeAllByPlugin(const AString & aPluginName); + /** Sets (adds or overwrites) a single Hint value for a BlockType. + Throws NotRegisteredException if the BlockTypeName is not registered. */ + void setBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey, + const AString & aHintValue + ); + + /** Removes a previously registered single Hint value for a BlockType. + Throws NotRegisteredException if the BlockTypeName is not registered. + Silently ignored if the Hint hasn't been previously set. */ + void removeBlockTypeHint( + const AString & aBlockTypeName, + const AString & aHintKey + ); + private: @@ -156,3 +184,31 @@ private: std::shared_ptr<BlockInfo> aNewRegistration ); }; + + + + + +/** The exception thrown from BlockTypeRegistry::setBlockTypeHint() if the block type has not been registered before. */ +class BlockTypeRegistry::NotRegisteredException: public std::runtime_error +{ + using Super = std::runtime_error; + +public: + + /** Creates a new instance of the exception that provides info on both the original registration and the newly attempted + registration that caused the failure. */ + NotRegisteredException( + const AString & aBlockTypeName, + const AString & aHintKey, + const AString & aHintValue + ); + + // Simple getters: + const AString & blockTypeName() const { return mBlockTypeName; } + + +private: + + const AString mBlockTypeName; +}; |