diff --git a/MAGE/FPS/res/output.txt b/MAGE/FPS/res/output.txt new file mode 100644 index 000000000..b743a6efc --- /dev/null +++ b/MAGE/FPS/res/output.txt @@ -0,0 +1,10 @@ +#begin +a_true_bool bool true +a_false_bool bool false +an_integer int 5 +a_float float 5.001000 +a_float3 float3 1.010000 2.020000 3.030000 +a_float4 float4 4.010000 5.020000 6.030000 7.040000 +a_colour colour 8.010000 9.020000 10.030000 11.040000 +a_string string "test" +#end \ No newline at end of file diff --git a/MAGE/FPS/res/script_test.txt b/MAGE/FPS/res/script_test.txt new file mode 100644 index 000000000..265e2b8e9 --- /dev/null +++ b/MAGE/FPS/res/script_test.txt @@ -0,0 +1,14 @@ + +#begin + +a_true_bool bool true +a_false_bool bool false + +an_integer int 5 +a_float float 5.001 +a_float3 float3 1.01 2.02 3.03 +a_float4 float4 4.01 5.02 6.03 7.04 +a_colour colour 8.01 9.02 10.03 11.04 +a_string string "test" + +#end \ No newline at end of file diff --git a/MAGE/FPS/src/core/FPS.cpp b/MAGE/FPS/src/core/FPS.cpp index ee1602e06..bad5c4eae 100644 --- a/MAGE/FPS/src/core/FPS.cpp +++ b/MAGE/FPS/src/core/FPS.cpp @@ -8,7 +8,11 @@ using namespace mage; class TestState : public State { virtual void Update(double elapsed_time) { if (g_engine->GetInput()->GetKeyPress(DIK_Q)) { - PostQuitMessage(0); + //PostQuitMessage(0); + + Script s("script_test.txt", "C:/Users/Matthias/Documents/Visual Studio 2015/Projects/MAGE/MAGE/FPS/res/"); + s.SaveScript("C:/Users/Matthias/Documents/Visual Studio 2015/Projects/MAGE/MAGE/FPS/res/output.txt"); + } }; }; diff --git a/MAGE/MAGE/src/resource/resource.hpp b/MAGE/MAGE/src/resource/resource.hpp index 316fba054..363c70fa8 100644 --- a/MAGE/MAGE/src/resource/resource.hpp +++ b/MAGE/MAGE/src/resource/resource.hpp @@ -53,7 +53,7 @@ namespace mage { @return The filename of this resource. */ const string GetFilename() const { - return m_name + m_path; + return m_path + m_name; } private: diff --git a/MAGE/MAGE/src/scripting/script.cpp b/MAGE/MAGE/src/scripting/script.cpp index 126c938bc..9085d8e7d 100644 --- a/MAGE/MAGE/src/scripting/script.cpp +++ b/MAGE/MAGE/src/scripting/script.cpp @@ -1,12 +1,3 @@ -//----------------------------------------------------------------------------- -// System Includes -//----------------------------------------------------------------------------- -#pragma region - -#include - -#pragma endregion - //----------------------------------------------------------------------------- // Engine Includes //----------------------------------------------------------------------------- @@ -82,9 +73,9 @@ namespace mage { const Variable *next = it.Next(); const char *name = next->GetName().c_str(); const void *raw_value = next->GetValue(); - const char *type_name = typeid(raw_value).name(); - if (strcmp(type_name, "Pb") == 0) { + switch (next->GetType()) { + case BoolType: { const bool *value = (bool *)raw_value; if (*value) { sprintf_s(output, sizeof(output), "%s bool true", name); @@ -92,52 +83,76 @@ namespace mage { else { sprintf_s(output, sizeof(output), "%s bool false", name); } + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, "Pi") == 0) { + case IntType: { const int *value = (int *)raw_value; sprintf_s(output, sizeof(output), "%s int %d", name, *value); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, "Ff") == 0) { + case FloatType: { const float *value = (float *)raw_value; sprintf_s(output, sizeof(output), "%s float %f", name, *value); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, typeid(float3 *).name()) == 0) { + case Float3Type: { const float3 *value = (float3 *)raw_value; sprintf_s(output, sizeof(output), "%s float3 %f %f %f", name, value->x, value->y, value->z); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, typeid(float4 *).name()) == 0) { + case Float4Type: { const float4 *value = (float4 *)raw_value; sprintf_s(output, sizeof(output), "%s float4 %f %f %f %f", name, value->x, value->y, value->z, value->w); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, typeid(colour *).name()) == 0) { + case ColourType: { const colour *value = (colour *)raw_value; sprintf_s(output, sizeof(output), "%s colour %f %f %f %f", name, value->x, value->y, value->z, value->w); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, "PSs") == 0) { + case StringType: { const string *value = (string *)raw_value; - sprintf_s(output, sizeof(output), "%s string %s", name, value->c_str()); + sprintf_s(output, sizeof(output), "%s string \"%s\"", name, value->c_str()); + fputs(output, file); + fputs("\n", file); + break; } - else if (strcmp(type_name, "Pv") == 0) { + case UnknownType: { const char *value = (char *)raw_value; sprintf_s(output, sizeof(output), "%s unknown %s", name, value); + fputs(output, file); + fputs("\n", file); + break; } - else { + default: { Warning("Could not export variable: %s", name); - continue; } - - fputs(output, file); - fputs("\n", file); + } } // Write the #end statement to the file. fputs("#end", file); + + // Close the script file. + fclose(file); } - void Script::ImportVariable(const string &variable_name, FILE *file) { + void Script::ImportVariable(const string &name, FILE *file) { // Ensure the file pointer is valid. if (file == NULL) { - Warning("Could not import variable: %s", variable_name); + Warning("Could not import variable: %s", name); return; } @@ -151,21 +166,21 @@ namespace mage { bool *value = new bool; fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); *value = (strcmp(buffer, "true") == 0) ? true : false; - AddVariable(variable_name, value); + AddVariable(name, BoolType, value); } else if (strcmp(buffer, "int") == 0) { // The variable is an int. int *value = new int; fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); *value = atoi(buffer); - AddVariable(variable_name, value); + AddVariable(name, IntType, value); } else if (strcmp(buffer, "float") == 0) { // The variable is a float. float *value = new float; fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); *value = (float)atof(buffer); - AddVariable(variable_name, value); + AddVariable(name, FloatType, value); } else if (strcmp(buffer, "float3") == 0) { // The variable is a float3. @@ -176,7 +191,7 @@ namespace mage { value->y = (float)atof(buffer); fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); value->z = (float)atof(buffer); - AddVariable(variable_name, value); + AddVariable(name, Float3Type, value); } else if (strcmp(buffer, "float4") == 0) { // The variable is a float4. @@ -189,7 +204,7 @@ namespace mage { value->z = (float)atof(buffer); fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); value->w = (float)atof(buffer); - AddVariable(variable_name, value); + AddVariable(name, Float4Type, value); } else if (strcmp(buffer, "colour") == 0) { // The variable is a colour. @@ -202,7 +217,7 @@ namespace mage { value->z = (float)atof(buffer); fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); value->w = (float)atof(buffer); - AddVariable(variable_name, value); + AddVariable(name, ColourType, value); } else if (strcmp(buffer, "string") == 0) { // The variable is a string. @@ -261,25 +276,25 @@ namespace mage { } while (commas_found == true); const string *value = new string(complete_string); - AddVariable(variable_name, value); + AddVariable(name, StringType, value); } else { // The variable has an unknown type. char *value = new char[strlen(buffer) + 1]; fscanf_s(file, "%s", buffer, (unsigned int)sizeof(buffer)); strcpy_s(value, sizeof(value), buffer); - AddVariable(variable_name, (void *)value); + AddVariable(name, UnknownType, (void *)value); } } - bool Script::RemoveVariable(const string &variable_name) { + bool Script::RemoveVariable(const string &name) { Variable *target = NULL; // Iterate the states looking for the specified variable. LinkedList< Variable >::LinkedListIterator it = m_variables->GetIterator(); while (it.HasNext()) { Variable *next = it.Next(); - if (next->GetName() == variable_name) { + if (next->GetName() == name) { target = next; break; } @@ -295,12 +310,12 @@ namespace mage { } template < typename T > - const T *Script::GetValueOfVariable(const string &variable_name) const { + const T *Script::GetValueOfVariable(const string &name) const { // Iterate the states looking for the specified variable. LinkedList< Variable >::LinkedListIterator it = m_variables->GetIterator(); while (it.HasNext()) { const Variable *next = it.Next(); - if (next->GetName() == variable_name) { + if (next->GetName() == name) { return (T *)next->GetValue(); } } @@ -309,10 +324,28 @@ namespace mage { } template < typename T > - void Script::SetValueOfVariable(const string &variable_name, const T *value) { - if (RemoveVariable(variable_name)) { - // Readd the variable with a new value. - AddVariable(variable_name, value); + void Script::SetValueOfVariable(const string &name, const T *value) { + Variable *target = NULL; + + // Iterate the states looking for the specified variable. + LinkedList< Variable >::LinkedListIterator it = m_variables->GetIterator(); + while (it.HasNext()) { + Variable *next = it.Next(); + if (next->GetName() == name) { + target = next; + break; + } + } + + if (target == NULL) { + return; } + + // Get type. + const VariableType type = target->GetType(); + // Remove the variable + m_variables->Remove(&target); + // Readd the variable with a new value. + AddVariable(name, type, value); } } \ No newline at end of file diff --git a/MAGE/MAGE/src/scripting/script.hpp b/MAGE/MAGE/src/scripting/script.hpp index 7a85f08c8..0ae977d7a 100644 --- a/MAGE/MAGE/src/scripting/script.hpp +++ b/MAGE/MAGE/src/scripting/script.hpp @@ -40,70 +40,72 @@ namespace mage { /** Import the given variable from the given file to this script . - @pre No variable with the name @a variable_name + @pre No variable with the name @a name exists in this script. - @param[in] variable_name + @param[in] name The name of the variable. @param[in, out] file A pointer to a file containing the value of the variable. */ - void ImportVariable(const string &variable_name, FILE *file); + void ImportVariable(const string &name, FILE *file); /** Adds the given variable to this script. - @pre No variable with the name @a variable_name + @pre No variable with the name @a name exists in this script. @tparam T The type of the value. - @param[in] variable_name + @param[in] name The name of the variable. + @param[in] type + The type of the variable. @param[in] value A pointer to the value of the variable. */ template < typename T > - void AddVariable(const string &variable_name, const T *value) { - m_variables->Add(new Variable(variable_name, value)); + void AddVariable(const string &name, VariableType type, const T *value) { + m_variables->Add(new Variable(name, type, (void *)value)); } /** Removes the given variable from this script. - @param[in] variable_name + @param[in] name The name of the variable. - @return @c true if a variable with the name @a variable_name + @return @c true if a variable with the name @a name exists in this script prior to removal. */ - bool RemoveVariable(const string &variable_name); + bool RemoveVariable(const string &name); /** Returns the value of the given variable in this script. @tparam T The type of the value. - @param[in] variable_name + @param[in] name The name of the variable. - @return @c NULL if no variable with the name @a variable_name + @return @c NULL if no variable with the name @a name exists in this script. @return A pointer to the value of the variable. */ template < typename T > - const T *GetValueOfVariable(const string &variable_name) const; + const T *GetValueOfVariable(const string &name) const; /** Sets the value of the given variable in this script. @tparam T The type of the value. - @param[in] variable_name + @param[in] name The name of the variable. @param[in] value A pointer to the value of the variable. - @note Nothing happens if no variable with the name @a variable_name + @note Nothing happens if no variable with the name @a name exists in this script. */ template < typename T > - void SetValueOfVariable(const string &variable_name, const T *value); + void SetValueOfVariable(const string &name, const T *value); private: diff --git a/MAGE/MAGE/src/scripting/variable.hpp b/MAGE/MAGE/src/scripting/variable.hpp index 27440f588..a0b508f7f 100644 --- a/MAGE/MAGE/src/scripting/variable.hpp +++ b/MAGE/MAGE/src/scripting/variable.hpp @@ -16,6 +16,21 @@ typedef XMFLOAT4 colour; //----------------------------------------------------------------------------- namespace mage { + /** + Enumeration of variable types. + */ + enum VariableType { + BoolType, + IntType, + FloatType, + Float3Type, + Float4Type, + ColourType, + StringType, + UnknownType + }; + + /** A struct of variables. */ @@ -24,15 +39,14 @@ namespace mage { /** Constructs a variable. - @tparam T - The type of the value. @param[in] name The name. + @param[in] type + The (scripting) type of the value. @param[in] value A pointer to the value. */ - template< typename T > - Variable(const string &name, const T *value) : m_name(name), m_value(new Value< T >(value)) {} + Variable(const string &name, VariableType type, const void *value) : m_name(name), m_type(type), m_value(value) {} /** Destructs this variable. @@ -50,13 +64,22 @@ namespace mage { return m_name; } + /** + Returns the type of this value. + + @return The type of this value. + */ + const VariableType &GetType() const { + return m_type; + } + /** Returns the value of this variable. @return A pointer to the value of this variable. */ const void *GetValue() const { - return m_value->GetValue(); + return m_value; } private: @@ -67,73 +90,17 @@ namespace mage { const string m_name; /** - A struct of abstract values. - - @note This is an example of the Type Erasure pattern for templates. - */ - struct AbstractValue { - - public: - - /** - Destructs this value. - */ - virtual ~AbstractValue() {} - - /** - Returns the value of this value. - - @return A pointer to the value of this value. - */ - virtual const void *GetValue() const = 0; - }; - - /** - A struct of values. + The type of this value. - @tparam T - The type of the value. + @note It is not possible to use typeid(T).name() since this assumes + a bijection between the scripting types and the storage types, + which is not the case. Thus the type needs to be stored explicitly. */ - template < typename T > - struct Value : AbstractValue { - - public: - - /** - Constructs a value. - - @param[in] value - A pointer to the value. - */ - Value(const T *value) : m_value(value) {} - - /** - Destructs this value. - */ - virtual ~Value() { - delete m_value; - } - - /** - Returns the value of this value. - - @return A pointer to the value of this value. - */ - virtual const void *GetValue() const { - return m_value ; - } - - private: - - /** - A pointer to the value of this value. - */ - const T *m_value; - }; + const VariableType m_type; /** A pointer to the value of this variable. */ - const AbstractValue *m_value; + const void *m_value; }; } \ No newline at end of file