Cuberite
A lightweight, fast and extensible game server for Minecraft
BlockTypeRegistry.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h"
3 #include "BlockTypeRegistry.h"
4 
5 
6 
7 
9 // BlockInfo:
10 
12  const AString & aPluginName,
13  const AString & aBlockTypeName,
14  std::shared_ptr<cBlockHandler> aHandler,
15  const std::map<AString, AString> & aHints,
16  const std::map<AString, BlockInfo::HintCallback> & aHintCallbacks
17 ):
18  mPluginName(aPluginName),
19  mBlockTypeName(aBlockTypeName),
20  mHandler(aHandler),
21  mHints(aHints),
22  mHintCallbacks(aHintCallbacks)
23 {
24 }
25 
26 
27 
28 
29 
31  const AString & aHintName,
32  const BlockState & aBlockState
33 )
34 {
35  // Search the hint callbacks first:
36  auto itrC = mHintCallbacks.find(aHintName);
37  if (itrC != mHintCallbacks.end())
38  {
39  // Hint callback found, use it:
40  return itrC->second(mBlockTypeName, aBlockState);
41  }
42 
43  // Search the static hints:
44  auto itr = mHints.find(aHintName);
45  if (itr != mHints.end())
46  {
47  // Hint found, use it:
48  return itr->second;
49  }
50 
51  // Nothing found, return empty string:
52  return AString();
53 }
54 
55 
56 
57 
58 
59 void BlockInfo::setHint(const AString & aHintKey, const AString & aHintValue)
60 {
61  mHints[aHintKey] = aHintValue;
62 
63  // Warn if the hint is already provided by a callback (aHintValue will be ignored when evaluating the hint):
64  auto itrC = mHintCallbacks.find(aHintKey);
65  if (itrC != mHintCallbacks.end())
66  {
67  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.",
68  aHintKey.c_str(), mBlockTypeName.c_str()
69  );
70  }
71 }
72 
73 
74 
75 
76 
77 void BlockInfo::removeHint(const AString & aHintKey)
78 {
79  mHints.erase(aHintKey);
80 }
81 
82 
83 
84 
85 
87 // BlockTypeRegistry:
88 
90  const AString & aPluginName,
91  const AString & aBlockTypeName,
92  std::shared_ptr<cBlockHandler> aHandler,
93  const std::map<AString, AString> & aHints,
94  const std::map<AString, BlockInfo::HintCallback> & aHintCallbacks
95 )
96 {
97  auto blockInfo = std::make_shared<BlockInfo>(aPluginName, aBlockTypeName, aHandler, aHints, aHintCallbacks);
98 
99  // Check previous registrations:
100  cCSLock lock(mCSRegistry);
101  auto itr = mRegistry.find(aBlockTypeName);
102  if (itr != mRegistry.end())
103  {
104  if (itr->second->pluginName() != aPluginName)
105  {
106  throw AlreadyRegisteredException(itr->second, blockInfo);
107  }
108  }
109 
110  // Store the registration:
111  mRegistry[aBlockTypeName] = blockInfo;
112 }
113 
114 
115 
116 
117 
118 std::shared_ptr<BlockInfo> BlockTypeRegistry::blockInfo(const AString & aBlockTypeName)
119 {
120  cCSLock lock(mCSRegistry);
121  auto itr = mRegistry.find(aBlockTypeName);
122  if (itr == mRegistry.end())
123  {
124  return nullptr;
125  }
126  return itr->second;
127 }
128 
129 
130 
131 
132 
134 {
135  cCSLock lock(mCSRegistry);
136  for (auto itr = mRegistry.begin(); itr != mRegistry.end();)
137  {
138  if (itr->second->pluginName() == aPluginName)
139  {
140  itr = mRegistry.erase(itr);
141  }
142  else
143  {
144  ++itr;
145  }
146  }
147 }
148 
149 
150 
151 
152 
154  const AString & aBlockTypeName,
155  const AString & aHintKey,
156  const AString & aHintValue
157 )
158 {
159  cCSLock lock(mCSRegistry);
160  auto blockInfo = mRegistry.find(aBlockTypeName);
161  if (blockInfo == mRegistry.end())
162  {
163  throw NotRegisteredException(aBlockTypeName, aHintKey, aHintValue);
164  }
165  blockInfo->second->setHint(aHintKey, aHintValue);
166 }
167 
168 
169 
170 
171 
173  const AString & aBlockTypeName,
174  const AString & aHintKey
175 )
176 {
177  cCSLock lock(mCSRegistry);
178  auto blockInfo = mRegistry.find(aBlockTypeName);
179  if (blockInfo == mRegistry.end())
180  {
181  return;
182  }
183  blockInfo->second->removeHint(aHintKey);
184 }
185 
186 
187 
188 
189 
191 // BlockTypeRegistry::AlreadyRegisteredException:
192 
194  std::shared_ptr<BlockInfo> aPreviousRegistration,
195  std::shared_ptr<BlockInfo> aNewRegistration
196 ) :
197  Super(message(aPreviousRegistration, aNewRegistration)),
198  mPreviousRegistration(aPreviousRegistration),
199  mNewRegistration(aNewRegistration)
200 {
201 }
202 
203 
204 
205 
206 
208  std::shared_ptr<BlockInfo> aPreviousRegistration,
209  std::shared_ptr<BlockInfo> aNewRegistration
210 )
211 {
212  return Printf("Attempting to register BlockTypeName %s from plugin %s, while it is already registered in plugin %s",
213  aNewRegistration->blockTypeName().c_str(),
214  aNewRegistration->pluginName().c_str(),
215  aPreviousRegistration->pluginName().c_str()
216  );
217 }
218 
219 
220 
221 
222 
224 // BlockTypeRegistry::NotRegisteredException:
225 
227  const AString & aBlockTypeName,
228  const AString & aHintKey,
229  const AString & aHintValue
230 ):
231  Super(Printf(
232  "Attempting to set a hint of nonexistent BlockTypeName.\n\tBlockTypeName = %s\n\tHintKey = %s\n\tHintValue = %s",
233  aBlockTypeName.c_str(),
234  aHintKey.c_str(),
235  aHintValue.c_str()
236  ))
237 {
238 }
The exception thrown from BlockTypeRegistry::setBlockTypeHint() if the block type has not been regist...
void removeBlockTypeHint(const AString &aBlockTypeName, const AString &aHintKey)
Removes a previously registered single Hint value for a BlockType.
AlreadyRegisteredException(std::shared_ptr< BlockInfo > aPreviousRegistration, std::shared_ptr< BlockInfo > aNewRegistration)
Creates a new instance of the exception that provides info on both the original registration and the ...
void setHint(const AString &aHintKey, const AString &aHintValue)
Sets (creates or updates) a static hint.
NotRegisteredException(const AString &aBlockTypeName, const AString &aHintKey, const AString &aHintValue)
Creates a new instance of the exception that provides info on both the original registration and the ...
std::shared_ptr< BlockInfo > blockInfo(const AString &aBlockTypeName)
Returns the registration information for the specified BlockTypeName.
BlockInfo(const AString &aPluginName, const AString &aBlockTypeName, std::shared_ptr< cBlockHandler > aHandler, const std::map< AString, AString > &aHints=std::map< AString, AString >(), const std::map< AString, HintCallback > &aHintCallbacks=std::map< AString, HintCallback >())
Creates a new instance with the specified BlockTypeName and handler / hints / callbacks.
std::map< AString, AString > mHints
Optional static hints for any subsystem to use, such as "IsSnowable" -> "1".
static AString message(std::shared_ptr< BlockInfo > aPreviousRegistration, std::shared_ptr< BlockInfo > aNewRegistration)
Returns the general exception message formatted by the two registrations.
AString hintValue(const AString &aHintName, const BlockState &aBlockState)
Retrieves the value associated with the specified hint for this specific BlockTypeName and BlockState...
void removeHint(const AString &aHintKey)
Removes a hint.
void LOGINFO(const char *a_Format, fmt::ArgList a_ArgList)
Definition: Logger.cpp:165
AString & Printf(AString &str, const char *format, fmt::ArgList args)
Output the formatted text into the string.
Definition: StringUtils.cpp:55
void removeAllByPlugin(const AString &aPluginName)
Removes all registrations done by the specified plugin.
std::string AString
Definition: StringUtils.h:13
AString mBlockTypeName
The name of the block type, such as "minecraft:redstone_lamp".
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
void registerBlockType(const AString &aPluginName, const AString &aBlockTypeName, std::shared_ptr< cBlockHandler > aHandler, const std::map< AString, AString > &aHints=std::map< AString, AString >(), const std::map< AString, BlockInfo::HintCallback > &aHintCallbacks=std::map< AString, BlockInfo::HintCallback >())
Registers the specified block type.
The exception thrown from BlockTypeRegistry::registerBlockType() if the same block type is being regi...
void setBlockTypeHint(const AString &aBlockTypeName, const AString &aHintKey, const AString &aHintValue)
Sets (adds or overwrites) a single Hint value for a BlockType.
std::map< AString, HintCallback > mHintCallbacks
The callbacks for dynamic evaluation of hints, such as "LightValue" -> function(BlockTypeName, BlockState).
Represents the state of a single block (previously known as "block meta").
Definition: BlockState.h:19