mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 17:45:25 -04:00
deb802cfec
* For now, this is limited to instances inside custom objects. This will be made available in the future for all instances in scenes if this works well.
487 lines
14 KiB
C++
487 lines
14 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
|
* reserved. This project is released under the MIT License.
|
|
*/
|
|
|
|
#ifndef GDCORE_SERIALIZERELEMENT_H
|
|
#define GDCORE_SERIALIZERELEMENT_H
|
|
#include <map>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "GDCore/Serialization/SerializerValue.h"
|
|
#include "GDCore/String.h"
|
|
|
|
namespace gd {
|
|
|
|
/**
|
|
* \brief A generic container that can represent a value (
|
|
* containing a string, double, bool or int), an object ("associative array",
|
|
* "dictionary") with children or an array (children indexed by numeric
|
|
* properties).
|
|
*
|
|
* It is used for serialization (to JSON or XML), or as a generic
|
|
* container for properties of objects (see for example gd::Behavior).
|
|
*
|
|
* It also has specialized methods in GDevelop.js (see postjs.js) to be
|
|
* converted to a JavaScript object.
|
|
*
|
|
* \note Children are stored with their order preserved, but this also
|
|
* means that their access/removal is O(number of children). This class
|
|
* is not appropriated for a use in game where fast access is required.
|
|
*
|
|
* \see gd::Serializer
|
|
*/
|
|
class GD_CORE_API SerializerElement {
|
|
public:
|
|
/**
|
|
* \brief Create an empty element with no value, no children and no
|
|
* attributes.
|
|
*/
|
|
SerializerElement();
|
|
|
|
/**
|
|
* \brief Create an element with the specified value.
|
|
*/
|
|
SerializerElement(const SerializerValue &value);
|
|
|
|
/**
|
|
* Copy constructor.
|
|
*/
|
|
SerializerElement(const gd::SerializerElement &object) { Init(object); };
|
|
|
|
/**
|
|
* Assignment operator.
|
|
*/
|
|
SerializerElement &operator=(const gd::SerializerElement &object) {
|
|
if ((this) != &object) Init(object);
|
|
return *this;
|
|
}
|
|
|
|
virtual ~SerializerElement();
|
|
|
|
/** \name Value
|
|
* Methods related to the value of the element, if any.
|
|
*/
|
|
///@{
|
|
/**
|
|
* \brief Set the value of the element.
|
|
*/
|
|
void SetValue(const SerializerValue &value) {
|
|
valueUndefined = false;
|
|
elementValue = value;
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a boolean.
|
|
*/
|
|
void SetValue(bool val) {
|
|
valueUndefined = false;
|
|
elementValue.SetBool(val);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a boolean.
|
|
*/
|
|
void SetBoolValue(bool val) { SetValue(val); }
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a string.
|
|
*/
|
|
void SetValue(const gd::String &val) {
|
|
valueUndefined = false;
|
|
elementValue.SetString(val);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a string.
|
|
*/
|
|
void SetStringValue(const gd::String &val) { SetValue(val); }
|
|
|
|
/**
|
|
* \brief Set the value of the element, as an integer.
|
|
*/
|
|
void SetValue(int val) {
|
|
valueUndefined = false;
|
|
elementValue.SetInt(val);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as an integer.
|
|
*/
|
|
void SetIntValue(int val) { SetValue(val); }
|
|
|
|
/**
|
|
* \brief Set the value of the element, as an unsigned integer.
|
|
*/
|
|
void SetValue(unsigned int val) {
|
|
valueUndefined = false;
|
|
elementValue.SetInt((int)val);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a double precision floating point
|
|
* number.
|
|
*/
|
|
void SetValue(double val) {
|
|
valueUndefined = false;
|
|
elementValue.SetDouble(val);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a double precision floating point
|
|
* number.
|
|
*/
|
|
void SetDoubleValue(double val) { SetValue(val); }
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a floating point number.
|
|
*/
|
|
void SetValue(float val) { SetValue((double)val); }
|
|
|
|
/**
|
|
* \brief Set the value of the element, as a floating point number.
|
|
*/
|
|
void SetFloatValue(float val) { SetValue(val); }
|
|
|
|
/**
|
|
* \brief Get the value of the element, as a generic gd::SerializerValue.
|
|
*
|
|
* \note If not value was set, an attribute named "value" is searched (for
|
|
* backward compatiblity). If found, its value is returned.
|
|
*/
|
|
const SerializerValue &GetValue() const;
|
|
|
|
/**
|
|
* \brief Get the value, its type being a boolean.
|
|
*/
|
|
bool GetBoolValue() const { return GetValue().GetBool(); };
|
|
|
|
/**
|
|
* \brief Get the value, its type being a gd::String.
|
|
*/
|
|
gd::String GetStringValue() const { return GetValue().GetString(); };
|
|
|
|
/**
|
|
* \brief Get the value, its type being an int.
|
|
*/
|
|
int GetIntValue() const { return GetValue().GetInt(); };
|
|
|
|
/**
|
|
* \brief Get the value, its type being a double
|
|
*/
|
|
double GetDoubleValue() const { return GetValue().GetDouble(); };
|
|
|
|
/**
|
|
* \brief Return true if no value was set for the element.
|
|
*/
|
|
bool IsValueUndefined() const { return valueUndefined; }
|
|
|
|
/**
|
|
* \brief Save the value either as a string or as an array of strings if it
|
|
* has line breaks.
|
|
*/
|
|
void SetMultilineStringValue(const gd::String &value);
|
|
|
|
/**
|
|
* \brief Read the value, either represented as a string or as an array of strings,
|
|
* into a string.
|
|
*/
|
|
gd::String GetMultilineStringValue();
|
|
///@}
|
|
|
|
/** \name Attributes
|
|
* Methods related to the attributes of the element.
|
|
*
|
|
* \deprecated Prefer using AddChild/GetChild methods.
|
|
*
|
|
* Attributes are stored differently than children elements, but
|
|
* are serialized to the same in JSON. Hence, the attribute getters
|
|
* will also search in children elements.
|
|
*/
|
|
///@{
|
|
/**
|
|
* \brief Set the boolean value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetAttribute(const gd::String &name, bool value);
|
|
|
|
/**
|
|
* \brief Set the boolean value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetBoolAttribute(const gd::String &name, bool value) {
|
|
return SetAttribute(name, value);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the string value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetAttribute(const gd::String &name,
|
|
const gd::String &value);
|
|
|
|
/**
|
|
* \brief Set the string value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetStringAttribute(const gd::String &name,
|
|
const gd::String &value) {
|
|
return SetAttribute(name, value);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the string value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetAttribute(const gd::String &name, const char *value) {
|
|
if (value) SetAttribute(name, gd::String(value));
|
|
return *this;
|
|
};
|
|
|
|
/**
|
|
* \brief Set the integer value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetAttribute(const gd::String &name, int value);
|
|
|
|
/**
|
|
* \brief Set the integer value of an attribute of the element
|
|
* \param name The name of the attribute.
|
|
* \param value The value of the attribute.
|
|
*/
|
|
SerializerElement &SetIntAttribute(const gd::String &name, int value) {
|
|
return SetAttribute(name, value);
|
|
}
|
|
|
|
/**
|
|
* \brief Set the double precision floating point number value of an attribute
|
|
* of the element \param name The name of the attribute. \param value The
|
|
* value of the attribute.
|
|
*/
|
|
SerializerElement &SetAttribute(const gd::String &name, double value);
|
|
|
|
/**
|
|
* \brief Set the double precision floating point number value of an attribute
|
|
* of the element \param name The name of the attribute. \param value The
|
|
* value of the attribute.
|
|
*/
|
|
SerializerElement &SetDoubleAttribute(const gd::String &name, double value) {
|
|
return SetAttribute(name, value);
|
|
}
|
|
|
|
/**
|
|
* Get the value of an attribute being a boolean.
|
|
* \param name The name of the attribute
|
|
* \param defaultValue The value returned if the attribute is not found.
|
|
* \param deprecatedName An alternative name for the attribute that will be
|
|
* used if the first one doesn't exist.
|
|
*/
|
|
bool GetBoolAttribute(const gd::String &name,
|
|
bool defaultValue = false,
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* Get the value of an attribute being a string.
|
|
* \param name The name of the attribute
|
|
* \param defaultValue The value returned if the attribute is not found.
|
|
* \param deprecatedName An alternative name for the attribute that will be
|
|
* used if the first one doesn't exist.
|
|
*/
|
|
gd::String GetStringAttribute(const gd::String &name,
|
|
gd::String defaultValue = "",
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* Get the value of an attribute being an int.
|
|
* \param name The name of the attribute
|
|
* \param defaultValue The value returned if the attribute is not found.
|
|
* \param deprecatedName An alternative name for the attribute that will be
|
|
* used if the first one doesn't exist.
|
|
*/
|
|
int GetIntAttribute(const gd::String &name,
|
|
int defaultValue = 0,
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* Get the value of an attribute being a double.
|
|
* \param name The name of the attribute
|
|
* \param defaultValue The value returned if the attribute is not found.
|
|
* \param deprecatedName An alternative name for the attribute that will be
|
|
* used if the first one doesn't exist.
|
|
*/
|
|
double GetDoubleAttribute(const gd::String &name,
|
|
double defaultValue = 0.0,
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* \deprecated Use HasChild instead. This should be removed from the codebase.
|
|
* \brief Return true if the specified attribute exists.
|
|
* \param name The name of the attribute to find.
|
|
*/
|
|
bool HasAttribute(const gd::String &name) const;
|
|
|
|
/**
|
|
* \brief Remove the attribute with the specified name
|
|
* \param name The name of the attribute to remove.
|
|
*/
|
|
void RemoveAttribute(const gd::String& name);
|
|
|
|
/**
|
|
* \brief Return all the attributes of the element.
|
|
*/
|
|
const std::map<gd::String, SerializerValue> &GetAllAttributes() const {
|
|
return attributes;
|
|
};
|
|
///@}
|
|
|
|
/** \name Children
|
|
* Methods related to the children elements
|
|
*/
|
|
///@{
|
|
/**
|
|
* \brief Consider that the element is an array of elements, without specific
|
|
* name for the children element.
|
|
*
|
|
* When serialized to a format accepting arrays (like JSON), the element will
|
|
* be serialized to an array.
|
|
*/
|
|
void ConsiderAsArray() const { isArray = true; };
|
|
|
|
/**
|
|
* \brief Check if the element is considered as an array containing its
|
|
* children.
|
|
*
|
|
* As possible, this should be serialized to an array (possible JSON, but not
|
|
* in XML).
|
|
*/
|
|
bool ConsideredAsArray() const { return isArray; };
|
|
|
|
/**
|
|
* \brief Consider that the element is an array for elements with the given
|
|
* name.
|
|
*
|
|
* In this case, no child with a different name should be added. When
|
|
* serialized to a format accepting arrays (like JSON), the element will be
|
|
* serialized to an array.
|
|
*
|
|
* \param name The name of the children.
|
|
*/
|
|
void ConsiderAsArrayOf(const gd::String &name,
|
|
const gd::String &deprecatedName = "") const {
|
|
ConsiderAsArray();
|
|
arrayOf = name;
|
|
deprecatedArrayOf = deprecatedName;
|
|
};
|
|
|
|
/**
|
|
* \brief Return the name of the children the element is considered an array
|
|
* of.
|
|
*
|
|
* Return an empty string if the element is not considered as an array.
|
|
*/
|
|
const gd::String &ConsideredAsArrayOf() const { return arrayOf; };
|
|
|
|
/**
|
|
* \brief Add a child at the end of the children list with the given name and
|
|
* return a reference to it.
|
|
*
|
|
* \param name The name of the new child.
|
|
*/
|
|
SerializerElement &AddChild(gd::String name);
|
|
|
|
/**
|
|
* \brief Get a child of the element using its name.
|
|
*
|
|
* \param name The name of the child.
|
|
* \param name The index of the child, in case of an array.
|
|
*/
|
|
SerializerElement &GetChild(gd::String name,
|
|
std::size_t index = 0,
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* \brief Get a child of the element using its index (when the element is
|
|
* considered as an array).
|
|
*
|
|
* \param name The index of the child
|
|
*/
|
|
SerializerElement &GetChild(std::size_t index) const;
|
|
|
|
/**
|
|
* \brief Get the number of children having a specific name.
|
|
*
|
|
* If no children name is specified, return the number of children being part
|
|
* of the array. (ConsiderAsArrayOf must have been called before). Note that
|
|
* unnamed children are considered to be valid element of the array.
|
|
*
|
|
* \param name The name of the children.
|
|
*
|
|
* \see SerializerElement::ConsiderAsArrayOf
|
|
*/
|
|
std::size_t GetChildrenCount(gd::String name = "",
|
|
gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* \brief Return true if the specified child exists.
|
|
* \note Complexity is O(number of children).
|
|
* \param name The name of the child to find.
|
|
*/
|
|
bool HasChild(const gd::String &name, gd::String deprecatedName = "") const;
|
|
|
|
/**
|
|
* \brief Remove the child with the specified name
|
|
* \note Complexity is O(number of children).
|
|
* \param name The name of the child to remove.
|
|
*/
|
|
void RemoveChild(const gd::String &name);
|
|
|
|
/**
|
|
* \brief Remove all children and attributes.
|
|
*/
|
|
void Clear();
|
|
|
|
bool IsEmpty();
|
|
|
|
/**
|
|
* \brief Return all the children of the element.
|
|
*/
|
|
const std::vector<std::pair<gd::String, std::shared_ptr<SerializerElement> > >
|
|
&GetAllChildren() const {
|
|
return children;
|
|
};
|
|
///@}
|
|
|
|
static SerializerElement nullElement;
|
|
|
|
private:
|
|
/**
|
|
* Initialize element using another element. Used by copy-ctor and assign-op.
|
|
* Don't forget to update me if members were changed!
|
|
*/
|
|
void Init(const gd::SerializerElement &other);
|
|
|
|
bool valueUndefined = true; ///< If true, the element does not have a value.
|
|
SerializerValue elementValue;
|
|
|
|
std::map<gd::String, SerializerValue> attributes;
|
|
std::vector<std::pair<gd::String, std::shared_ptr<SerializerElement> > >
|
|
children;
|
|
mutable bool isArray = false; ///< true if element is considered as an array
|
|
mutable gd::String arrayOf; ///< The name of the children (was useful for XML
|
|
///< parsed elements).
|
|
mutable gd::String deprecatedArrayOf; ///< Alternate name for children
|
|
};
|
|
|
|
} // namespace gd
|
|
|
|
#endif
|