Leviathan  0.8.0.0
Leviathan game engine
Leviathan::ObjectFileProcessor Class Reference

Static class for handling ObjectFiles. More...

#include <ObjectFileProcessor.h>

Public Member Functions

 ObjectFileProcessor ()=delete
 
 ~ObjectFileProcessor ()=delete
 

Static Public Member Functions

static DLLEXPORT void Initialize ()
 
static DLLEXPORT void Release ()
 
static DLLEXPORT std::unique_ptr< ObjectFileProcessObjectFile (const std::string &file, LErrorReporter *reporterror)
 Reads an ObjectFile to an in-memory data structure. More...
 
static DLLEXPORT std::unique_ptr< ObjectFileProcessObjectFileFromString (const std::string &filecontents, const std::string &filenameforerrors, LErrorReporter *reporterror)
 
static DLLEXPORT bool WriteObjectFile (ObjectFile &data, const std::string &file, LErrorReporter *reporterror)
 Writes an ObjectFile's data structure to a file. More...
 
static DLLEXPORT bool SerializeObjectFile (ObjectFile &data, std::string &receiver)
 Serializes an ObjectFile object into a string. More...
 
static DLLEXPORT void RegisterValue (const std::string &name, VariableBlock *valuetokeep)
 Registers a new value alias for the processor. More...
 
