Files
GDevelop/Core/GDCore/Project/InitialInstance.h
2025-06-23 18:52:39 +02:00

411 lines
13 KiB
C++

/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <map>
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/String.h"
namespace gd {
class PropertyDescriptor;
class Project;
class Layout;
class ObjectsContainer;
} // namespace gd
namespace gd {
/**
* \brief Represents an instance of an object to be created on a layout start
* up.
*/
class GD_CORE_API InitialInstance {
public:
/**
* \brief Create an initial instance pointing to no object, at position (0,0).
*/
InitialInstance();
virtual ~InitialInstance() {};
/**
* Must return a pointer to a copy of the object. A such method is needed to
* do polymorphic copies. Just redefine this method in your derived object
* class like this: \code return new MyInitialInstanceClass(*this); \endcode
*/
InitialInstance* Clone() const { return new InitialInstance(*this); }
/** \name Common properties
* Members functions related to common properties
*/
///@{
/**
* \brief Get the name of object instantiated on the layout.
*/
const gd::String& GetObjectName() const { return objectName; }
/**
* \brief Set the name of object instantiated on the layout.
*/
void SetObjectName(const gd::String& name) { objectName = name; }
/**
* \brief Get the X position of the instance
*/
double GetX() const { return x; }
/**
* \brief Set the X position of the instance
*/
void SetX(double x_) { x = x_; }
/**
* \brief Get the Y position of the instance
*/
double GetY() const { return y; }
/**
* \brief Set the Y position of the instance
*/
void SetY(double y_) { y = y_; }
/**
* \brief Get the Z position of the instance
*/
double GetZ() const { return z; }
/**
* \brief Set the Z position of the instance
*/
void SetZ(double z_) { z = z_; }
/**
* \brief Get the rotation of the instance on Z axis, in radians.
*/
double GetAngle() const { return angle; }
/**
* \brief Set the rotation of the instance on Z axis, in radians.
*/
void SetAngle(double angle_) { angle = angle_; }
/**
* \brief Get the rotation of the instance on X axis, in radians.
*/
double GetRotationX() const { return rotationX; }
/**
* \brief Set the rotation of the instance on X axis, in radians.
*/
void SetRotationX(double rotationX_) { rotationX = rotationX_; }
/**
* \brief Get the rotation of the instance on Y axis, in radians.
*/
double GetRotationY() const { return rotationY; }
/**
* \brief Set the rotation of the instance on Y axis, in radians.
*/
void SetRotationY(double rotationY_) { rotationY = rotationY_; }
/**
* \brief Get the Z order of the instance (for a 2D object).
*/
int GetZOrder() const { return zOrder; }
/**
* \brief Set the Z order of the instance (for a 2D object).
*/
void SetZOrder(int zOrder_) { zOrder = zOrder_; }
/**
* \brief Get Opacity.
*/
int GetOpacity() const { return opacity; }
/**
* \brief Set the opacity of the instance.
*/
void SetOpacity(int opacity_) { opacity = opacity_; }
/**
* \brief Return true if the instance is flipped on X axis.
*/
bool IsFlippedX() const { return flippedX; }
/**
* \brief Set whether the instance is flipped on X axis.
*/
void SetFlippedX(bool flippedX_) { flippedX = flippedX_; }
/**
* \brief Return true if the instance is flipped on Y axis.
*/
bool IsFlippedY() const { return flippedY; }
/**
* \brief Set whether the instance is flipped on Y axis.
*/
void SetFlippedY(bool flippedY_) { flippedY = flippedY_; }
/**
* \brief Return true if the instance is flipped on Z axis.
*/
bool IsFlippedZ() const { return flippedZ; }
/**
* \brief Set whether the instance is flipped on Z axis.
*/
void SetFlippedZ(bool flippedZ_) { flippedZ = flippedZ_; }
/**
* \brief Get the layer the instance belongs to.
*/
const gd::String& GetLayer() const { return layer; }
/**
* \brief Set the layer the instance belongs to.
*/
void SetLayer(const gd::String& layer_) { layer = layer_; }
/**
* \brief Return true if the instance has a width/height which is different
* from its object default width/height. This is independent from
* `HasCustomDepth`.
*
* \see gd::Object
*/
bool HasCustomSize() const { return customSize; }
/**
* \brief Return true if the instance has a depth which is different from its
* object default depth. This is independent from `HasCustomSize`.
*
* \see gd::Object
*/
bool HasCustomDepth() const { return customDepth; }
/**
* \brief Set whether the instance has a width/height which is different from
* its object default width/height or not. This is independent from
* `SetHasCustomDepth`.
*
* \see gd::Object
*/
void SetHasCustomSize(bool hasCustomSize_) { customSize = hasCustomSize_; }
/**
* \brief Set whether the instance has a depth which is different from its
* object default depth or not.
* This is independent from `SetHasCustomSize`.
*
* \param hasCustomSize true if the depth is different from the object's
* default depth.
* \see gd::Object
*/
void SetHasCustomDepth(bool hasCustomDepth_) {
customDepth = hasCustomDepth_;
}
double GetCustomWidth() const { return width; }
void SetCustomWidth(double width_) { width = width_; }
double GetCustomHeight() const { return height; }
void SetCustomHeight(double height_) { height = height_; }
double GetCustomDepth() const { return depth; }
void SetCustomDepth(double depth_) { depth = depth_; }
/**
* \brief Return true if the instance is locked and cannot be moved in the
* IDE.
*/
bool IsLocked() const { return locked; };
/**
* \brief (Un)lock the initial instance.
*
* An instance which is locked cannot be moved with actions in the IDE.
*/
void SetLocked(bool enable = true) { locked = enable; }
/**
* \brief Return true if the instance cannot be selected by clicking on it
* in the IDE (only applies if instance is also locked).
*/
bool IsSealed() const { return sealed; };
/**
* \brief (Un)seal the initial instance.
*
* An instance which is sealed cannot be selected by clicking on it in a
* layout editor canvas.
*/
void SetSealed(bool enable = true) { sealed = enable; }
/**
* \brief Return true if the dimensions (width, height and depth) should keep
* the same ratio.
*/
bool ShouldKeepRatio() const { return keepRatio; };
/**
* \brief Define if instance's dimensions should keep the same ratio.
*/
void SetShouldKeepRatio(bool enable = true) { keepRatio = enable; }
///@}
/** \name Variable management
* Members functions related to initial instance variables management.
*/
///@{
/**
* Must return a reference to the container storing the instance variables
* \see gd::VariablesContainer
*/
const gd::VariablesContainer& GetVariables() const {
return initialVariables;
}
/**
* Must return a reference to the container storing the instance variables
* \see gd::VariablesContainer
*/
gd::VariablesContainer& GetVariables() { return initialVariables; }
///@}
/** \name Others properties management
* Members functions related to exposing others properties of the instance.
*
* \note Extensions writers: even if we can define new types of object by
* inheriting from gd::Object class, we cannot define new gd::InitialInstance
* classes.
*
* However, objects can store custom properties for their associated
* initial instances. When the IDE want to get the custom properties, it
* will call `GetCustomProperties` and `UpdateCustomProperty` methods.
* These methods are here defined to forward the call to the gd::Object
* associated to the gd::InitialInstance (by looking at the value returned
* by GetObjectName()).
*
* \see gd::Object
*/
///@{
/**
* \brief Return a map containing the properties names (as keys) and their
* values.
*
* \note Common properties ( name, position... ) do not need to be
* inserted in this map
*/
std::map<gd::String, gd::PropertyDescriptor> GetCustomProperties(
gd::ObjectsContainer& globalObjectsContainer,
gd::ObjectsContainer& objectsContainer);
/**
* \brief Update the property called \a name with the new \a value.
*
* \return false if the property could not be updated.
*/
bool UpdateCustomProperty(const gd::String& name,
const gd::String& value,
gd::ObjectsContainer& globalObjectsContainer,
gd::ObjectsContainer& objectsContainer);
/**
* \brief Get the value of a double property stored in the instance.
* \note Only use this when \a GetCustomProperties is too slow (when rendering
* instances for example).
* \return the value of the property, or 0 if it does
* not exists.
*/
double GetRawDoubleProperty(const gd::String& name) const;
/**
* \brief Get the value of a string property stored in the instance.
* \note Only use this when \a GetCustomProperties is too slow (when rendering
* instances for example).
* \return the value of the propety, or an empty
* string if it does not exists.
*/
const gd::String& GetRawStringProperty(const gd::String& name) const;
/**
* \brief Set the value of a double property stored in the instance.
*/
void SetRawDoubleProperty(const gd::String& name, double value);
/**
* \brief Set the value of a string property stored in the instance.
*/
void SetRawStringProperty(const gd::String& name, const gd::String& value);
///@}
/** \name Saving and loading
* Members functions related to serialization.
*/
///@{
/**
* \brief Serialize instances container.
*/
virtual void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the instances container.
*/
virtual void UnserializeFrom(const SerializerElement& element);
/**
* \brief Reset the persistent UUID used to recognize
* the same initial instance between serialization.
*/
InitialInstance& ResetPersistentUuid();
const gd::String& GetPersistentUuid() const { return persistentUuid; }
///@}
private:
// More properties can be stored in numberProperties and stringProperties.
// These properties are then managed by the Object class.
std::map<gd::String, double>
numberProperties; ///< More data which can be used by the object
std::map<gd::String, gd::String>
stringProperties; ///< More data which can be used by the object
gd::String objectName; ///< Object name
double x; ///< Instance X position
double y; ///< Instance Y position
double z; ///< Instance Z position (for a 3D object)
double angle; ///< Instance angle on Z axis
double rotationX; ///< Instance angle on X axis (for a 3D object)
double rotationY; ///< Instance angle on Y axis (for a 3D object)
int zOrder; ///< Instance Z order (for a 2D object)
int opacity; ///< Instance opacity
bool flippedX; ///< True if the instance is flipped on X axis
bool flippedY; ///< True if the instance is flipped on Y axis
bool flippedZ; ///< True if the instance is flipped on Z axis
gd::String layer; ///< Instance layer
bool customSize; ///< True if object has a custom width and height
bool customDepth; ///< True if object has a custom depth
double width; ///< Instance custom width
double height; ///< Instance custom height
double depth; ///< Instance custom depth
gd::VariablesContainer initialVariables; ///< Instance specific variables
bool locked; ///< True if the instance is locked
bool sealed; ///< True if the instance is sealed
bool keepRatio; ///< True if the instance's dimensions
/// should keep the same ratio.
mutable gd::String persistentUuid; ///< A persistent random version 4 UUID,
/// useful for hot reloading.
static gd::String* badStringPropertyValue; ///< Empty string returned by
///< GetRawStringProperty
};
} // namespace gd