Leviathan  0.8.0.0
Leviathan game engine
NamedVars.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
2 #include "NamedVars.h"
3 
4 #include "../../Iterators/StringIterator.h"
5 #include "FileSystem.h"
6 #include <cstdint>
7 #include <limits.h>
8 
9 using namespace Leviathan;
10 using namespace std;
11 // ------------------------------------ //
12 NamedVariableList::NamedVariableList() : Datas(0), Name("") {}
13 
14 DLLEXPORT NamedVariableList::NamedVariableList(const std::string& name) : Datas(0), Name(name)
15 {}
16 
18  const std::string& name, VariableBlock* value1) :
19  Datas(1),
20  Name(name)
21 {
22  // set value //
23  Datas[0] = value1;
24 }
25 
27  const std::string& name, const VariableBlock& val) :
28  Datas(1),
29  Name(name)
30 {
31  // set value //
32  Datas[0] = new VariableBlock(val);
33 }
34 
35 #ifdef LEVIATHAN_USING_ANGELSCRIPT
37  Datas(1), Name(data->GetName())
38 {
39  // Copy value //
40  Datas[0] = new VariableBlock(*data);
41 }
42 #endif // LEVIATHAN_USING_ANGELSCRIPT
43 
45  const std::string& name, vector<VariableBlock*> values_willclear) :
46  Datas(values_willclear.size()),
47  Name(name)
48 {
49  // set values //
50  for(size_t i = 0; i < values_willclear.size(); i++) {
51  Datas[i] = values_willclear[i];
52  }
53 }
54 
56  Datas(other.Datas.size()), Name(other.Name)
57 {
58 
59  // copy value over //
60  for(size_t i = 0; i < other.Datas.size(); i++) {
61 
62  Datas[i] = new VariableBlock(*other.Datas[i]);
63  }
64 }
65 
67  LErrorReporter* errorreport, map<std::string, std::shared_ptr<VariableBlock>>* predefined
68  /*= NULL*/)
69 {
70  // using StringIterator makes this shorter //
71  StringIterator itr(&line);
72 
73  auto name = itr.GetUntilEqualityAssignment<std::string>(EQUALITYCHARACTER_TYPE_ALL);
74 
75  if(!name) {
76  // no name //
77 #ifdef ALTERNATIVE_EXCEPTIONS_FATAL
78  errorreport->Error(std::string("invalid data on line (invalid name)"));
79  return;
80 #else
81  throw InvalidArgument("invalid data on line (invalid name)");
82 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
83  }
84 
85  Name = *name;
86 
87  // skip whitespace //
88  itr.SkipWhiteSpace();
89 
90  // get last part of it //
91  auto tempvar = itr.GetUntilNextCharacterOrAll<std::string>(L';');
92 
93  if(!tempvar || tempvar->size() < 1) {
94  // no variable //
95 #ifdef ALTERNATIVE_EXCEPTIONS_FATAL
96  Name = "";
97  errorreport->Error(std::string("invalid data on line (no variable data)"));
98  return;
99 #else
100  throw InvalidArgument("invalid data on line (no variable data)");
101 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
102  }
103 
104  if(!ConstructValuesForObject(*tempvar, errorreport, predefined)) {
105 #ifdef ALTERNATIVE_EXCEPTIONS_FATAL
106  Name = "";
107  errorreport->Error(std::string("invalid variable string, parsing failed"));
108  return;
109 #else
110  throw InvalidArgument("invalid variable string, parsing failed");
111 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
112  }
113 }
114 
116  const std::string& valuestr, LErrorReporter* errorreport,
117  map<string, std::shared_ptr<VariableBlock>>* predefined /*= NULL*/)
118 {
119  // We already have the name provided for us //
120  Name = name;
121 
122  // The value needs to be parsed //
123  if(!ConstructValuesForObject(valuestr, errorreport, predefined)) {
124 #ifdef ALTERNATIVE_EXCEPTIONS_FATAL
125  Name = "";
126  errorreport->Error(std::string("invalid variable string, parsing failed"));
127  return;
128 #else
129  throw InvalidArgument("invalid variable string, parsing failed");
130 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
131  }
132 }
133 
134 DLLEXPORT bool NamedVariableList::RecursiveParseList(std::vector<VariableBlock*>& resultvalues,
135  std::unique_ptr<std::string> expression, LErrorReporter* errorreport,
136  std::map<std::string, std::shared_ptr<VariableBlock>>* predefined)
137 {
138  // Empty brackets //
139  if(!expression) {
140 
141  resultvalues.push_back(new VariableBlock(new StringBlock(new string())));
142  return true;
143  }
144 
145  StringIterator itr(expression.get());
146 
147  itr.SkipWhiteSpace();
148 
149  // TODO: allow commas inside brackets without quoting them
150  while(auto value = itr.GetUntilNextCharacterOrAll<string>(',')) {
151 
152  StringIterator itr2(value.get());
153 
154  itr2.SkipWhiteSpace();
155 
156  if(itr2.IsOutOfBounds()) {
157 
158  continue;
159  }
160 
161  // Parameter is wrapped in brackets //
162  if(itr2.GetCharacter() == '[') {
163 
164  auto firstvalue = itr2.GetStringInBracketsRecursive<string>();
165 
166  std::vector<VariableBlock*> morevalues;
167 
168  if(!RecursiveParseList(morevalues, move(firstvalue), errorreport, predefined)) {
169 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
170  throw InvalidArgument("Sub expression parsing failed");
171 #else
172  errorreport->Error(std::string("Sub expression parsing failed"));
173  return false;
174 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
175  }
176 
177  if(morevalues.size() > 1) {
178 
179  SAFE_DELETE_VECTOR(morevalues);
180  morevalues.clear();
181 
182 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
183  throw InvalidArgument("NamedVars recursive parsing is not done");
184 #else
185  LEVIATHAN_ASSERT(0, "NamedVars recursive parsing is not done");
186 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
187 
188  } else {
189 
190  // Just a single or no values where wrapped in extra brackets //
191  for(auto ptr : morevalues) {
192  resultvalues.push_back(ptr);
193  }
194 
195  morevalues.clear();
196  }
197 
198  continue;
199  }
200 
201  // Parse value //
202  auto valuestr = itr2.GetUntilEnd<string>();
203 
204  if(!valuestr)
205  continue;
206 
207  std::unique_ptr<VariableBlock> tmpcreated;
208 
209 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
210  try {
211  tmpcreated = std::make_unique<VariableBlock>(*valuestr, predefined);
212  } catch(const InvalidArgument&) {
213 
214  // Rethrow the exception //
215  SAFE_DELETE_VECTOR(resultvalues);
216  throw;
217  }
218 #else
219  tmpcreated = std::make_unique<VariableBlock>(*valuestr, predefined);
220 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
221 
222  if(!tmpcreated || !tmpcreated->IsValid()) {
223 
224  SAFE_DELETE_VECTOR(resultvalues);
225  errorreport->Error(std::string("VariableBlock invalid value: " + *valuestr));
226  return false;
227  }
228 
229  resultvalues.push_back(tmpcreated.release());
230  }
231 
232  return true;
233 }
234 
235 DLLEXPORT bool NamedVariableList::ConstructValuesForObject(const std::string& variablestr,
236  LErrorReporter* errorreport,
237  std::map<std::string, std::shared_ptr<VariableBlock>>* predefined)
238 {
239  if(variablestr.size() == 0) {
240 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
241  throw InvalidArgument("invalid variable string, 0 length");
242 #else
243  errorreport->Error(std::string("invalid variable string, 0 length"));
244  return false;
245 #endif
246  }
247 
248  // check does it have brackets (and need to be processed like so) //
249  if(variablestr[0] == L'[') {
250 
251  // Needs to be split into values //
252  StringIterator itr(variablestr);
253 
254  auto firstlevel = itr.GetStringInBracketsRecursive<string>();
255 
256  std::vector<VariableBlock*> parsedvalues;
257 
258 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
259 
260  try {
261  if(!RecursiveParseList(
262  parsedvalues, std::move(firstlevel), errorreport, predefined)) {
263 
264  throw InvalidArgument("NamedVariableList could not parse top level bracket "
265  "expression");
266  }
267  } catch(const InvalidArgument&) {
268 
269  throw;
270  }
271 #else
272  if(!RecursiveParseList(parsedvalues, std::move(firstlevel), errorreport, predefined)) {
273 
274  errorreport->Error(
275  std::string("NamedVariableList could not parse top level bracket "
276  "expression"));
277  return false;
278  }
279 
280 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
281 
282  for(auto iter = Datas.begin(); iter != Datas.end(); ++iter) {
283 
284  SAFE_DELETE(*iter);
285  }
286 
287  Datas.resize(parsedvalues.size());
288 
289  // Add the final values //
290  for(size_t i = 0; i < Datas.size(); i++) {
291 
292  Datas[i] = parsedvalues[i];
293  }
294 
295  parsedvalues.clear();
296 
297  return true;
298  }
299 
300  // just one value //
301 
302  // try to create new VariableBlock //
303  // it should always have one element //
304  std::unique_ptr<VariableBlock> tmpcreated;
305 
306 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
307  try {
308  tmpcreated = std::make_unique<VariableBlock>(variablestr, predefined);
309  } catch(const InvalidArgument&) {
310 
311  // Rethrow the exception //
312  SAFE_DELETE_VECTOR(Datas);
313  throw;
314  }
315 #else
316  tmpcreated = std::make_unique<VariableBlock>(variablestr, predefined);
317 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
318 
319  if(!tmpcreated || !tmpcreated->IsValid()) {
320 
321  SAFE_DELETE_VECTOR(Datas);
322  return false;
323  }
324 
325  Datas.push_back(tmpcreated.release());
326  return true;
327 }
328 #ifdef SFML_PACKETS
329 // ------------------ Handling passing to packets ------------------ //
331 {
332  // Unpack the data from the packet //
333  packet >> Name;
334 
335  // First get the size //
336  int tmpsize = 0;
337 
338  // Thousand is considered here the maximum number of elements //
339  if(!(packet >> tmpsize) || tmpsize > 1000 || tmpsize < 0) {
340 
341  throw InvalidArgument("invalid packet format");
342  }
343 
344  // Reserve enough space //
345  Datas.reserve((size_t)tmpsize);
346 
347  // Loop and get the data //
348  for(int i = 0; i < tmpsize; i++) {
349 
350  Datas.push_back(new VariableBlock(packet));
351  }
352 }
353 
354 DLLEXPORT void NamedVariableList::AddDataToPacket(sf::Packet& packet) const
355 {
356  // Start adding data to the packet //
357  packet << Name;
358 
359  // The vector passing //
360  int truncsize = (int)Datas.size();
361 
362  if(truncsize > 1000) {
363 
364  // That's an error //
365  Logger::Get()->Error("NamedVariableList: AddToPacket: too many elements (sane maximum "
366  "is 1000 values), got " +
367  Convert::ToString(truncsize) +
368  " values, truncated to first 1000");
369 
370  truncsize = 1000;
371  }
372 
373  packet << truncsize;
374 
375  // Pass that number of elements //
376  for(int i = 0; i < truncsize; i++) {
377 
378  Datas[i]->AddDataToPacket(packet);
379  }
380 }
381 #endif // SFML_PACKETS
382 
384 {
385 
386  SAFE_DELETE_VECTOR(Datas);
387 }
388 // ------------------------------------ //
390 {
391  // clear old //
392  SAFE_DELETE_VECTOR(Datas);
393 
394  // assign value //
395 
396  // create new //
397  Datas.push_back(new VariableBlock(value1));
398 }
399 
401 {
402  // clear old //
403  SAFE_DELETE_VECTOR(Datas);
404 
405  // put value to vector //
406  Datas.push_back(value1);
407 }
408 
409 DLLEXPORT void NamedVariableList::SetValue(const int& nindex, const VariableBlock& valuetoset)
410 {
411  // check do we need to allocate new //
412  if(Datas.size() <= (size_t)nindex) {
413 
414  // resize to have enough space //
415  Datas.resize(nindex + 1, NULL);
416  Datas[nindex] = new VariableBlock(valuetoset);
417  } else {
418 
419  if(Datas[nindex] != NULL) {
420  // assign to existing value //
421  *Datas[nindex] = valuetoset;
422  } else {
423  // new value needed //
424  Datas[nindex] = new VariableBlock(valuetoset);
425  }
426  }
427 }
428 
429 DLLEXPORT void NamedVariableList::SetValue(const int& nindex, VariableBlock* valuetoset)
430 {
431  // check do we need to allocate new //
432  if(Datas.size() <= (size_t)nindex) {
433 
434  // resize to have enough space //
435  Datas.resize(nindex + 1, NULL);
436  // just copy the pointer //
437  Datas[nindex] = valuetoset;
438  } else {
439 
440  if(Datas[nindex] != NULL) {
441  // existing value needs to be deleted //
442  SAFE_DELETE(Datas[nindex]);
443  }
444  // set pointer //
445  Datas[nindex] = valuetoset;
446  }
447 }
448 
449 DLLEXPORT void NamedVariableList::SetValue(const vector<VariableBlock*>& values)
450 {
451  // delete old //
452  SAFE_DELETE_VECTOR(Datas);
453 
454  // copy vector (will copy pointers and steal them) //
455  Datas = values;
456 }
457 DLLEXPORT void NamedVariableList::PushValue(std::unique_ptr<VariableBlock>&& value)
458 {
459  Datas.push_back(value.release());
460 }
461 // ------------------------------------ //
463 {
464  // uses vector operator to get value, might throw something //
465  return *Datas[0];
466 }
467 
469 {
470  // uses vector operator to get value, might throw or something //
471  return *Datas[nindex];
472 }
473 
474 DLLEXPORT void NamedVariableList::GetName(std::string& name) const
475 {
476  // return name in a reference //
477  name = Name;
478 }
479 
480 void NamedVariableList::SetName(const std::string& name)
481 {
482  Name = name;
483 }
484 
485 bool NamedVariableList::CompareName(const std::string& name) const
486 {
487  // just default comparison //
488  return Name.compare(name) == 0;
489 }
491  int WhichSeparator /*= 0*/, bool AddAllBrackets /*= false*/) const
492 {
493 
494  string stringifiedval = Name;
495 
496  switch(WhichSeparator) {
497  default:
498  case 0: stringifiedval += " = "; break;
499  case 1: stringifiedval += ": "; break;
500  }
501 
502  // convert value to string //
503 
504  const bool WrapInBrackets = AddAllBrackets ? true : Datas.size() != 1;
505 
506  // starting bracket //
507  if(WrapInBrackets)
508  stringifiedval += "[";
509 
510  // reserve some space //
511  stringifiedval.reserve(Datas.size() * 4);
512 
513  for(size_t i = 0; i < Datas.size(); i++) {
514 
515  if(i != 0)
516  stringifiedval += ", ";
517 
518  // Check if type is a string type //
519  int blocktype = Datas[i]->GetBlockConst()->Type;
520 
521  if(blocktype == DATABLOCK_TYPE_STRING || blocktype == DATABLOCK_TYPE_WSTRING ||
522  blocktype == DATABLOCK_TYPE_CHAR) {
523  // Output in quotes //
524  if(AddAllBrackets)
525  stringifiedval += "[\"" + Datas[i]->operator string() + "\"]";
526  else
527  stringifiedval += "\"" + Datas[i]->operator string() + "\"";
528 
529  } else if(blocktype == DATABLOCK_TYPE_BOOL) {
530 
531  // Use true/false for this //
532  if(AddAllBrackets) {
533 
534  stringifiedval +=
535  "[" + (Datas[i]->operator bool() ? string("true") : string("false")) + "]";
536 
537  } else {
538 
539  stringifiedval += Datas[i]->operator bool() ? string("true") : string("false");
540  }
541 
542  } else {
543 
544  // check is conversion allowed //
545  if(!Datas[i]->IsConversionAllowedNonPtr<string>()) {
546 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
547  // no choice but to throw exception //
548  throw InvalidType("value cannot be cast to string");
549 #else
550  LEVIATHAN_ASSERT(0, "value cannot be cast to string");
551 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
552  }
553  if(AddAllBrackets)
554  stringifiedval += "[" + Datas[i]->operator string() + "]";
555  else
556  stringifiedval += "" + Datas[i]->operator string() + "";
557  }
558  }
559 
560  // add ending bracket and done //
561  if(WrapInBrackets)
562  stringifiedval += "];";
563  else
564  stringifiedval += ";";
565 
566  return stringifiedval;
567 }
568 
570 {
571  // copy values //
572  Name = other.Name;
573 
574  SAFE_DELETE_VECTOR(Datas);
575  Datas.resize(other.Datas.size());
576  // copy values over //
577  for(size_t i = 0; i < other.Datas.size(); i++) {
578 
579  Datas[i] = new VariableBlock(*other.Datas[i]);
580  }
581 
582  // return this as result //
583  return *this;
584 }
585 
587 {
588  // Make sure that names are the same //
589  if(Name != other.Name)
590  return false;
591 
592  // Check variables //
593  if(Datas.size() != other.Datas.size())
594  return false;
595 
596  // Compare data in the DataBlocks //
597  for(size_t i = 0; i < Datas.size(); i++) {
598 
599  if(*Datas[i] != *other.Datas[i])
600  return false;
601  }
602 
603  // They truly are the same //
604  return true;
605 }
607 {
608 
609  return !(*this == other);
610 }
611 // ----------------- process functions ------------------- //
612 DLLEXPORT bool NamedVariableList::ProcessDataDump(const std::string& data,
613  std::vector<std::shared_ptr<NamedVariableList>>& vec, LErrorReporter* errorreport,
614  std::map<std::string, std::shared_ptr<VariableBlock>>* predefined /*= NULL*/)
615 {
616  // Split to lines //
617  std::vector<std::shared_ptr<std::string>> lines;
618 
619  StringIterator itr(data);
620 
621  // Use string iterator to get the lines that are separated by ; //
622  std::unique_ptr<std::string> curLine;
623  size_t lineLength = 0;
624 
625  do {
626  curLine = itr.GetUntilNextCharacterOrNothing<std::string>(';');
627 
628  if(!curLine)
629  break;
630 
631  lineLength = curLine->size();
632 
633  lines.push_back(std::shared_ptr<string>(curLine.release()));
634 
635  } while(lineLength != 0);
636 
637 
638  if(lines.empty()) {
639  // No lines //
640  return false;
641  }
642 
643  // Make space for values //
644  // let's reserve space //
645  vec.reserve(lines.size());
646 
647  // Fill values //
648  for(size_t i = 0; i < lines.size(); ++i) {
649  // Skip empty lines //
650  if(lines[i]->empty())
651  continue;
652 
653  // Create a named var //
654 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
655  try {
656  auto var =
657  std::make_shared<NamedVariableList>(*lines[i], Logger::Get(), predefined);
658 
659  if(!var || !var->IsValid()) {
660  // Invalid value //
661  continue;
662  }
663 
664  vec.push_back(var);
665 
666  } catch(const InvalidArgument& e) {
667  // exception throws, must be invalid line //
668 
669  errorreport->Error("NamedVar: ProcessDataDump: contains invalid line, "
670  "line (with only ASCII characters): " +
671  // This should remove null characters from the string //
672  Convert::ToString(*lines[i]) + "\nEND");
673 
674  // Print to log //
675  e.Print(errorreport);
676 
677  continue;
678  }
679 
680 #else
681 
682  std::shared_ptr<NamedVariableList> var(
683  new NamedVariableList(*lines[i], errorreport, predefined));
684 
685  if(!var || !var->IsValid()) {
686  // Invalid value //
687  continue;
688  }
689 
690  vec.push_back(var);
691 
692 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
693  }
694 
695  return true;
696 }
697 
699  NamedVariableList& receiver, NamedVariableList& donator)
700 {
701  // only overwrite name if there is one //
702  if(donator.Name.size() > 0)
703  receiver.Name = donator.Name;
704 
705 
706  SAFE_DELETE_VECTOR(receiver.Datas);
707  // resize to match sizes to avoid excess resizing //
708  receiver.Datas.resize(donator.Datas.size());
709 
710  for(size_t i = 0; i < donator.Datas.size(); i++) {
711 
712  receiver.Datas[i] = donator.Datas[i];
713  }
714  // clear donator data //
715  donator.Datas.clear();
716 }
717 
719 {
720  // return first element //
721  return Datas.size() ? Datas[0] : NULL;
722 }
723 
725 {
726 
727  if(nindex >= Datas.size())
728  return nullptr;
729 
730  return Datas[nindex];
731 }
732 
734 {
735  return Datas.size();
736 }
737 
739 {
740  // if all have a common type return it //
741  if(Datas.size() == 0)
742  // no common type //
743  return DATABLOCK_TYPE_ERROR;
744 
745  int lasttype = Datas[0]->GetBlock()->Type;
746 
747  for(size_t i = 1; i < Datas.size(); i++) {
748 
749  if(lasttype != Datas[i]->GetBlock()->Type) {
750  // not same type //
751  return DATABLOCK_TYPE_ERROR;
752  }
753  }
754  // there is a common type //
755  return lasttype;
756 }
757 
759 {
760  // get variable type of first index //
761  return Datas.size() ? Datas[0]->GetBlock()->Type : DATABLOCK_TYPE_ERROR;
762 }
763 
764 DLLEXPORT int NamedVariableList::GetVariableType(const int& nindex) const
765 {
766 
767  return Datas[nindex]->GetBlock()->Type;
768 }
769 
771 {
772  // will allow to throw any exceptions the vector wants //
773  return *Datas[nindex];
774 }
775 
776 DLLEXPORT vector<VariableBlock*>& NamedVariableList::GetValues()
777 {
778  return Datas;
779 }
780 // ---------------------------- NamedVars --------------------------------- //
781 NamedVars::NamedVars() : Variables()
782 {
783  // nothing to initialize //
784 }
786 {
787  // deep copy is required here //
788  Variables.reserve(other.Variables.size());
789  for(size_t i = 0; i < other.Variables.size(); i++) {
790  Variables.push_back(
791  shared_ptr<NamedVariableList>(new NamedVariableList(*other.Variables[i])));
792  }
793 }
794 
795 DLLEXPORT NamedVars::NamedVars(NamedVars* stealfrom) : Variables(stealfrom->Variables)
796 {
797  stealfrom->Variables.clear();
798 }
799 
800 DLLEXPORT NamedVars::NamedVars(const std::string& datadump, LErrorReporter* errorreport) :
801  Variables()
802 {
803 
804  // load data directly to vector //
805  if(!NamedVariableList::ProcessDataDump(datadump, Variables, errorreport, NULL)) {
806 
807  // error happened //
808 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
809  throw InvalidArgument("datadump processing failed");
810 #else
811  StateIsInvalid = true;
812  return;
813 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
814  }
815 }
816 
817 DLLEXPORT NamedVars::NamedVars(const vector<shared_ptr<NamedVariableList>>& variables) :
818  Variables(variables)
819 {}
820 
821 DLLEXPORT NamedVars::NamedVars(shared_ptr<NamedVariableList> variable) : Variables(1)
822 {
823  // store the single variable //
824  Variables[0] = variable;
825 }
826 
827 DLLEXPORT NamedVars::NamedVars(NamedVariableList* takevariable) : Variables(1)
828 {
829  Variables[0] = std::shared_ptr<NamedVariableList>(takevariable);
830 }
831 
833 {
834  // no need to release due to smart pointers //
835 }
836 // ------------------------------------ //
837 #ifdef SFML_PACKETS
838 DLLEXPORT NamedVars::NamedVars(sf::Packet& packet)
839 {
840  // First get the size //
841  int isize;
842 
843  if(!(packet >> isize)) {
844 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
845  throw InvalidArgument("packet has invalid format");
846 #else
847  StateIsInvalid = true;
848  return;
849 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
850  }
851 
852  // Reserve space //
853  Variables.reserve(isize);
854 
855  for(int i = 0; i < isize; i++) {
856 
857  shared_ptr<NamedVariableList> newvalue(new NamedVariableList(packet));
858 
859  if(!newvalue || !newvalue->IsValid())
860  continue;
861 
862  Variables.push_back(newvalue);
863  }
864 }
865 
866 DLLEXPORT void NamedVars::AddDataToPacket(sf::Packet& packet) const
867 {
868  GUARD_LOCK();
869 
870  // First write size //
871  int isize = (int)Variables.size();
872 
873  packet << isize;
874 
875  // Write each individual variable //
876  for(int i = 0; i < isize; i++) {
877 
878  Variables[i]->AddDataToPacket(packet);
879  }
880 }
881 #endif // SFML_PACKETS
882 // ------------------------------------ //
883 DLLEXPORT bool NamedVars::Add(std::shared_ptr<NamedVariableList> value)
884 {
885  GUARD_LOCK();
886 
887  auto index = Find(guard, value->Name);
888  // index check //
889  if(index >= Variables.size()) {
890 
891  Variables.push_back(value);
892  return true;
893  }
894 
895  Variables[index] = value;
896  return false;
897 }
898 
899 DLLEXPORT bool NamedVars::SetValue(const std::string& name, const VariableBlock& value1)
900 {
901  GUARD_LOCK();
902  auto index = Find(name);
903 
904  if(index >= Variables.size())
905  return false;
906 
907 
908  Variables[index]->SetValue(value1);
909  return true;
910 }
911 
912 DLLEXPORT bool NamedVars::SetValue(const std::string& name, VariableBlock* value1)
913 {
914  GUARD_LOCK();
915  auto index = Find(guard, name);
916 
917  if(index >= Variables.size())
918  return false;
919 
920 
921  Variables[index]->SetValue(value1);
922  return true;
923 }
924 
926  const std::string& name, const vector<VariableBlock*>& values)
927 {
928  GUARD_LOCK();
929  auto index = Find(name);
930 
931  if(index >= Variables.size())
932  return false;
933 
934 
935  Variables[index]->SetValue(values);
936  return true;
937 }
938 
940 {
941  GUARD_LOCK();
942  auto index = Find(nameandvalues.Name);
943  // index check //
944  if(index >= Variables.size()) {
945 
946  Variables.push_back(
947  shared_ptr<NamedVariableList>(new NamedVariableList(nameandvalues)));
948  return true;
949  }
950 
951  nameandvalues.Name.clear();
952  // set values with "swap" //
953  NamedVariableList::SwitchValues(*Variables[index].get(), nameandvalues);
954  return true;
955 }
956 
958 {
959  GUARD_LOCK();
960  auto index = Find(guard, name);
961 
962  if(index >= Variables.size()) {
963 
964 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
965  throw InvalidArgument("value not found");
966 #else
967  LEVIATHAN_ASSERT(0, "NamedVars name not found");
968 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
969  }
970 
971  return Variables[index]->GetValue();
972 }
973 
974 DLLEXPORT const VariableBlock* NamedVars::GetValue(const std::string& name) const
975 {
976  GUARD_LOCK();
977 
978  auto index = Find(guard, name);
979 
980  if(index >= Variables.size()) {
981 
982 #ifndef ALTERNATIVE_EXCEPTIONS_FATAL
983  throw InvalidArgument("value not found");
984 #else
985  return nullptr;
986 #endif // ALTERNATIVE_EXCEPTIONS_FATAL
987  }
988 
989  return Variables[index]->GetValueDirect();
990 }
991 
992 DLLEXPORT bool NamedVars::GetValue(const std::string& name, VariableBlock& receiver) const
993 {
994  GUARD_LOCK();
995 
996  auto index = Find(guard, name);
997  // index check //
998  if(index >= Variables.size()) {
999  return false;
1000  }
1001  // specific operator wanted here //
1002  receiver = const_cast<const VariableBlock&>(Variables[index]->GetValue());
1003  return true;
1004 }
1005 
1007  const std::string& name, const int& nindex, VariableBlock& receiver) const
1008 {
1009  GUARD_LOCK();
1010 
1011  auto index = Find(guard, name);
1012 
1013  // index check //
1014  if(index >= Variables.size()) {
1015  return false;
1016  }
1017 
1018  // specific operator wanted here //
1019  receiver = const_cast<const VariableBlock&>(Variables[index]->GetValue(nindex));
1020  return true;
1021 }
1022 
1023 DLLEXPORT bool NamedVars::GetValue(const int& index, VariableBlock& receiver) const
1024 {
1025  GUARD_LOCK();
1026 
1027  // index check //
1028  if(index >= static_cast<int>(Variables.size())) {
1029  return false;
1030  }
1031 
1032  // specific operator wanted here //
1033  receiver = const_cast<const VariableBlock&>(Variables[index]->GetValue(0));
1034  return true;
1035 }
1036 
1037 DLLEXPORT size_t NamedVars::GetValueCount(const std::string& name) const
1038 {
1039  GUARD_LOCK();
1040 
1041  auto index = Find(guard, name);
1042  // index check //
1043  if(index >= Variables.size()) {
1044  return 0;
1045  }
1046 
1047  return Variables[index]->GetVariableCount();
1048 }
1049 
1050 DLLEXPORT vector<VariableBlock*>* NamedVars::GetValues(const std::string& name)
1051 {
1052  GUARD_LOCK();
1053  auto index = Find(guard, name);
1054  // index check //
1055  if(index >= Variables.size()) {
1056  return NULL;
1057  }
1058 
1059  return &Variables[index]->GetValues();
1060 }
1061 
1063  const std::string& name, vector<const VariableBlock*>& receiver) const
1064 {
1065  GUARD_LOCK();
1066  auto index = Find(guard, name);
1067  // index check //
1068  if(index >= Variables.size()) {
1069  return false;
1070  }
1071  vector<VariableBlock*>& tmpvals = Variables[index]->GetValues();
1072 
1073  vector<const VariableBlock*> tmpconsted(tmpvals.size());
1074 
1075  for(size_t i = 0; i < tmpconsted.size(); i++) {
1076 
1077  tmpconsted[i] = const_cast<const VariableBlock*>(tmpvals[i]);
1078  }
1079 
1080  receiver = tmpconsted;
1081  return true;
1082 }
1083 
1084 DLLEXPORT std::shared_ptr<NamedVariableList> NamedVars::GetValueDirect(
1085  const std::string& name) const
1086 {
1087  GUARD_LOCK();
1088  auto index = Find(guard, name);
1089  // index check //
1090  if(index >= Variables.size()) {
1091  return NULL;
1092  }
1093  return Variables[index];
1094 }
1095 
1097 {
1098  GUARD_LOCK();
1099  auto index = Find(guard, name);
1100  // index check //
1101  if(index >= Variables.size()) {
1102  return NULL;
1103  }
1104 
1105  return Variables[index].get();
1106 }
1107 
1109 {
1110  if(index >= Variables.size()) {
1111  return nullptr;
1112  }
1113 
1114  return Variables[index].get();
1115 }
1116 
1118  const std::string& lineprefix /*= ""*/) const
1119 {
1120  std::string result;
1121 
1122  for(const auto& variable : Variables) {
1123 
1124  result += lineprefix + variable->ToText(0) + "\n";
1125  }
1126 
1127  return result;
1128 }
1129 
1130 // ------------------------------------ //
1131 DLLEXPORT int NamedVars::GetVariableType(const std::string& name) const
1132 {
1133  GUARD_LOCK();
1134  // call overload //
1135  return GetVariableType(guard, Find(guard, name));
1136 }
1137 
1138 DLLEXPORT int NamedVars::GetVariableType(Lock& guard, size_t index) const
1139 {
1140  return Variables[index]->GetVariableType();
1141 }
1142 
1143 DLLEXPORT int NamedVars::GetVariableTypeOfAll(const std::string& name) const
1144 {
1145  GUARD_LOCK();
1146  // call overload //
1147  return GetVariableTypeOfAll(guard, Find(guard, name));
1148 }
1149 
1150 DLLEXPORT int NamedVars::GetVariableTypeOfAll(Lock& guard, size_t index) const
1151 {
1152  return Variables[index]->GetCommonType();
1153 }
1154 // ------------------------------------ //
1155 string NamedVars::GetName(size_t index)
1156 {
1157  GUARD_LOCK();
1158 
1159  return Variables[index]->GetName();
1160 }
1161 
1162 DLLEXPORT bool NamedVars::GetName(size_t index, string& name) const
1163 {
1164  GUARD_LOCK();
1165 
1166  Variables[index]->GetName(name);
1167  return true;
1168 }
1169 
1170 void NamedVars::SetName(Lock& guard, size_t index, const std::string& name)
1171 {
1172 
1173  Variables[index]->SetName(name);
1174 }
1175 
1176 void NamedVars::SetName(const std::string& oldname, const std::string& name)
1177 {
1178  GUARD_LOCK();
1179  // call overload //
1180  SetName(guard, Find(guard, oldname), name);
1181 }
1182 
1183 bool NamedVars::CompareName(size_t index, const std::string& name) const
1184 {
1185  GUARD_LOCK();
1186 
1187  return Variables[index]->CompareName(name);
1188 }
1189 // ------------------------------------ //
1190 DLLEXPORT void NamedVars::AddVar(shared_ptr<NamedVariableList> values)
1191 {
1192  GUARD_LOCK();
1193  RemoveIfExists(values->GetName(), guard);
1194  // just add to vector //
1195  Variables.push_back(values);
1196 }
1197 
1199 {
1200  GUARD_LOCK();
1201  RemoveIfExists(newvaluetoadd->GetName(), guard);
1202  // create new smart pointer and push back //
1203  Variables.push_back(shared_ptr<NamedVariableList>(newvaluetoadd));
1204 }
1205 
1206 DLLEXPORT void NamedVars::AddVar(const std::string& name, VariableBlock* valuetosteal)
1207 {
1208  GUARD_LOCK();
1209  RemoveIfExists(name, guard);
1210  // create new smart pointer and push back //
1211  Variables.push_back(
1212  shared_ptr<NamedVariableList>(new NamedVariableList(name, valuetosteal)));
1213 }
1214 // ------------------------------------ //
1215 void NamedVars::Remove(size_t index)
1216 {
1217  GUARD_LOCK();
1218 
1219  // smart pointers //
1220  Variables.erase(Variables.begin() + index);
1221 }
1222 
1223 DLLEXPORT void NamedVars::Remove(const std::string& name)
1224 {
1225  // call overload //
1226  Remove(Find(name));
1227 }
1228 
1229 DLLEXPORT void NamedVars::RemoveIfExists(const std::string& name, Lock& guard)
1230 {
1231  // Try to find it //
1232  size_t index = Find(guard, name);
1233 
1234  if(index >= Variables.size())
1235  return;
1236 
1237 
1238  Variables.erase(Variables.begin() + index);
1239 }
1240 // ------------------------------------ //
1241 bool NamedVars::LoadVarsFromFile(const std::string& file, LErrorReporter* errorreport)
1242 {
1243  // call datadump loaded with this object's vector //
1244  return FileSystem::LoadDataDump(file, Variables, errorreport);
1245 }
1246 vector<shared_ptr<NamedVariableList>>* NamedVars::GetVec()
1247 {
1248  return &Variables;
1249 }
1250 void NamedVars::SetVec(vector<shared_ptr<NamedVariableList>>& vec)
1251 {
1252  GUARD_LOCK();
1253  Variables = vec;
1254 }
1255 // ------------------------------------ //
1256 DLLEXPORT size_t NamedVars::Find(Lock& guard, const std::string& name) const
1257 {
1258  for(size_t i = 0; i < Variables.size(); i++) {
1259  if(Variables[i]->CompareName(name))
1260  return i;
1261  }
1262 
1263  return std::numeric_limits<size_t>::max();
1264 }
1265 // ------------------ Script compatible functions ------------------ //
1266 #ifdef LEVIATHAN_USING_ANGELSCRIPT
1268 {
1269  // Use a try block to not throw exceptions to the script engine //
1270  try {
1271  VariableBlock& tmpblock = GetValueNonConst(name);
1272 
1273  // Create script safe version //
1274  return new ScriptSafeVariableBlock(&tmpblock, name);
1275 
1276 
1277  } catch(...) {
1278  // Something failed, return empty handle //
1279  return NULL;
1280  }
1281 }
1282 
1284 {
1285  GUARD_LOCK();
1286 
1287  RemoveIfExists(value->GetName(), guard);
1288 
1289  bool success = false;
1290 
1291  try {
1292 
1293  Variables.push_back(shared_ptr<NamedVariableList>(new NamedVariableList(value)));
1294  success = true;
1295 
1296  } catch(...) {
1297  }
1298 
1299  value->Release();
1300  return success;
1301 }
1302 #endif // LEVIATHAN_USING_ANGELSCRIPT
1303 
1305 {
1306  return Variables.size();
1307 }
DLLEXPORT VariableBlock & GetValueNonConst(const std::string &name)
Definition: NamedVars.cpp:957
static DLLEXPORT void SwitchValues(NamedVariableList &receiver, NamedVariableList &donator)
Switches values to a new instance.
Definition: NamedVars.cpp:698
DLLEXPORT size_t GetValueCount(const std::string &name) const
Definition: NamedVars.cpp:1037
static DLLEXPORT bool ProcessDataDump(const std::string &data, std::vector< std::shared_ptr< NamedVariableList >> &vec, LErrorReporter *errorreport, std::map< std::string, std::shared_ptr< VariableBlock >> *predefined=nullptr)
Definition: NamedVars.cpp:612
hosts one or more VariableBlocks keeping only one name for all of them
Definition: NamedVars.h:27
DLLEXPORT std::shared_ptr< NamedVariableList > GetValueDirect(const std::string &name) const
Definition: NamedVars.cpp:1084
std::unique_ptr< RStrType > GetStringInBracketsRecursive(int specialflags=0)
Gets characters inside brackets.
Non-template class for working with all types of DataBlocks.
Definition: DataBlock.h:425
DLLEXPORT bool SetValue(const std::string &name, const VariableBlock &value1)
Definition: NamedVars.cpp:899
void SkipWhiteSpace(int specialflags=0)
Skips until characters that are not whitespace are found.
DLLEXPORT NamedVars()
Definition: NamedVars.cpp:781
DLLEXPORT VariableBlock & GetValue()
Definition: NamedVars.cpp:462
DLLEXPORT const VariableBlock * GetValue(const std::string &name) const
Definition: NamedVars.cpp:974
DLLEXPORT std::vector< VariableBlock * > & GetValues()
Definition: NamedVars.cpp:776
DLLEXPORT std::string Serialize(const std::string &lineprefix="") const
Serializes this object into a string representation.
Definition: NamedVars.cpp:1117
DLLEXPORT void Remove(size_t index)
Definition: NamedVars.cpp:1215
STL namespace.
DLLEXPORT bool operator==(const NamedVariableList &other) const
Definition: NamedVars.cpp:586
DLLEXPORT void SetValue(const VariableBlock &value1)
Definition: NamedVars.cpp:389
DLLEXPORT int GetVariableType() const
Definition: NamedVars.cpp:758
size_t Find(const std::string &name) const
Definition: NamedVars.h:367
std::string GetName() const
Definition: DataBlock.h:813
bool AddScriptCompatibleValue(ScriptSafeVariableBlock *value)
Definition: NamedVars.cpp:1283
DLLEXPORT size_t GetVariableCount() const
Returns the size of the internal variable vector.
Definition: NamedVars.cpp:1304
#define SAFE_DELETE_VECTOR(x)
Definition: Define.h:123
DLLEXPORT size_t GetVariableCount() const
Definition: NamedVars.cpp:733
#define DATABLOCK_TYPE_WSTRING
Definition: DataBlock.h:25
DLLEXPORT std::string ToText(int WhichSeparator=0, bool AddAllBrackets=false) const
Definition: NamedVars.cpp:490
std::unique_ptr< RStrType > GetUntilEqualityAssignment(EQUALITYCHARACTER stopcase, int specialflags=0)
Gets the string that is before the equality assignment.
DLLEXPORT void SetVec(std::vector< std::shared_ptr< NamedVariableList >> &vec)
Definition: NamedVars.cpp:1250
DLLEXPORT bool CompareName(const std::string &name) const
Definition: NamedVars.cpp:485
DLLEXPORT VariableBlock * GetValueDirect()
Definition: NamedVars.cpp:718
std::unique_ptr< RStrType > GetUntilNextCharacterOrAll(int charactertolookfor, int specialflags=0)
Gets characters until a character or all remaining characters.
virtual DLLEXPORT void Print(LErrorReporter *errorreport) const noexcept
Definition: Exceptions.cpp:41
DLLEXPORT bool LoadVarsFromFile(const std::string &file, LErrorReporter *errorreport)
Definition: NamedVars.cpp:1241
Reference counted version for scripts of VariableBlock.
Definition: DataBlock.h:840
DLLEXPORT bool Add(std::shared_ptr< NamedVariableList > value)
Adds a value.
Definition: NamedVars.cpp:883
Iterator class for getting parts of a string.
DLLEXPORT std::string GetName(size_t index)
Definition: NamedVars.cpp:1155
FORCE_INLINE void Release()
removes a reference and deletes the object if reference count reaches zero
DLLEXPORT int GetCommonType() const
Definition: NamedVars.cpp:738
#define DATABLOCK_TYPE_STRING
Definition: DataBlock.h:26
ScriptSafeVariableBlock * GetScriptCompatibleValue(const std::string &name)
Finds and returns the first value in a list matching name.
Definition: NamedVars.cpp:1267
DLLEXPORT ~NamedVars()
Definition: NamedVars.cpp:832
bool IsValid() const
Definition: DataBlock.h:511
DLLEXPORT void AddVar(NamedVariableList *newvaluetoadd)
Definition: NamedVars.cpp:1198
DLLEXPORT void AddDataToPacket(sf::Packet &packet) const
Writes this NamedVars to a packet.
Definition: NamedVars.cpp:866
static std::string ToString(const T &val)
Definition: Convert.h:72
DLLEXPORT NamedVariableList & operator=(const NamedVariableList &other)
Definition: NamedVars.cpp:569
DLLEXPORT int GetVariableType(const std::string &name) const
Definition: NamedVars.cpp:1131
DLLEXPORT void RemoveIfExists(const std::string &name, Lock &guard)
Removes a value with the given name if it exists.
Definition: NamedVars.cpp:1229
DLLEXPORT bool GetValues(const std::string &name, std::vector< const VariableBlock *> &receiver) const
Definition: NamedVars.cpp:1062
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void PushValue(std::unique_ptr< VariableBlock > &&value)
Adds a new value.
Definition: NamedVars.cpp:457
DLLEXPORT void AddDataToPacket(sf::Packet &packet) const
For passing NamedVariableLists to other instances through the network.
Definition: NamedVars.cpp:354
DLLEXPORT bool CompareName(size_t index, const std::string &name) const
Definition: NamedVars.cpp:1183
std::unique_ptr< RStrType > GetUntilNextCharacterOrNothing(int charactertolookfor, int specialflags=0)
Gets characters until a character or nothing if the specified character is not found.
#define DATABLOCK_TYPE_ERROR
Definition: DataBlock.h:31
virtual void Error(const std::string &Text)=0
DLLEXPORT VariableBlock & operator[](const int &nindex)
Definition: NamedVars.cpp:770
DLLEXPORT NamedVariableList * GetValueDirectRaw(const std::string &name) const
Definition: NamedVars.cpp:1096
static DLLEXPORT bool LoadDataDump(const std::string &file, std::vector< std::shared_ptr< NamedVariableList >> &vec, LErrorReporter *errorreport)
Definition: FileSystem.cpp:308
DLLEXPORT void SetName(const std::string &name)
Definition: NamedVars.cpp:480
#define DLLEXPORT
Definition: Include.h:115
#define DATABLOCK_TYPE_BOOL
Definition: DataBlock.h:24
DLLEXPORT void SetName(Lock &guard, size_t index, const std::string &name)
Definition: NamedVars.cpp:1170
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:116
DLLEXPORT bool RecursiveParseList(std::vector< VariableBlock *> &resultvalues, std::unique_ptr< std::string > expression, LErrorReporter *errorreport, std::map< std::string, std::shared_ptr< VariableBlock >> *predefined)
Handles a found bracket expression "[...]" parsing it recursively into values.
Definition: NamedVars.cpp:134
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
DLLEXPORT std::vector< std::shared_ptr< NamedVariableList > > * GetVec()
Definition: NamedVars.cpp:1246
#define DATABLOCK_TYPE_CHAR
Definition: DataBlock.h:27
std::string GetName() const
Definition: NamedVars.h:139
#define GUARD_LOCK()
Definition: ThreadSafe.h:97
DLLEXPORT bool ConstructValuesForObject(const std::string &variablestr, LErrorReporter *errorreport, std::map< std::string, std::shared_ptr< VariableBlock >> *predefined)
Helper function for constructing values.
Definition: NamedVars.cpp:235
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:16
DLLEXPORT int GetVariableTypeOfAll(const std::string &name) const
Definition: NamedVars.cpp:1143
DLLEXPORT bool operator!=(const NamedVariableList &other) const
Definition: NamedVars.cpp:606