template<class T >
static bool LoadValueFromNamedVars (NamedVars *block, const std::string &varname, T &receiver, const T &defaultvalue, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 
template<class T >
static FORCE_INLINE bool LoadValueFromNamedVars (NamedVars &block, const std::string &varname, T &receiver, const T &defaultvalue, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 
template<class RType , class SingleType , int VarCount>
static void LoadMultiPartValueFromNamedVars (NamedVars *block, const std::string &varname, RType &receiver, const RType &defaultvalue, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 
template<class RType , class SingleType , int VarCount>
static bool LoadMultiPartValueFromNamedVariableList (NamedVariableList *block, int &valuestartindex, RType &receiver, const RType &defaultvalue, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 
template<class RType , class SingleType , int VarCount>
static FORCE_INLINE void LoadMultiPartValueFromNamedVars (NamedVars &block, const std::string &varname, RType &receiver, const RType &defaultvalue, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 
template<class T >
static bool LoadVectorOfTypeUPtrFromNamedVars (NamedVars &block, const std::string &varname, std::vector< std::unique_ptr< T >> &receiver, size_t mustbedivisableby=1, LErrorReporter *ReportError=nullptr, const std::string &errorprefix="")
 Loads a vector of type from a NamedVars. More...
 

Detailed Description

Static class for handling ObjectFiles.

Definition at line 14 of file ObjectFileProcessor.h.

Constructor & Destructor Documentation

◆ ObjectFileProcessor()

Leviathan::ObjectFileProcessor::ObjectFileProcessor ( )
delete

◆ ~ObjectFileProcessor()

Leviathan::ObjectFileProcessor::~ObjectFileProcessor ( )
delete

Member Function Documentation

◆ Initialize()

void Leviathan::ObjectFileProcessor::Initialize ( )
static

Definition at line 55 of file ObjectFileProcessor.cpp.

55  {
56 #if defined(_DEBUG) && !defined(NO_DEFAULT_DATAINDEX)
57  // Just out of curiosity check this //
58  auto iter = RegisteredValues.find("DATAINDEX_TICKTIME");
59 
60  if(iter == RegisteredValues.end()){
61 
62  LOG_FATAL("ObjectFileProcessor: RegisteredValues are messed up, "
63  "DATAINDEX_TICKTIME is not defined, check the macros!");
64 
65  return;
66  }
67 #endif // _DEBUG
68 }
#define LOG_FATAL(x)
Definition: Define.h:92

◆ LoadMultiPartValueFromNamedVariableList()

template<class RType , class SingleType , int VarCount>
static bool Leviathan::ObjectFileProcessor::LoadMultiPartValueFromNamedVariableList ( NamedVariableList block,
int &  valuestartindex,
RType &  receiver,
const RType &  defaultvalue,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Definition at line 114 of file ObjectFileProcessor.h.

117  {
118  // make sure that size is right and types are correct //
119  if(block->GetVariableCount()-valuestartindex < VarCount ||
120  !block->CanAllBeCastedToType<SingleType>(
121  valuestartindex, valuestartindex+VarCount-1))
122  {
123  // not enough values / wrong types //
124  if(ReportError){
125  ReportError->Error(errorprefix+" invalid variable "+block->GetName()+
126  ", not enough values ("+Convert::ToString<int>(VarCount)+
127  " needed) or wrong types");
128  }
129  // set as default //
130  receiver = defaultvalue;
131  return false;
132  }
133 
134  // iterate over how many are wanted and assign //
135  for(int i = 0; i < VarCount; i++){
136 
137  // convert and set //
138  receiver[i] = (SingleType)block->GetValue(valuestartindex+i);
139  }
140 
141  // values copied //
142  // increment the index before returning //
143  valuestartindex += VarCount;
144 
145  return true;
146  }
virtual void Error(const std::string &Text)=0

◆ LoadMultiPartValueFromNamedVars() [1/2]

template<class RType , class SingleType , int VarCount>
static void Leviathan::ObjectFileProcessor::LoadMultiPartValueFromNamedVars ( NamedVars block,
const std::string &  varname,
RType &  receiver,
const RType &  defaultvalue,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Definition at line 88 of file ObjectFileProcessor.h.

91  {
92  // get pointer to value list //
93  std::shared_ptr<NamedVariableList> curvalues = block->GetValueDirect(varname);
94 
95  if(curvalues.get() == NULL){
96 
97  // not found //
98  if(ReportError)
99  ReportError->Error(errorprefix+" invalid variable "+varname+", not found");
100 
101  // set as default //
102  receiver = defaultvalue;
103  return;
104  }
105 
106  // call assigning function //
107  int varindex = 0;
108  LoadMultiPartValueFromNamedVariableList<RType, SingleType, VarCount>(curvalues.get(),
109  varindex, receiver, defaultvalue, ReportError, errorprefix);
110 
111  }
virtual void Error(const std::string &Text)=0

◆ LoadMultiPartValueFromNamedVars() [2/2]

template<class RType , class SingleType , int VarCount>
static FORCE_INLINE void Leviathan::ObjectFileProcessor::LoadMultiPartValueFromNamedVars ( NamedVars block,
const std::string &  varname,
RType &  receiver,
const RType &  defaultvalue,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Definition at line 150 of file ObjectFileProcessor.h.

153  {
154  return LoadMultiPartValueFromNamedVars<RType, SingleType, VarCount>(&block,
155  varname, receiver, defaultvalue, ReportError, errorprefix);
156  }

◆ LoadValueFromNamedVars() [1/2]

template<class T >
static bool Leviathan::ObjectFileProcessor::LoadValueFromNamedVars ( NamedVars block,
const std::string &  varname,
T &  receiver,
const T &  defaultvalue,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Definition at line 56 of file ObjectFileProcessor.h.

59  {
60  // try to get value and convert to receiver //
61  if(!block->GetValueAndConvertTo<T>(varname, receiver)){
62  // variable not found / wrong type //
63  // report error if wanted //
64  if(ReportError)
65  ReportError->Error(errorprefix+" invalid variable "+varname+
66  ", not found/wrong type");
67 
68  // set value to provided default //
69  receiver = defaultvalue;
70 
71  return false;
72  }
73  return true;
74  }
virtual void Error(const std::string &Text)=0

◆ LoadValueFromNamedVars() [2/2]

template<class T >
static FORCE_INLINE bool Leviathan::ObjectFileProcessor::LoadValueFromNamedVars ( NamedVars block,
const std::string &  varname,
T &  receiver,
const T &  defaultvalue,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Definition at line 78 of file ObjectFileProcessor.h.

81  {
82  return LoadValueFromNamedVars<T>(&block, varname, receiver, defaultvalue,
83  ReportError, errorprefix);
84  }

◆ LoadVectorOfTypeUPtrFromNamedVars()

template<class T >
static bool Leviathan::ObjectFileProcessor::LoadVectorOfTypeUPtrFromNamedVars ( NamedVars block,
const std::string &  varname,
std::vector< std::unique_ptr< T >> &  receiver,
size_t  mustbedivisableby = 1,
LErrorReporter ReportError = nullptr,
const std::string &  errorprefix = "" 
)
inlinestatic

Loads a vector of type from a NamedVars.

Definition at line 161 of file ObjectFileProcessor.h.

165  {
166  NamedVariableList* inanimlist = block.GetValueDirectRaw(varname);
167 
168  if(inanimlist && inanimlist->GetVariableCount() && inanimlist->GetVariableCount() %
169  mustbedivisableby == 0 &&
170  inanimlist->CanAllBeCastedToType<T>())
171  {
172 
173  receiver.reserve(inanimlist->GetVariableCount());
174 
175  for(size_t i = 0; i < inanimlist->GetVariableCount(); i++){
176 
177  const T tmpresult =
178  inanimlist->GetValueDirect(i)->ConvertAndReturnVariable<T>();
179 
180  receiver.push_back(std::move(std::unique_ptr<T>(new T(tmpresult))));
181  }
182 
183  return true;
184  }
185 
186  // Something isn't right //
187  if(ReportError)
188  ReportError->Error(errorprefix+" invalid variable list "+varname+
189  ", not found/wrong type/wrong amount");
190  return false;
191  }
virtual void Error(const std::string &Text)=0

◆ ProcessObjectFile()

DLLEXPORT std::unique_ptr< ObjectFile > Leviathan::ObjectFileProcessor::ProcessObjectFile ( const std::string &  file,
LErrorReporter reporterror 
)
static

Reads an ObjectFile to an in-memory data structure.

Definition at line 90 of file ObjectFileProcessor.cpp.

92 {
93  // First read the file entirely //
94  std::string filecontents;
95 
96  if (!FileSystem::ReadFileEntirely(file, filecontents)) {
97 
98  reporterror->Error("ObjectFileProcessor: ProcessObjectFile: file could not be read: " +
99  file);
100  return nullptr;
101  }
102 
103  // Skip empty files //
104  if(filecontents.size() == 0){
105 
106  return nullptr;
107  }
108 
109  // Skip the BOM if there is one //
110  if(utf8::starts_with_bom(filecontents.begin(), filecontents.end())){
111 
112  // Pop the first 3 bytes //
113  filecontents = filecontents.substr(3, filecontents.size()-3);
114  }
115 
116  return ProcessObjectFileFromString(filecontents, file, reporterror);
117 }
static DLLEXPORT std::unique_ptr< ObjectFile > ProcessObjectFileFromString(const std::string &filecontents, const std::string &filenameforerrors, LErrorReporter *reporterror)
bool starts_with_bom(octet_iterator it, octet_iterator end)
Definition: core.h:306
virtual void Error(const std::string &Text)=0
static DLLEXPORT bool ReadFileEntirely(const std::string &file, std::string &resultreceiver)
Definition: FileSystem.cpp:538

◆ ProcessObjectFileFromString()

DLLEXPORT std::unique_ptr< Leviathan::ObjectFile > ObjectFileProcessor::ProcessObjectFileFromString ( const std::string &  filecontents,
const std::string &  filenameforerrors,
LErrorReporter reporterror 
)
static

Definition at line 120 of file ObjectFileProcessor.cpp.

123 {
124  // Create the target object //
125  auto ofile = std::make_unique<ObjectFile>();
126 
127  bool succeeded = true;
128 
129  // Create an UTF8 supporting iterator //
130  StringIterator itr(std::make_unique<UTF8PointerDataIterator>(filecontents));
131 
132  while(!itr.IsOutOfBounds()){
133 
134  // First get the first thing defining what the following object/thing will be //
135  auto thingtype = itr.GetNextCharacterSequence<std::string>(
138 
139  // Empty line
140  if(!thingtype)
141  continue;
142 
143  // Store the starting line for error reporting purposes //
144  size_t thisstart = itr.GetCurrentLine();
145 
146  if(*thingtype == "template") {
147  // Either a template definition or a template instantiation //
148 
149  if(!TryToHandleTemplate(filenameforerrors, itr, *ofile, *thingtype, reporterror)){
150 
151  LogError("processing a template definitions or instantiation has failed",
152  filenameforerrors, thisstart, reporterror);
153 
154  succeeded = false;
155  break;
156  }
157 
158  continue;
159 
160  } else if(*thingtype == "o"){
161 
162  // Process an object //
163  auto tmpobj = TryToLoadObject(filenameforerrors, itr, *ofile, *thingtype,
164  reporterror);
165 
166  if(!tmpobj){
167 
168  LogError("processing an object has failed",
169  filenameforerrors, thisstart, reporterror);
170 
171  succeeded = false;
172  break;
173  }
174 
175  if(!ofile->AddObject(tmpobj)){
176 
177  LogError("object has a conflicting name, name: \"" + tmpobj->GetName() +
178  "\"",
179  filenameforerrors, thisstart, reporterror);
180 
181  succeeded = false;
182  break;
183  }
184 
185 
186  continue;
187 
188  } else{
189  // It should be a named variable //
190 
191  auto ptr = TryToLoadNamedVariables(filenameforerrors, itr, *thingtype, reporterror);
192  if(!ptr){
193 
194  LogError("processing a NamedVariableList has failed",
195  filenameforerrors, thisstart, reporterror);
196 
197  succeeded = false;
198  break;
199  }
200 
201  // Add to the object //
202  if(!ofile->AddNamedVariable(ptr)){
203 
204  LogError("variable name (\"" + ptr->GetName() + "\") already in use",
205  filenameforerrors, thisstart, reporterror);
206 
207  succeeded = false;
208  break;
209  }
210 
211  continue;
212  }
213 
214  // It is something that cannot be handled //
215  LogError("ObjectFile has an invalid/unknown block (" + *thingtype + ")",
216  filenameforerrors, thisstart, reporterror);
217 
218  // The file is clearly malformed //
219  succeeded = false;
220  break;
221  }
222 
223 
224  if(!succeeded || !itr.IsOutOfBounds()){
225 
226  // It failed //
227  LogError("parsing file failed. Parsing ended",
228  filenameforerrors, itr.GetCurrentLine(), reporterror);
229 
230  // Notify about unended strings and comments //
231 
232  if(itr.IsInsideString()){
233  LogError("parsing ended inside unclosed quotes",
234  filenameforerrors, itr.GetCurrentLine(), reporterror);
235  }
236 
237  if(itr.IsInsideComment()){
238  LogError("parsing ended inside unclosed comment",
239  filenameforerrors, itr.GetCurrentLine(), reporterror);
240  }
241 
242  return nullptr;
243  }
244 
245  // Generate the template instantiations and it's done //
246  if(!ofile->GenerateTemplatedObjects(reporterror)){
247 
248  LogError("file has invalid templates (either bad names, "
249  "or instances without definitions)",
250  filenameforerrors, itr.GetCurrentLine(), reporterror);
251 
252  return nullptr;
253  }
254 
255  return ofile;
256 }
Iterator class for getting parts of a string.
#define SPECIAL_ITERATOR_FILEHANDLING
Common flag for file handling.
void LogError(const TStr &msgStart, const std::string &file, TLineType line, LErrorReporter *reporterror)

◆ RegisterValue()

DLLEXPORT void Leviathan::ObjectFileProcessor::RegisterValue ( const std::string &  name,
VariableBlock valuetokeep 
)
static

Registers a new value alias for the processor.

Warning
Calling this while files are being parsed will cause undefined behavior

Definition at line 74 of file ObjectFileProcessor.cpp.

76 {
77  RegisteredValues[name] = std::shared_ptr<VariableBlock>(valuetokeep);
78 }

◆ Release()

void Leviathan::ObjectFileProcessor::Release ( )
static

Definition at line 69 of file ObjectFileProcessor.cpp.

69  {
70  // Release our allocated memory //
71  RegisteredValues.clear();
72 }

◆ SerializeObjectFile()

DLLEXPORT bool Leviathan::ObjectFileProcessor::SerializeObjectFile ( ObjectFile data,
std::string &  receiver 
)
static

Serializes an ObjectFile object into a string.

The string can be written to a file and later parsed to get the ObjectFile object back

Parameters
receiverThe generated text will be appended to this string
Returns
True if succeeds, false if the object failed to be serialized for some reason

Definition at line 1050 of file ObjectFileProcessor.cpp.

1052 {
1053 
1054  // Header variables //
1055  for (size_t i = 0; i < data.GetVariables()->GetVariableCount(); ++i){
1056 
1057  const auto* variable = data.GetVariables()->GetValueDirectRaw(i);
1058 
1059  receiver += variable->ToText() + "\n";
1060  }
1061 
1062  receiver += "\n";
1063 
1064  // Template definitions //
1065  for (size_t i = 0; i < data.GetTemplateDefinitionCount(); ++i){
1066 
1067  std::shared_ptr<ObjectFileTemplateDefinition> object = data.GetTemplateDefinition(i);
1068 
1069  LEVIATHAN_ASSERT(object, "GetTemplateDefinition iteration invalid");
1070 
1071  receiver += object->Serialize();
1072  }
1073 
1074  // Objects //
1075  for (size_t i = 0; i < data.GetTotalObjectCount(); ++i){
1076 
1077  std::shared_ptr<ObjectFileObject> object = data.GetObject(i);
1078 
1079  LEVIATHAN_ASSERT(object, "GetObject iteration invalid");
1080 
1081  if(object->IsThisTemplated())
1082  continue;
1083 
1084  receiver += object->Serialize();
1085  }
1086 
1087  // Template instantiations //
1088  for (size_t i = 0; i < data.GetTemplateInstanceCount(); ++i){
1089 
1090  std::shared_ptr<ObjectFileTemplateInstance> object = data.GetTemplateInstance(i);
1091 
1092  LEVIATHAN_ASSERT(object, "GetTemplateInstance iteration invalid");
1093 
1094  receiver += object->Serialize();
1095  }
1096 
1097  receiver += "\n";
1098  return true;
1099 }
DLLEXPORT size_t GetTemplateInstanceCount() const
Definition: ObjectFile.h:473
DLLEXPORT size_t GetVariableCount() const
Returns the size of the internal variable vector.
Definition: NamedVars.cpp:1304
DLLEXPORT std::shared_ptr< ObjectFileObject > GetObject(size_t index)
Definition: ObjectFile.h:464
DLLEXPORT std::string ToText(int WhichSeparator=0, bool AddAllBrackets=false) const
Definition: NamedVars.cpp:490
DLLEXPORT std::shared_ptr< ObjectFileTemplateInstance > GetTemplateInstance(size_t index)
Definition: ObjectFile.h:479
DLLEXPORT size_t GetTotalObjectCount() const
Gets the total number of objects (objects + template instances)
Definition: ObjectFile.h:414
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98
DLLEXPORT std::shared_ptr< ObjectFileTemplateDefinition > GetTemplateDefinition(size_t index)
Definition: ObjectFile.h:455
DLLEXPORT NamedVariableList * GetValueDirectRaw(const std::string &name) const
Definition: NamedVars.cpp:1096
DLLEXPORT NamedVars * GetVariables()
Returns a raw pointer to HeaderVars.
Definition: ObjectFile.cpp:70
DLLEXPORT size_t GetTemplateDefinitionCount() const
Definition: ObjectFile.h:449

◆ WriteObjectFile()

DLLEXPORT bool Leviathan::ObjectFileProcessor::WriteObjectFile ( ObjectFile data,
const std::string &  file,
LErrorReporter reporterror 
)
static

Writes an ObjectFile's data structure to a file.

Warning
Using the process and this function will erase ALL comments, which is not optimal for config files. It is recommended to only append to an existing file to keep comments intact
Returns
True when the file has been written, false if something failed

Definition at line 1034 of file ObjectFileProcessor.cpp.

1036 {
1037  std::string datatowrite;
1038 
1039  if(!SerializeObjectFile(data, datatowrite)){
1040 
1041  reporterror->Error("WriteObjectFile: failed to serialize data into a std::string");
1042  return false;
1043  }
1044 
1045  FileSystem::WriteToFile(datatowrite, file);
1046 
1047  return true;
1048 }
static DLLEXPORT bool SerializeObjectFile(ObjectFile &data, std::string &receiver)
Serializes an ObjectFile object into a string.
virtual void Error(const std::string &Text)=0
static DLLEXPORT bool WriteToFile(const std::string &data, const std::string &filename)
Definition: FileSystem.cpp:456

The documentation for this class was generated from the following files: