Leviathan  0.8.0.0
Leviathan game engine
DataBlock.cpp
Go to the documentation of this file.
1 #include "Include.h"
2 // ------------------------------------ //
3 #include "../StringOperations.h"
4 #include "DataBlock.h"
6 #include <float.h>
7 
8 #ifdef LEVIATHAN_USING_ANGELSCRIPT
10 #endif // LEVIATHAN_USING_ANGELSCRIPT
11 using namespace Leviathan;
12 using namespace std;
13 // ------------------------------------ //
15  const std::string& valuetoparse, map<string, std::shared_ptr<VariableBlock>>* predefined)
16 {
17  // the text should have all preceding and trailing spaces removed //
18  if(valuetoparse.size() == 0) {
19  // can't be anything //
20 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
21  throw InvalidArgument("no data passed");
22 #else
23  return;
24 #endif
25  }
26  // try to figure out what type of block is required for this variable //
27 
28  // easy one first, quotes //
29  if(valuetoparse[0] == '"') {
30  // it's a string //
31 
32  // use iterator to get data inside quotes //
33  StringIterator itr(valuetoparse);
34 
35  auto tempdata = itr.GetStringInQuotes<std::string>(QUOTETYPE_DOUBLEQUOTES);
36 
37  // set data //
38  // WstringBlock takes the pointer as it's own here //
39  BlockData = new StringBlock(tempdata ? tempdata.release() : new std::string());
40 
41  return;
42  }
43 
44  // check does it contain non numeric characters //
45  if(!StringOperations::IsStringNumeric<std::string>(valuetoparse)) {
46 
47  // check does it match true/false //
48  bool possiblevalue = false;
49 
50  if(Convert::IsStringBool(valuetoparse, &possiblevalue)) {
51 
52  BlockData = new BoolBlock(possiblevalue);
53 
54  return;
55  }
56 
57  // check does some special value match it //
58  if(predefined != NULL) {
59  // check do them match //
60 
61  auto ivaliterator = predefined->find(valuetoparse);
62 
63  if(ivaliterator != predefined->end()) {
64  // found! //
65 
66  BlockData = ivaliterator->second->GetBlockConst()->AllocateNewFromThis();
67  return;
68  }
69  }
70 
71  // create a string from the whole thing //
72  BlockData = new StringBlock(valuetoparse);
73 
74  return;
75  }
76 
77  // Try to figure out what kind of a number it is //
78  size_t decimalspot = valuetoparse.find_first_of('.');
79  if(decimalspot != std::wstring::npos) {
80  // has decimal separator //
81 
82  // check does it need more decimal digits than a float has //
83 
84  if(valuetoparse.size() - 1 - decimalspot > FLT_DIG) {
85  // create a double //
86  BlockData = new DoubleBlock(Convert::StringTo<double>(valuetoparse));
87 
88  } else {
89 
90  // float should have space to hold all characters //
91  BlockData = new FloatBlock(Convert::StringTo<float>(valuetoparse));
92  }
93 
94  return;
95  }
96 
97  // Should be a plain old int //
98  BlockData = new IntBlock(Convert::StringTo<int>(valuetoparse));
99 }
100 
101 
102 // ------------------ ScriptSafeVariableBlock ------------------ //
103 #ifdef LEVIATHAN_USING_ANGELSCRIPT
105  VariableBlock* copyfrom, const std::string& name) :
106  NamedVariableBlock(copyfrom->GetBlock()->AllocateNewFromThis(), name)
107 {
108  // we need to copy all settings from the block //
109  switch(copyfrom->GetBlock()->Type) {
110  case DATABLOCK_TYPE_INT:
112  break;
115  break;
116  case DATABLOCK_TYPE_BOOL:
118  break;
119  case DATABLOCK_TYPE_WSTRING: {
120  // we'll use automatic conversion here //
121  unique_ptr<DataBlockAll> tmp(new StringBlock(ConvertAndReturnVariable<std::string>()));
122 
124  BlockData = tmp.release();
125 
127  break;
128  } break;
131  break;
132  case DATABLOCK_TYPE_CHAR:
134  break;
137  break;
138 
139  default:
140  throw InvalidArgument("cannot convert non-named, generic type block to script "
141  "safe block");
142  }
143 }
144 #endif // LEVIATHAN_USING_ANGELSCRIPT
145 // ------------------ Loading/saving from/to packets ------------------ //
146 #define DEFAULTTOANDFROMPACKETCONVERTFUNCTINS(BlockTypeName, VarTypeName, TmpTypeName) \
147  template<> \
148  DLLEXPORT void BlockTypeName::AddDataToPacket(sf::Packet& packet) \
149  { \
150  packet << *Value; \
151  } \
152  template<> \
153  DLLEXPORT BlockTypeName::DataBlock(sf::Packet& packet) \
154  { \
155  Type = DataBlockNameResolver<VarTypeName>::TVal; \
156  TmpTypeName tmpval; \
157  if(!(packet >> tmpval)) { \
158  throw InvalidArgument("invalid packet format"); \
159  } \
160  Value = new VarTypeName(tmpval); \
161  }
162 
163 
164 
165 // ------------------ Loading/saving from/to packets ------------------ //
166 #ifdef SFML_PACKETS
167 namespace Leviathan {
175 
176 
177 
178 // Fill in the gaps in the templates with these defaults //
179 template<class DBlockT>
181 {
182  // The default one cannot do anything, only the specialized functions can try to do
183  // something
184  throw Exception("this type doesn't support saving to a packet");
185 }
186 template<class DBlockT>
188 {
189  // The default one cannot do anything, only the specialized functions can try to do
190  // something
191  throw Exception("this type doesn't support loading from a packet");
192 }
193 
194 // ------------------ VariableBlock ------------------ //
195 DLLEXPORT void VariableBlock::AddDataToPacket(sf::Packet& packet) const
196 {
197  // Set the type //
198  if(BlockData != NULL) {
199  packet << BlockData->Type;
200  } else {
201  packet << 0;
202  return;
203  }
204 
205  // Set the data //
208  packet);
209  else if(BlockData->Type == DATABLOCK_TYPE_FLOAT)
211  ->AddDataToPacket(packet);
212  else if(BlockData->Type == DATABLOCK_TYPE_BOOL)
214  packet);
217  ->AddDataToPacket(packet);
220  ->AddDataToPacket(packet);
221  else if(BlockData->Type == DATABLOCK_TYPE_CHAR)
223  packet);
226  ->AddDataToPacket(packet);
227 
228  // type that shouldn't be used is used //
229  throw InvalidType("unallowed datatype in datablock for writing to packet");
230 }
231 
233 {
234 
235  // Get the type //
236  short type;
237  packet >> type;
238 
239  // Load the actual data based on the type //
240  switch(type) {
241  case 0: {
242  // No data //
243  BlockData = NULL;
244  return;
245  }
246  case DATABLOCK_TYPE_INT: {
247  BlockData = new IntBlock(packet);
248  return;
249  }
250  case DATABLOCK_TYPE_FLOAT: {
251  BlockData = new FloatBlock(packet);
252  return;
253  }
254  case DATABLOCK_TYPE_BOOL: {
255  BlockData = new BoolBlock(packet);
256  return;
257  }
258  case DATABLOCK_TYPE_WSTRING: {
259  BlockData = new WstringBlock(packet);
260  return;
261  }
262  case DATABLOCK_TYPE_STRING: {
263  BlockData = new StringBlock(packet);
264  return;
265  }
266  case DATABLOCK_TYPE_CHAR: {
267  BlockData = new CharBlock(packet);
268  return;
269  }
270  case DATABLOCK_TYPE_DOUBLE: {
271  BlockData = new DoubleBlock(packet);
272  return;
273  }
274  }
275 
276  // Invalid packet //
277  throw InvalidArgument("invalid packet format");
278 }
279 } // namespace Leviathan
280 #endif // SFML_PACKETS
281 
282 namespace Leviathan {
283 
284 DLLEXPORT std::ostream& operator<<(std::ostream& stream, const VariableBlock& value)
285 {
286 
287  if(!value.GetBlockConst()) {
288 
289  stream << "Empty Variable";
290  return stream;
291  }
292 
293  if(!value.IsConversionAllowedNonPtr<std::string>()) {
294 
295  stream << "No Text Presentation";
296  return stream;
297  }
298 
299  stream << value.operator std::string();
300  return stream;
301 }
302 
303 } // namespace Leviathan
DataBlock< float > FloatBlock
Definition: DataBlock.h:383
Non-template class for working with all types of DataBlocks.
Definition: DataBlock.h:425
static int Get(ScriptExecutor *resolver)
DataBlock< std::wstring > WstringBlock
Definition: DataBlock.h:385
VariableBlock()
Default empty constructor, block has no value of any kind.
Definition: DataBlock.h:429
DataBlock< double > DoubleBlock
Definition: DataBlock.h:388
std::unique_ptr< RStrType > GetStringInQuotes(QUOTETYPE quotes, int specialflags=0)
Gets the next string in quotes.
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
#define DATABLOCK_TYPE_INT
Definition: DataBlock.h:22
DataBlockAll * BlockData
Definition: DataBlock.h:756
static DLLEXPORT ScriptExecutor * Get()
#define DATABLOCK_TYPE_WSTRING
Definition: DataBlock.h:25
ScriptSafeVariableBlock(DataBlock< BlockBaseType > *block, const std::string &name)
Definition: DataBlock.h:844
#define DATABLOCK_TYPE_FLOAT
Definition: DataBlock.h:23
DataBlock< bool > BoolBlock
Definition: DataBlock.h:384
Iterator class for getting parts of a string.
#define DATABLOCK_TYPE_STRING
Definition: DataBlock.h:26
bool IsConversionAllowedNonPtr() const
Definition: DataBlock.h:663
#define DATABLOCK_TYPE_DOUBLE
Definition: DataBlock.h:28
DataBlockAll * GetBlock()
Definition: DataBlock.h:499
const DataBlockAll * GetBlockConst() const
Definition: DataBlock.h:504
DataBlock< int > IntBlock
Definition: DataBlock.h:382
DLLEXPORT void AddDataToPacket(sf::Packet &packet)
Definition: DataBlock.cpp:180
Main DataBlock class.
Definition: DataBlock.h:37
static const DataBlockAll * Conversion(const DataBlockAll *bl)
Definition: DataBlock.h:395
DEFAULTTOANDFROMPACKETCONVERTFUNCTINS(IntBlock, int, int)
#define DLLEXPORT
Definition: Include.h:84
#define DATABLOCK_TYPE_BOOL
Definition: DataBlock.h:24
DataBlock< std::string > StringBlock
Definition: DataBlock.h:386
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
#define SAFE_DELETE(x)
Definition: Define.h:149
DataBlock variant with name.
Definition: DataBlock.h:762
#define DATABLOCK_TYPE_CHAR
Definition: DataBlock.h:27
static DLLEXPORT bool IsStringBool(const std::string &val, bool *receiver)
Definition: Convert.cpp:37
DLLEXPORT void AddDataToPacket(sf::Packet &packet) const
Stores data to a packet.
Definition: DataBlock.cpp:195
DataBlock< char > CharBlock
Definition: DataBlock.h:387
DataBlock(const _U &forceempty)
Creates an uninitialized block of type non.
Definition: DataBlock.h:166
DLLEXPORT std::ostream & operator<<(std::ostream &stream, const VariableBlock &value)
Definition: DataBlock.cpp:284