/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_EDITOR_UTIL_VARIABLE_H #define CRYINCLUDE_EDITOR_UTIL_VARIABLE_H #pragma once #include "RefCountBase.h" #include #include "Include/EditorCoreAPI.h" #include #include typedef Functor4 TMissingAssetResolveCallback; inline const char* to_c_str(const char* str) { return str; } #define MAX_VAR_STRING_LENGTH 4096 struct IVarEnumList; struct ISplineInterpolator; class CUsedResources; struct IVariable; namespace { template T nextNiceNumberBelow(T number); template T nextNiceNumberAbove(T number) { if (number == 0) { return 0; } if (number < 0) { return -nextNiceNumberBelow(-number); } // number = 8000 auto l = log10(number); // 3.90 AZ::s64 i = aznumeric_cast(l); // 3 int f = aznumeric_cast(pow(10, l - i)); // 10^0.9 = 8 f = f < 2 ? 2 : f < 5 ? 5 : 10; // f -> 10 return aznumeric_cast(pow(10, i) * f); } template T nextNiceNumberBelow(T number) { if (number == 0) { return 0; } if (number < 0) { return -nextNiceNumberAbove(-number); } // number = 8000 auto l = log10(number); // 3.90 AZ::s64 i = aznumeric_cast(l); // 3 int f = aznumeric_cast(pow(10, l - i)); // 10^0.9 = 8 f = f > 5 ? 5 : f > 2 ? 2 : 1; // f -> 5 return aznumeric_cast(pow(10, i) * f); } } /** IVariableContainer * Interface for all classes that hold child variables */ struct IVariableContainer : public CRefCountBase { //! Add child variable virtual void AddVariable(IVariable* var) = 0; //! Delete specific variable virtual bool DeleteVariable(IVariable* var, bool recursive = false) = 0; //! Delete all variables virtual void DeleteAllVariables() = 0; //! Gets number of variables virtual int GetNumVariables() const = 0; //! Get variable at index virtual IVariable* GetVariable(int index) const = 0; //! Returns true if var block contains specified variable. virtual bool IsContainsVariable(IVariable* pVar, bool bRecursive = false) const = 0; //! Find variable by name. virtual IVariable* FindVariable(const char* name, bool bRecursive = false, bool bHumanName = false) const = 0; //! Return true if variable block is empty (Does not have any vars). virtual bool IsEmpty() const = 0; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /** IVariable is the variant variable interface. */ struct IVariable : public IVariableContainer { /** Type of data stored in variable. */ enum EType { UNKNOWN, //!< Unknown parameter type. INT, //!< Integer property. BOOL, //!< Boolean property. FLOAT, //!< Float property. VECTOR2, //!< Vector property. VECTOR, //!< Vector property. VECTOR4, //!< Vector property. QUAT, //!< Quaternion property. STRING, //!< String property. ARRAY, //!< Array of parameters. FLOW_CUSTOM_DATA, //!< FLow graph custom data DOUBLE //!< Double property. }; //! Type of data hold by variable. enum EDataType { DT_SIMPLE = 0, //!< Standard param type. DT_BOOLEAN, DT_PERCENT, //!< Percent data type, (Same as simple but value is from 0-1 and UI will be from 0-100). DT_COLOR, DT_ANGLE, DT_FILE, DT_TEXTURE, DT_ANIMATION, DT_OBJECT, DT_SHADER, DT_AI_BEHAVIOR, DT_AI_ANCHOR, #ifdef USE_DEPRECATED_AI_CHARACTER_SYSTEM DT_AI_CHARACTER, #endif DT_AI_PFPROPERTIESLIST, DT_AIENTITYCLASSES, DT_AITERRITORY, DT_AIWAVE, DT_LOCAL_STRING, DT_EQUIP, DT_REVERBPRESET, DT_MATERIAL, DT_MATERIALLOOKUP, DT_SOCLASS, // Smart Object Class DT_SOCLASSES, // Smart Object Classes DT_SOSTATE, // Smart Object State DT_SOSTATES, // Smart Object States DT_SOSTATEPATTERN, // Smart Object State Pattern DT_SOACTION, // Smart Object Action DT_SOHELPER, // Smart Object Helper DT_SONAVHELPER, // Smart Object Navigation Helper DT_SOANIMHELPER, // Smart Object Animation Helper DT_SOEVENT, // Smart Object Event DT_SOTEMPLATE, // Smart Object Template DT_DEPRECATED0, // Formerly Custom Action DT_EXTARRAY, // Extendable Array DT_VEEDHELPER, // Vehicle Helper DT_VEEDPART, // Vehicle Part DT_VEEDCOMP, // Vehicle Component DT_GAMETOKEN, // Game Token DT_SEQUENCE, // Movie Sequence (DEPRECATED, use DT_SEQUENCE_ID, instead.) DT_MISSIONOBJ, // Mission Objective DT_USERITEMCB, // Use a callback GetItemsCallback in user data of variable DT_UIENUM, // Edit as enum, uses CUIEnumsDatabase to lookup the enum to value pairs and combobox in GUI. DT_SEQUENCE_ID, // Movie Sequence DT_LIGHT_ANIMATION, // Light Animation Node in the global Light Animation Set DT_PARTICLE_EFFECT, DT_GEOM_CACHE, // Geometry cache DT_FLARE, DT_AUDIO_TRIGGER, DT_AUDIO_SWITCH, DT_AUDIO_SWITCH_STATE, DT_AUDIO_RTPC, DT_AUDIO_ENVIRONMENT, DT_AUDIO_PRELOAD_REQUEST, DT_UI_ELEMENT, DT_COLORA, // DT_COLOR with alpha channel DT_MOTION, // Motion animation asset DT_ASSET, DT_CURVE = BIT(7), // Combined with other types }; // Flags that can used with variables. enum EFlags { // User interface related flags. UI_DISABLED = BIT(0), //!< This variable will be disabled in UI. UI_BOLD = BIT(1), //!< Variable name in properties will be bold. UI_SHOW_CHILDREN = BIT(2), //!< Display children in parent field. UI_USE_GLOBAL_ENUMS = BIT(3), //!< Use CUIEnumsDatabase to fetch enums for this variable name. UI_INVISIBLE = BIT(4), //!< This variable will not be displayed in the UI UI_ROLLUP2 = BIT(5), //!< Prefer right roll-up bar for extended property control. UI_COLLAPSED = BIT(6), //!< Category collapsed by default. UI_UNSORTED = BIT(7), //!< Do not sort list-box alphabetically. UI_EXPLICIT_STEP = BIT(8), //!< Use the step size set in the variable for the UI directly. UI_NOT_DISPLAY_VALUE = BIT(9), //!< The UI will display an empty string where it would normally draw the variable value. UI_HIGHLIGHT_EDITED = BIT(10), //!< Edited (non-default value) properties show highlight color. UI_AUTO_EXPAND = BIT(11), //!< Category expanded by default. to auto-expand child in ReflectedPropertyCtrl. UI_CREATE_SPLINE = BIT(12), //!< To indicate the spline need to be re-created. This is usually because the data was changed directly through the data address }; typedef Functor1 OnSetCallback; using OnSetEnumCallback = OnSetCallback; // Store IGetCustomItems into IVariable's UserData and set datatype to // DT_USERITEMCB // RefCounting is NOT handled by IVariable! struct IGetCustomItems : public CRefCountBase { struct SItem { SItem() {} SItem(const QString& name, const QString& desc = QString()) : name(name) , desc(desc) {} SItem(const char* name, const char* desc = "") : name(name) , desc(desc) {} QString name; QString desc; }; virtual bool GetItems (IVariable* /* pVar */, std::vector& /* items */, QString& /* outDialogTitle */) = 0; virtual bool UseTree() = 0; virtual const char* GetTreeSeparator() = 0; }; //! Get name of parameter. virtual QString GetName() const = 0; //! Set name of parameter. virtual void SetName(const QString& name) = 0; //! Get human readable name of parameter (Normally same as name). virtual QString GetHumanName() const = 0; //! Set human readable name of parameter (name without prefix). virtual void SetHumanName(const QString& name) = 0; //! Get variable description. virtual QString GetDescription() const = 0; //! Set variable description. virtual void SetDescription(const char* desc) = 0; //! Set variable description. virtual void SetDescription(const QString& desc) = 0; //! Get parameter type. virtual EType GetType() const = 0; //! Get size of parameter. virtual int GetSize() const = 0; //! Type of data stored in this variable. virtual unsigned char GetDataType() const = 0; virtual void SetDataType(unsigned char dataType) = 0; virtual void SetUserData(const QVariant &data) = 0; virtual QVariant GetUserData() const = 0; ////////////////////////////////////////////////////////////////////////// // Flags ////////////////////////////////////////////////////////////////////////// //! Set variable flags, (Limited to 16 flags). virtual void SetFlags(int flags) = 0; virtual int GetFlags() const = 0; virtual void SetFlagRecursive(EFlags flag) = 0; ///////////////////////////////////////////////////////////////////////////// // Set methods. ///////////////////////////////////////////////////////////////////////////// virtual void Set(int value) = 0; virtual void Set(bool value) = 0; virtual void Set(float value) = 0; virtual void Set(double value) = 0; virtual void Set(const Vec2& value) = 0; virtual void Set(const Vec3& value) = 0; virtual void Set(const Vec4& value) = 0; virtual void Set(const Ang3& value) = 0; virtual void Set(const Quat& value) = 0; virtual void Set(const QString& value) = 0; virtual void Set(const char* value) = 0; virtual void SetDisplayValue(const QString& value) = 0; // Called when value updated by any means (including internally). virtual void OnSetValue(bool bRecursive) = 0; ///////////////////////////////////////////////////////////////////////////// // Get methods. ///////////////////////////////////////////////////////////////////////////// virtual void Get(int& value) const = 0; virtual void Get(bool& value) const = 0; virtual void Get(float& value) const = 0; virtual void Get(double& value) const = 0; virtual void Get(Vec2& value) const = 0; virtual void Get(Vec3& value) const = 0; virtual void Get(Vec4& value) const = 0; virtual void Get(Ang3& value) const = 0; virtual void Get(Quat& value) const = 0; virtual void Get(QString& value) const = 0; virtual QString GetDisplayValue() const = 0; virtual bool HasDefaultValue() const = 0; //! reset value to default value virtual void ResetToDefault() = 0; //! Return cloned value of variable. virtual IVariable* Clone(bool bRecursive) const = 0; //! Copy variable value from specified variable. //! This method executed always recursively on all sub hierarchy of variables, //! In Array vars, will never create new variables, only copy values of corresponding childs. //! @param fromVar Source variable to copy value from. virtual void CopyValue(IVariable* fromVar) = 0; ////////////////////////////////////////////////////////////////////////// // Value Limits. ////////////////////////////////////////////////////////////////////////// //! Set value limits. virtual void SetLimits(float fMin, float fMax, float fStep = 0.f, bool bHardMin = true, bool bHardMax = true) {} //! Get value limits. virtual void GetLimits(float& fMin, float& fMax, float& fStep, bool& bHardMin, bool& bHardMax) {} void GetLimits(float& fMin, float& fMax) { float f; bool b; GetLimits(fMin, fMax, f, b, b); } virtual bool HasCustomLimits() { return false; } virtual void EnableNotifyWithoutValueChange(bool bFlag){} ////////////////////////////////////////////////////////////////////////// // Wire/Unwire variables. ////////////////////////////////////////////////////////////////////////// //! Wire variable, wired variable will be changed when this var changes. virtual void Wire(IVariable* targetVar) = 0; //! Unwire variable. virtual void Unwire(IVariable* targetVar) = 0; ////////////////////////////////////////////////////////////////////////// // Assign on set callback. ////////////////////////////////////////////////////////////////////////// virtual void AddOnSetCallback(OnSetCallback func) = 0; virtual void RemoveOnSetCallback(OnSetCallback func) = 0; virtual void ClearOnSetCallbacks() {} ////////////////////////////////////////////////////////////////////////// // Assign callback triggered when enums change. ////////////////////////////////////////////////////////////////////////// virtual void AddOnSetEnumCallback(OnSetEnumCallback func) = 0; virtual void RemoveOnSetEnumCallback(OnSetCallback func) = 0; virtual void ClearOnSetEnumCallbacks() {} ////////////////////////////////////////////////////////////////////////// //! Retrieve pointer to selection list used by variable. virtual IVarEnumList* GetEnumList() const { return 0; } virtual ISplineInterpolator* GetSpline() { return 0; } ////////////////////////////////////////////////////////////////////////// //! Serialize variable to XML. ////////////////////////////////////////////////////////////////////////// virtual void Serialize(XmlNodeRef node, bool load) = 0; // From CObject, (not implemented) virtual void Serialize(CArchive& ar) {} ////////////////////////////////////////////////////////////////////////// // Disables the update callbacks for certain operations in order to avoid // too many function calls when not needed. ////////////////////////////////////////////////////////////////////////// virtual void EnableUpdateCallbacks(bool boEnable) = 0; // Setup to true to force save Undo in case the value the same. virtual void SetForceModified(bool bForceModified) {} }; // Smart pointer to this parameter. typedef _smart_ptr IVariablePtr; AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING /** ************************************************************************************** * CVariableBase implements IVariable interface and provide default implementation * for basic IVariable functionality (Name, Flags, etc...) * CVariableBase cannot be instantiated directly and should be used as the base class for * actual Variant implementation classes. *************************************************************************************** */ class EDITOR_CORE_API CVariableBase : public IVariable { AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING public: virtual ~CVariableBase() {} void SetName(const QString& name) { m_name = name; }; //! Get name of parameter. QString GetName() const { return m_name; }; QString GetHumanName() const { if (!m_humanName.isEmpty()) { return m_humanName; } return m_name; } void SetHumanName(const QString& name) { m_humanName = name; } void SetDescription(const char* desc) { m_description = desc; }; void SetDescription(const QString& desc) { m_description = desc; }; //! Get name of parameter. QString GetDescription() const { return m_description; }; EType GetType() const { return IVariable::UNKNOWN; }; int GetSize() const { return sizeof(*this); }; unsigned char GetDataType() const { return m_dataType; }; void SetDataType(unsigned char dataType) { m_dataType = dataType; } void SetFlags(int flags) { m_flags = flags; } int GetFlags() const { return m_flags; } void SetFlagRecursive(EFlags flag) { m_flags |= flag; } void SetUserData(const QVariant &data){ m_userData = data; }; QVariant GetUserData() const { return m_userData; } ////////////////////////////////////////////////////////////////////////// // Set methods. ////////////////////////////////////////////////////////////////////////// void Set(int value) { assert(0); } void Set(bool value) { assert(0); } void Set(float value) { assert(0); } void Set(double value) { assert(0); } void Set(const Vec2& value) { assert(0); } void Set(const Vec3& value) { assert(0); } void Set(const Vec4& value) { assert(0); } void Set(const Ang3& value) { assert(0); } void Set(const Quat& value) { assert(0); } void Set(const QString& value) { assert(0); } void Set(const char* value) { assert(0); } void SetDisplayValue(const QString& value) { Set(value); } ////////////////////////////////////////////////////////////////////////// // Get methods. ////////////////////////////////////////////////////////////////////////// void Get(int& value) const { assert(0); } void Get(bool& value) const { assert(0); } void Get(float& value) const { assert(0); } void Get(double& value) const { assert(0); } void Get(Vec2& value) const { assert(0); } void Get(Vec3& value) const { assert(0); } void Get(Vec4& value) const { assert(0); } void Get(Ang3& value) const { assert(0); } void Get(Quat& value) const { assert(0); } void Get(QString& value) const { assert(0); } QString GetDisplayValue() const { QString val; Get(val); return val; } ////////////////////////////////////////////////////////////////////////// // IVariableContainer functions ////////////////////////////////////////////////////////////////////////// virtual void AddVariable(IVariable* var) { assert(0); } virtual bool DeleteVariable(IVariable* var, bool recursive = false) { return false; } virtual void DeleteAllVariables() {} virtual int GetNumVariables() const { return 0; } virtual IVariable* GetVariable(int index) const { return nullptr; } virtual bool IsContainsVariable(IVariable* pVar, bool bRecursive = false) const { return false; } virtual IVariable* FindVariable(const char* name, bool bRecursive = false, bool bHumanName = false) const { return nullptr; } virtual bool IsEmpty() const { return true; } ////////////////////////////////////////////////////////////////////////// void Wire(IVariable* var) { m_wiredVars.push_back(var); } ////////////////////////////////////////////////////////////////////////// void Unwire(IVariable* var) { if (!var) { // Unwire all. m_wiredVars.clear(); } else { stl::find_and_erase(m_wiredVars, var); } } ////////////////////////////////////////////////////////////////////////// void AddOnSetCallback(OnSetCallback func) { if (!stl::find(m_onSetFuncs, func)) { m_onSetFuncs.push_back(func); } } ////////////////////////////////////////////////////////////////////////// void RemoveOnSetCallback(OnSetCallback func) { stl::find_and_erase(m_onSetFuncs, func); } ////////////////////////////////////////////////////////////////////////// void ClearOnSetCallbacks() { m_onSetFuncs.clear(); } void AddOnSetEnumCallback(OnSetEnumCallback func) override { if (!stl::find(m_onSetEnumFuncs, func)) { m_onSetEnumFuncs.push_back(func); } } ////////////////////////////////////////////////////////////////////////// void RemoveOnSetEnumCallback(OnSetCallback func) { stl::find_and_erase(m_onSetEnumFuncs, func); } void ClearOnSetEnumCallbacks() override { m_onSetEnumFuncs.clear(); } virtual void OnSetValue(bool bRecursive) { // If have wired variables or OnSet callback, process them. // Send value to wired variable. for (CVariableBase::WiredList::iterator it = m_wiredVars.begin(); it != m_wiredVars.end(); ++it) { if (m_bForceModified) { (*it)->SetForceModified(true); } // Copy value to wired vars. (*it)->CopyValue(this); } if (!m_boUpdateCallbacksEnabled) { return; } // Call on set callback. for (auto it = m_onSetFuncs.begin(); it != m_onSetFuncs.end(); ++it) { // Call on set callback. (*it)(this); } } ////////////////////////////////////////////////////////////////////////// void Serialize(XmlNodeRef node, bool load) { if (load) { if (node->haveAttr(m_name.toUtf8().data())) { Set(node->getAttr(m_name.toUtf8().data())); } } else { // Saving. QString str; Get(str); node->setAttr(m_name.toUtf8().data(), str.toUtf8().data()); } } virtual void EnableUpdateCallbacks(bool boEnable){m_boUpdateCallbacksEnabled = boEnable; }; virtual void SetForceModified(bool bForceModified) { m_bForceModified = bForceModified; } protected: // Constructor. CVariableBase() : m_dataType(DT_SIMPLE) , m_flags(0) , m_boUpdateCallbacksEnabled(true) , m_bForceModified(false) { } // Copy constructor. CVariableBase(const CVariableBase& var) { m_name = var.m_name; m_humanName = var.m_humanName; m_description = var.m_description; m_flags = var.m_flags; m_dataType = var.m_dataType; m_userData = var.m_userData; m_boUpdateCallbacksEnabled = true; m_bForceModified = var.m_bForceModified; // Never copy callback function or wired variables they are private to specific variable, } protected: // Not allow. CVariableBase& operator=(const CVariableBase& var) { return *this; } bool StartResolveRequest(char type, const char* value, const TMissingAssetResolveCallback& cb); void CancelResolveRequest(const TMissingAssetResolveCallback& cb); protected: ////////////////////////////////////////////////////////////////////////// // Variables. ////////////////////////////////////////////////////////////////////////// typedef std::vector OnSetCallbackList; typedef std::vector WiredList; using OnSetEnumCallbackList = std::vector; QString m_name; QString m_humanName; QString m_description; //! Optional userdata pointer QVariant m_userData; AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING //! Extended data (Extended data is never copied, it's always private to this variable). WiredList m_wiredVars; OnSetCallbackList m_onSetFuncs; OnSetEnumCallbackList m_onSetEnumFuncs; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING uint16 m_flags; //! Limited to 8 flags. unsigned char m_dataType; bool m_boUpdateCallbacksEnabled; bool m_bForceModified; }; /** ************************************************************************************** * CVariableArray implements variable of type array of IVariables. *************************************************************************************** */ class EDITOR_CORE_API CVariableArray : public CVariableBase { public: CVariableArray(){} //! Get name of parameter. virtual EType GetType() const { return IVariable::ARRAY; }; virtual int GetSize() const { return sizeof(CVariableArray); }; ////////////////////////////////////////////////////////////////////////// // Set methods. ////////////////////////////////////////////////////////////////////////// virtual void Set(const QString& value) { if (m_strValue != value) { m_strValue = value; OnSetValue(false); } } void OnSetValue(bool bRecursive) { CVariableBase::OnSetValue(bRecursive); if (bRecursive) { for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { (*it)->OnSetValue(true); } } } void SetFlagRecursive(EFlags flag) { CVariableBase::SetFlagRecursive(flag); for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { (*it)->SetFlagRecursive(flag); } } ////////////////////////////////////////////////////////////////////////// // Get methods. ////////////////////////////////////////////////////////////////////////// virtual void Get(QString& value) const { value = m_strValue; } virtual bool HasDefaultValue() const { for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { if (!(*it)->HasDefaultValue()) { return false; } } return true; } virtual void ResetToDefault() { for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { (*it)->ResetToDefault(); } } ////////////////////////////////////////////////////////////////////////// IVariable* Clone(bool bRecursive) const { CVariableArray* var = new CVariableArray(*this); // m_vars was shallow-duplicated, clone elements. for (int i = 0; i < m_vars.size(); i++) { var->m_vars[i] = m_vars[i]->Clone(bRecursive); } return var; } ////////////////////////////////////////////////////////////////////////// void CopyValue(IVariable* fromVar) { assert(fromVar); if (fromVar->GetType() != IVariable::ARRAY) { return; } int numSrc = fromVar->GetNumVariables(); int numTrg = static_cast(m_vars.size()); for (int i = 0; i < numSrc && i < numTrg; i++) { // Copy Every child variable. m_vars[i]->CopyValue(fromVar->GetVariable(i)); } QString strValue; fromVar->Get(strValue); Set(strValue); } ////////////////////////////////////////////////////////////////////////// virtual int GetNumVariables() const { return static_cast(m_vars.size()); } virtual IVariable* GetVariable(int index) const { assert(index >= 0 && index < (int)m_vars.size()); return m_vars[index]; } virtual void AddVariable(IVariable* var) { m_vars.push_back(var); } virtual bool DeleteVariable(IVariable* var, bool recursive /*=false*/) { bool found = stl::find_and_erase(m_vars, var); if (!found && recursive) { for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { if ((*it)->DeleteVariable(var, recursive)) { return true; } } } return found; } virtual void DeleteAllVariables() { m_vars.clear(); } virtual bool IsContainsVariable(IVariable* pVar, bool bRecursive) const { for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { if (*it == pVar) { return true; } } // If not found search childs. if (bRecursive) { // Search all top level variables. for (Variables::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { if ((*it)->IsContainsVariable(pVar)) { return true; } } } return false; } virtual IVariable* FindVariable(const char* name, bool bRecursive, bool bHumanName) const; virtual bool IsEmpty() const { return m_vars.empty(); } void Serialize(XmlNodeRef node, bool load) { if (load) { // Loading. QString name; for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { IVariable* var = *it; if (var->GetNumVariables()) { XmlNodeRef child = node->findChild(var->GetName().toUtf8().data()); if (child) { var->Serialize(child, load); } } else { var->Serialize(node, load); } } } else { // Saving. for (Variables::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { IVariable* var = *it; if (var->GetNumVariables()) { XmlNodeRef child = node->newChild(var->GetName().toUtf8().data()); var->Serialize(child, load); } else { var->Serialize(node, load); } } } } protected: typedef std::vector Variables; AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING Variables m_vars; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING //! Any string value displayed in properties. QString m_strValue; }; /** var_type namespace includes type definitions needed for CVariable implementaton. */ namespace var_type { ////////////////////////////////////////////////////////////////////////// template struct type_traits_base { static int type() { return TypeID; }; //! Return true if standard C++ type. static bool is_standart() { return IsStandart; }; static bool is_integer() { return IsInteger; }; static bool is_signed() { return IsSigned; }; static bool supports_range() { return SupportsRange; }; }; template struct type_traits : public type_traits_base {}; // Types specialization. template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base{}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; template<> struct type_traits : public type_traits_base {}; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // General one type to another type convertor class. ////////////////////////////////////////////////////////////////////////// struct type_convertor { template void operator()(const From& from, To& to) const { assert(0); } void operator()(const int& from, int& to) const { to = from; } void operator()(const int& from, bool& to) const { to = from != 0; } void operator()(const int& from, float& to) const { to = (float)from; } ////////////////////////////////////////////////////////////////////////// void operator()(const bool& from, int& to) const { to = from; } void operator()(const bool& from, bool& to) const { to = from; } void operator()(const bool& from, float& to) const { to = from; } ////////////////////////////////////////////////////////////////////////// void operator()(const float& from, int& to) const { to = (int)from; } void operator()(const float& from, bool& to) const { to = from != 0; } void operator()(const float& from, float& to) const { to = from; } void operator()(const double& from, int& to) const { to = (int)from; } void operator()(const double& from, bool& to) const { to = from != 0; } void operator()(const double& from, float& to) const { to = aznumeric_cast(from); } void operator()(const Vec2& from, Vec2& to) const { to = from; } void operator()(const Vec3& from, Vec3& to) const { to = from; } void operator()(const Vec4& from, Vec4& to) const { to = from; } void operator()(const Quat& from, Quat& to) const { to = from; } void operator()(const QString& from, QString& to) const { to = from; } void operator()(bool value, QString& to) const { to = QString::number((value) ? (int)1 : (int)0); } void operator()(int value, QString& to) const { to = QString::number(value); } void operator()(float value, QString& to) const { to = QString::number(value); }; void operator()(double value, QString& to) const { to = QString::number(value); }; void operator()(const Vec2& value, QString& to) const { to = QString::fromLatin1("%1,%2").arg(value.x).arg(value.y); } void operator()(const Vec3& value, QString& to) const { to = QString::fromLatin1("%1,%2,%3").arg(value.x).arg(value.y).arg(value.z); } void operator()(const Vec4& value, QString& to) const { to = QString::fromLatin1("%1,%2,%3,%4").arg(value.x).arg(value.y).arg(value.z).arg(value.w); } void operator()(const Ang3& value, QString& to) const { to = QString::fromLatin1("%1,%2,%3").arg(value.x).arg(value.y).arg(value.z); } void operator()(const Quat& value, QString& to) const { to = QString::fromLatin1("%1,%2,%3,%4").arg(value.w).arg(value.v.x).arg(value.v.y).arg(value.v.z); } void operator()(const QString& from, int& value) const { value = from.toInt(); } void operator()(const QString& from, bool& value) const { value = from.toInt() != 0; } void operator()(const QString& from, float& value) const { value = from.toFloat(); } void operator()(const QString& from, Vec2& value) const { QStringList parts = from.split(QStringLiteral(",")); while (parts.size() < 2) { parts.push_back(QString()); } value.x = parts[0].toFloat(); value.y = parts[1].toFloat(); }; void operator()(const QString& from, Vec3& value) const { QStringList parts = from.split(QStringLiteral(",")); while (parts.size() < 3) { parts.push_back(QString()); } value.x = parts[0].toFloat(); value.y = parts[1].toFloat(); value.z = parts[2].toFloat(); }; void operator()(const QString& from, Vec4& value) const { QStringList parts = from.split(QStringLiteral(",")); while (parts.size() < 4) { parts.push_back(QString()); } value.x = parts[0].toFloat(); value.y = parts[1].toFloat(); value.z = parts[2].toFloat(); value.w = parts[3].toFloat(); }; void operator()(const QString& from, Ang3& value) const { QStringList parts = from.split(QStringLiteral(",")); while (parts.size() < 3) { parts.push_back(QString()); } value.x = parts[0].toFloat(); value.y = parts[1].toFloat(); value.z = parts[2].toFloat(); }; void operator()(const QString& from, Quat& value) const { QStringList parts = from.split(QStringLiteral(",")); while (parts.size() < 4) { parts.push_back(QString()); } value.w = parts[0].toFloat(); value.v.x = parts[1].toFloat(); value.v.y = parts[2].toFloat(); value.v.z = parts[3].toFloat(); }; }; ////////////////////////////////////////////////////////////////////////// // Custom comparison functions for different variable type's values,. ////////////////////////////////////////////////////////////////////////// template inline bool compare(const Type& arg1, const Type& arg2) { return arg1 == arg2; }; inline bool compare(const Vec2& v1, const Vec2& v2) { return v1.x == v2.x && v1.y == v2.y; } inline bool compare(const Vec3& v1, const Vec3& v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; } inline bool compare(const Vec4& v1, const Vec4& v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w; } inline bool compare(const Ang3& v1, const Ang3& v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; } inline bool compare(const Quat& q1, const Quat& q2) { return q1.v.x == q2.v.x && q1.v.y == q2.v.y && q1.v.z == q2.v.z && q1.w == q2.w; } inline bool compare(const char* s1, const char* s2) { return strcmp(s1, s2) == 0; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // Custom Initialization functions for different variable type's values,. ////////////////////////////////////////////////////////////////////////// template inline void init(Type& val) { val = 0; }; inline void init(Vec2& val) { val.x = 0; val.y = 0; }; inline void init(Vec3& val) { val.x = 0; val.y = 0; val.z = 0; }; inline void init(Vec4& val) { val.x = 0; val.y = 0; val.z = 0; val.w = 0; }; inline void init(Ang3& val) { val.x = 0; val.y = 0; val.z = 0; }; inline void init(Quat& val) { val.v.x = 0; val.v.y = 0; val.v.z = 0; val.w = 0; }; inline void init(const char*& val) { val = ""; }; inline void init(QString& val) { // self initializing. } ////////////////////////////////////////////////////////////////////////// }; ////////////////////////////////////////////////////////////////////////// // Void variable does not contain any value. ////////////////////////////////////////////////////////////////////////// class CVariableVoid : public CVariableBase { public: CVariableVoid(){}; virtual EType GetType() const { return IVariable::UNKNOWN; }; virtual IVariable* Clone(bool bRecursive) const { return new CVariableVoid(*this); } virtual void CopyValue(IVariable* fromVar) {}; virtual bool HasDefaultValue() const { return true; } virtual void ResetToDefault() {}; protected: CVariableVoid(const CVariableVoid& v) : CVariableBase(v) {}; }; ////////////////////////////////////////////////////////////////////////// template class CVariable : public CVariableBase { typedef CVariable Self; public: // Constructor. CVariable() : m_valueMin(0.0f) , m_valueMax(100.0f) , m_valueStep(0.0f) , m_bHardMin(false) , m_bHardMax(false) , m_customLimits(false) { // Initialize value to zero or empty string. var_type::init(m_valueDef); } explicit CVariable(const T& set) : CVariable() { var_type::init(m_valueDef); // Update F32NAN values in Debud mode SetValue(set); } //! Get name of parameter. virtual EType GetType() const { return (EType)var_type::type_traits::type(); }; virtual int GetSize() const { return sizeof(T); }; ////////////////////////////////////////////////////////////////////////// // Set methods. ////////////////////////////////////////////////////////////////////////// virtual void Set(int value) { SetValue(value); } virtual void Set(bool value) { SetValue(value); } virtual void Set(float value) { SetValue(value); } virtual void Set(double value) { SetValue(value); } virtual void Set(const Vec2& value) { SetValue(value); } virtual void Set(const Vec3& value) { SetValue(value); } virtual void Set(const Vec4& value) { SetValue(value); } virtual void Set(const Ang3& value) { SetValue(value); } virtual void Set(const Quat& value) { SetValue(value); } virtual void Set(const QString& value) { SetValue(value); } virtual void Set(const char* value) { SetValue(QString(value)); } ////////////////////////////////////////////////////////////////////////// // Get methods. ////////////////////////////////////////////////////////////////////////// virtual void Get(int& value) const { GetValue(value); } virtual void Get(bool& value) const { GetValue(value); } virtual void Get(float& value) const { GetValue(value); } virtual void Get(double& value) const { GetValue(value); } virtual void Get(Vec2& value) const { GetValue(value); } virtual void Get(Vec3& value) const { GetValue(value); } virtual void Get(Vec4& value) const { GetValue(value); } virtual void Get(Quat& value) const { GetValue(value); } virtual void Get(QString& value) const { GetValue(value); } virtual bool HasDefaultValue() const { T defval; var_type::init(defval); return m_valueDef == defval; } virtual void ResetToDefault() { T defval; var_type::init(defval); SetValue(defval); } ////////////////////////////////////////////////////////////////////////// // Limits. ////////////////////////////////////////////////////////////////////////// virtual void SetLimits(float fMin, float fMax, float fStep = 0.f, bool bHardMin = true, bool bHardMax = true) { m_valueMin = fMin; m_valueMax = fMax; m_valueStep = fStep; m_bHardMin = bHardMin; m_bHardMax = bHardMax; // Flag to determine when this variable has custom limits set m_customLimits = true; } virtual void GetLimits(float& fMin, float& fMax, float& fStep, bool& bHardMin, bool& bHardMax) { if (!m_customLimits && var_type::type_traits::supports_range()) { float value; GetValue(value); if (value > m_valueMax && !m_bHardMax) { SetLimits(m_valueMin, nextNiceNumberAbove(value), 0.0, false, false); } if (value < m_valueMin && !m_bHardMin) { SetLimits(nextNiceNumberBelow(value), m_valueMax, 0.0, false, false); } } fMin = m_valueMin; fMax = m_valueMax; fStep = m_valueStep; bHardMin = m_bHardMin; bHardMax = m_bHardMax; } void ClearLimits() { SetLimits(0.0f, 0.0f, 0.0f, false, false); m_customLimits = false; } virtual bool HasCustomLimits() { return m_customLimits; } ////////////////////////////////////////////////////////////////////////// // Access operators. ////////////////////////////////////////////////////////////////////////// //! Cast to held type. operator T const& () const { return m_valueDef; } //! Assign operator for variable. void operator=(const T& value) { SetValue(value); } ////////////////////////////////////////////////////////////////////////// IVariable* Clone(bool bRecursive) const { Self* var = new Self(*this); return var; } ////////////////////////////////////////////////////////////////////////// void CopyValue(IVariable* fromVar) { assert(fromVar); T val; fromVar->Get(val); SetValue(val); } protected: ////////////////////////////////////////////////////////////////////////// template void SetValue(const P& value, bool bResolve = true) { T newValue = T(); //var_type::type_convertor convertor; var_type::type_convertor convertor; convertor(value, newValue); // compare old and new values. if (m_bForceModified || !var_type::compare(m_valueDef, newValue)) { m_valueDef = newValue; m_bForceModified = false; OnSetValue(false); } if (bResolve) { InitAssetResolver(newValue); } } ////////////////////////////////////////////////////////////////////////// template void GetValue(P& value) const { var_type::type_convertor convertor; convertor(m_valueDef, value); } template inline void InitAssetResolver(const P& value) { } inline void InitAssetResolver(const QString& value) { if (m_bResolving) { CVariableBase::CancelResolveRequest(functor(*this, &CVariable::OnResolved)); } m_bResolving = CVariableBase::StartResolveRequest(GetDataType(), value.toUtf8().data(), functor(*this, &CVariable::OnResolved)); } void OnResolved(uint32 id, bool success, const char* orgVal, const char* newVal) { if (success) { SetValue(QString::fromLatin1(newVal), false); } } protected: T m_valueDef; bool m_customLimits; bool m_bResolving; unsigned char m_bHardMin : 1; unsigned char m_bHardMax : 1; // Min/Max value. float m_valueMin, m_valueMax, m_valueStep; }; ////////////////////////////////////////////////////////////////////////// /** ************************************************************************************** * CVariableArray implements variable of type array of IVariables. *************************************************************************************** */ template class TVariableArray : public CVariable { typedef TVariableArray Self; public: using CVariable::GetType; TVariableArray() : CVariable() {}; // Copy Constructor. TVariableArray(const Self& var) : CVariable(var) {} //! Get name of parameter. virtual int GetSize() const { return sizeof(Self); }; virtual bool HasDefaultValue() const { for (Vars::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { if (!(*it)->HasDefaultValue()) { return false; } } return true; } virtual void ResetToDefault() { for (Vars::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { (*it)->ResetToDefault(); } } ////////////////////////////////////////////////////////////////////////// IVariable* Clone(bool bRecursive) const { Self* var = new Self(*this); for (Vars::const_iterator it = m_vars.begin(); it != m_vars.end(); ++it) { var->m_vars.push_back((*it)->Clone(bRecursive)); } return var; } ////////////////////////////////////////////////////////////////////////// void CopyValue(IVariable* fromVar) { assert(fromVar); if (fromVar->GetType() != GetType()) { return; } CVariable::CopyValue(fromVar); int numSrc = fromVar->GetNumVariables(); int numTrg = m_vars.size(); for (int i = 0; i < numSrc && i < numTrg; i++) { // Copy Every child variable. m_vars[i]->CopyValue(fromVar->GetVariable(i)); } } ////////////////////////////////////////////////////////////////////////// int GetNumVariables() const { return m_vars.size(); } IVariable* GetVariable(int index) const { assert(index >= 0 && index < (int)m_vars.size()); return m_vars[index]; } void AddVariable(IVariable* var) { m_vars.push_back(var); } void DeleteAllVariables() { m_vars.clear(); } ////////////////////////////////////////////////////////////////////////// void Serialize(XmlNodeRef node, bool load) { CVariable::Serialize(node, load); if (load) { // Loading. QString name; for (Vars::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { IVariable* var = *it; if (var->GetNumVariables()) { XmlNodeRef child = node->findChild(var->GetName().toUtf8().data()); if (child) { var->Serialize(child, load); } } else { var->Serialize(node, load); } } } else { // Saving. for (Vars::iterator it = m_vars.begin(); it != m_vars.end(); ++it) { IVariable* var = *it; if (var->GetNumVariables()) { XmlNodeRef child = node->newChild(var->GetName().toUtf8().data()); var->Serialize(child, load); } else { var->Serialize(node, load); } } } } protected: typedef std::vector Vars; Vars m_vars; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //! Selection list shown in combo box, for enumerated variable. struct IVarEnumList : public CRefCountBase { //! Get the name of specified value in enumeration, or NULL if out of range. virtual QString GetItemName(uint index) = 0; }; typedef _smart_ptr IVarEnumListPtr; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING; //! Selection list shown in combo box, for enumerated variable. template class CVarEnumListBase : public IVarEnumList { AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING public: CVarEnumListBase(){} ////////////////////////////////////////////////////////////////////////// virtual T NameToValue(const QString& name) = 0; ////////////////////////////////////////////////////////////////////////// virtual QString ValueToName(T const& value) = 0; //! Add new item to the selection. virtual void AddItem(const QString& name, const T& value) = 0; template static bool IsValueEqual(const TVal& v1, const TVal& v2) { return v1 == v2; } static bool IsValueEqual(const QString& v1, const QString& v2) { // Case insensitive compare. return QString::compare(v1, v2, Qt::CaseInsensitive) == 0; } protected: virtual ~CVarEnumListBase() {}; friend class _smart_ptr >; }; struct CUIEnumsDatabase_SEnum; ////////////////////////////////////////////////////////////////////////// AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING class EDITOR_CORE_API CVarGlobalEnumList : public CVarEnumListBase { AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING public: CVarGlobalEnumList(CUIEnumsDatabase_SEnum* pEnum); CVarGlobalEnumList(const QString& enumName); //! Get the name of specified value in enumeration. virtual QString GetItemName(uint index); virtual QString NameToValue(const QString& name); virtual QString ValueToName(const QString& value); //! Don't add anything to a global enum database virtual void AddItem(const QString& name, const QString& value) {} private: CUIEnumsDatabase_SEnum* m_pEnum; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //! Selection list shown in combo box, for enumerated variable. template class CVarEnumList : public CVarEnumListBase { public: using CVarEnumListBase::IsValueEqual; CVarEnumList(){} struct Item { QString name; T value; }; QString GetItemName(uint index) { if (index >= m_items.size()) { return NULL; } return m_items[index].name; }; ////////////////////////////////////////////////////////////////////////// T NameToValue(const QString& name) { for (int i = 0; i < m_items.size(); i++) { if (name == m_items[i].name) { return m_items[i].value; } } return T(); } ////////////////////////////////////////////////////////////////////////// QString ValueToName(T const& value) { for (int i = 0; i < m_items.size(); i++) { if (CVarEnumListBase::IsValueEqual(value, m_items[i].value)) { return m_items[i].name; } } return ""; } //! Add new item to the selection. void AddItem(const QString& name, const T& value) { Item item; item.name = name; item.value = value; m_items.push_back(item); }; protected: ~CVarEnumList() {}; private: std::vector m_items; }; ////////////////////////////////////////////////////////////////////////////////// // CVariableEnum is the same as CVariable but it display enumerated values in UI ////////////////////////////////////////////////////////////////////////////////// template class CVariableEnum : public CVariable { public: using CVariable::SetValue; using CVariable::GetFlags; using CVariable::OnSetValue; using CVariable::Set; using CVariable::m_valueDef; using CVariable::m_onSetEnumFuncs; ////////////////////////////////////////////////////////////////////////// CVariableEnum(){} //! Assign operator for variable. void operator=(const T& value) { CVariable::SetValue(value); } //! Add new item to the enumeration. void AddEnumItem(const char* name, const T& value) { AddEnumItem(QString(name), value); }; //! Add new item to the enumeration. void AddEnumItem(const QString& name, const T& value) { if (GetFlags() & IVariable::UI_USE_GLOBAL_ENUMS) // don't think adding makes sense { return; } if (!m_enum) { m_enum = new CVarEnumList(); } m_enum->AddItem(name, value); OnEnumsChanged(); }; void SetEnumList(CVarEnumListBase* enumList) { m_enum = enumList; OnSetValue(false); OnEnumsChanged(); } IVarEnumList* GetEnumList() const { return m_enum; } ////////////////////////////////////////////////////////////////////////// IVariable* Clone(bool bRecursive) const { CVariableEnum* var = new CVariableEnum(*this); return var; } virtual QString GetDisplayValue() const { if (m_enum) { return m_enum->ValueToName(m_valueDef); } else { return CVariable::GetDisplayValue(); } } virtual void SetDisplayValue(const QString& value) { if (m_enum) { Set(m_enum->NameToValue(value)); } else { Set(value); } } protected: void OnEnumsChanged() { // Call on set callback. for (auto it = m_onSetEnumFuncs.begin(); it != m_onSetEnumFuncs.end(); ++it) { // Call on set callback. (*it)(this); } } // Copy Constructor. CVariableEnum(const CVariableEnum& var) : CVariable(var) { m_enum = var.m_enum; } private: _smart_ptr > m_enum; }; ////////////////////////////////////////////////////////////////////////// // Smart pointers to variables. ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// template struct CSmartVariableBase { typedef TVar VarType; CSmartVariableBase() { pVar = new VarType(); } operator T const& () const { VarType* pV = pVar; return *pV; } //void operator=( const T& value ) { VarType *pV = pVar; *pV = value; } // Compare with pointer to variable. bool operator==(IVariable* pV) { return pVar == pV; } bool operator!=(IVariable* pV) { return pVar != pV; } operator VarType&() { VarType* pV = pVar; return *pV; } // Cast to CVariableBase& VarType& operator*() const { return *pVar; } VarType* operator->(void) const { return pVar; } VarType* GetVar() const { return pVar; }; protected: _smart_ptr pVar; }; ////////////////////////////////////////////////////////////////////////// template struct CSmartVariable : public CSmartVariableBase > { using CSmartVariableBase >::pVar; void operator=(const T& value) { CVariable* pV = pVar; *pV = value; } }; ////////////////////////////////////////////////////////////////////////// template struct CSmartVariableArrayT : public CSmartVariableBase > { using CSmartVariableBase >::pVar; void operator=(const T& value) { TVariableArray* pV = pVar; *pV = value; } }; ////////////////////////////////////////////////////////////////////////// template struct CSmartVariableEnum : public CSmartVariableBase > { using CSmartVariableBase >::pVar; CSmartVariableEnum(){} void operator=(const T& value) { CVariableEnum* pV = pVar; *pV = value; } void AddEnumItem(const QString& name, const T& value) { pVar->AddEnumItem(name, value); }; void SetEnumList(CVarEnumListBase* enumList) { pVar->EnableUpdateCallbacks(false); pVar->SetEnumList(enumList); pVar->EnableUpdateCallbacks(true); } }; ////////////////////////////////////////////////////////////////////////// struct CSmartVariableArray { typedef CVariableArray VarType; CSmartVariableArray() { pVar = new VarType(); } ////////////////////////////////////////////////////////////////////////// // Access operators. ////////////////////////////////////////////////////////////////////////// operator VarType&() { VarType* pV = pVar; return *pV; } VarType& operator*() const { return *pVar; } VarType* operator->(void) const { return pVar; } VarType* GetVar() const { return pVar; }; private: AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING _smart_ptr pVar; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING class EDITOR_CORE_API CVarBlock : public IVariableContainer { AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING public: // Dtor. virtual ~CVarBlock() {} //! Add variable to block. virtual void AddVariable(IVariable* var); //! Remove variable from block virtual bool DeleteVariable(IVariable* var, bool bRecursive = false); void AddVariable(IVariable* pVar, const char* varName, unsigned char dataType = IVariable::DT_SIMPLE); // This used from smart variable pointer. void AddVariable(CVariableBase& var, const char* varName, unsigned char dataType = IVariable::DT_SIMPLE); //! Returns number of variables in block. virtual int GetNumVariables() const { return static_cast(m_vars.size()); } //! Get pointer to stored variable by index. virtual IVariable* GetVariable(int index) const { assert(index >= 0 && index < m_vars.size()); return m_vars[index]; } // Clear all vars from VarBlock. virtual void DeleteAllVariables() { m_vars.clear(); }; //! Return true if variable block is empty (Does not have any vars). virtual bool IsEmpty() const { return m_vars.empty(); } // Returns true if var block contains specified variable. virtual bool IsContainsVariable(IVariable* pVar, bool bRecursive = true) const; //! Find variable by name. virtual IVariable* FindVariable(const char* name, bool bRecursive = true, bool bHumanName = false) const; ////////////////////////////////////////////////////////////////////////// //! Clone var block. CVarBlock* Clone(bool bRecursive) const; ////////////////////////////////////////////////////////////////////////// //! Copy variable values from specified var block. //! Do not create new variables, only copy values of existing ones. //! Should only be used to copy identical var blocks (eg. not Array type var copied to String type var) //! @param fromVarBlock Source variable block that contain copied values, must be identical to this var block. void CopyValues(const CVarBlock* fromVarBlock); ////////////////////////////////////////////////////////////////////////// //! Copy variable values from specified var block. //! Do not create new variables, only copy values of existing ones. //! Can be used to copy slightly different var blocks, matching performed by variable name. //! @param fromVarBlock Source variable block that contain copied values. void CopyValuesByName(CVarBlock* fromVarBlock); void OnSetValues(); ////////////////////////////////////////////////////////////////////////// //! Set UI_CREATE_SPLINE flags for all the varialbes in this Var Block. //! This is because when the data was changed for a spline variable, the spline need to be recreated to reflect the change. //! Set the flag to notify the spline variable. void SetRecreateSplines(); ////////////////////////////////////////////////////////////////////////// // Wire/Unwire other variable blocks. ////////////////////////////////////////////////////////////////////////// //! Wire to other variable block. //! Only equivalent VarBlocks can be wired (same number of variables with same type). //! Recursive wiring of array variables is supported. void Wire(CVarBlock* toVarBlock); //! Unwire var block. void Unwire(CVarBlock* varBlock); //! Add this callback to every variable in block (recursively). void AddOnSetCallback(IVariable::OnSetCallback func); //! Remove this callback from every variable in block (recursively). void RemoveOnSetCallback(IVariable::OnSetCallback func); ////////////////////////////////////////////////////////////////////////// void Serialize(XmlNodeRef vbNode, bool load); void ReserveNumVariables(int numVars); ////////////////////////////////////////////////////////////////////////// //! Gather resources in this variable block. virtual void GatherUsedResources(CUsedResources& resources); void EnableUpdateCallbacks(bool boEnable); IVariable* FindChildVar(const char* name, IVariable* pParentVar) const; void Sort(); protected: void SetCallbackToVar(IVariable::OnSetCallback func, IVariable* pVar, bool bAdd); void WireVar(IVariable* src, IVariable* trg, bool bWire); void GatherUsedResourcesInVar(IVariable* pVar, CUsedResources& resources); typedef std::vector Variables; AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING Variables m_vars; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; typedef _smart_ptr CVarBlockPtr; ////////////////////////////////////////////////////////////////////////// class EDITOR_CORE_API CVarObject : public QObject , public CRefCountBase { public: typedef IVariable::OnSetCallback VarOnSetCallback; CVarObject(); ~CVarObject(); void Serialize(XmlNodeRef node, bool load); CVarBlock* GetVarBlock() const { return m_vars; }; void AddVariable(CVariableBase& var, const QString& varName, VarOnSetCallback cb = NULL, unsigned char dataType = IVariable::DT_SIMPLE); void AddVariable(CVariableBase& var, const QString& varName, const QString& varHumanName, VarOnSetCallback cb = NULL, unsigned char dataType = IVariable::DT_SIMPLE); void AddVariable(CVariableArray& table, CVariableBase& var, const QString& varName, const QString& varHumanName, VarOnSetCallback cb = NULL, unsigned char dataType = IVariable::DT_SIMPLE); void ReserveNumVariables(int numVars); void RemoveVariable(IVariable* var); void EnableUpdateCallbacks(bool boEnable); void OnSetValues(); protected: //! Copy values of variables from other VarObject. //! Source object must be of same type. void CopyVariableValues(CVarObject* sourceObject); private: AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING CVarBlockPtr m_vars; AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING }; Q_DECLARE_METATYPE(IVariable *); #endif // CRYINCLUDE_EDITOR_UTIL_VARIABLE_H