merge stabilization/2106 into development
Signed-off-by: hultonha <hultonha@amazon.co.uk>
This commit is contained in:
@@ -689,6 +689,81 @@ namespace AZ
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Class__IndexAllowNil(lua_State* l)
|
||||
{
|
||||
LSV_BEGIN(l, 1);
|
||||
|
||||
// calling format __index(table,key)
|
||||
lua_getmetatable(l, -2); // load the userdata metatable
|
||||
int metaTableIndex = lua_gettop(l);
|
||||
|
||||
// Check if the key is string, if so we expect it to be a function or property name
|
||||
// otherwise we allow users to provide custom index handlers
|
||||
// Technically we can allow strings too, but it will clash with function/property names and it be hard to figure
|
||||
// out what is going on from with in the system.
|
||||
if (lua_type(l, -2) == LUA_TSTRING)
|
||||
{
|
||||
lua_pushvalue(l, -2); // duplicate the key
|
||||
lua_rawget(l, -2); // load the value at this index
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushliteral(l, "__AZ_Index");
|
||||
lua_rawget(l, -2); // check if the user provided custom Index method in the class metatable
|
||||
if (lua_isnil(l, -1)) // if not report an error
|
||||
{
|
||||
lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error
|
||||
if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX);
|
||||
}
|
||||
ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Invalid index type [], should be string! '%s:%s'!", lua_tostring(l, -1), lua_tostring(l, -4));
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have custom index handler
|
||||
lua_pushvalue(l, -4); // duplicate the table (class pointer)
|
||||
lua_pushvalue(l, -4); // duplicate the index value for the call
|
||||
lua_call(l, 2, 1); // call the function
|
||||
}
|
||||
|
||||
lua_remove(l, metaTableIndex); // remove the metatable
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!lua_isnil(l, -1))
|
||||
{
|
||||
if (lua_tocfunction(l, -1) == &Internal::LuaPropertyTagHelper) // if it's a property
|
||||
{
|
||||
lua_getupvalue(l, -1, 1); // push on the stack the getter function
|
||||
lua_remove(l, -2); // remove property object
|
||||
|
||||
if (lua_isnil(l, -1))
|
||||
{
|
||||
lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error
|
||||
if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX);
|
||||
}
|
||||
|
||||
ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Property '%s:%s' is write only", lua_tostring(l, -1), lua_tostring(l, -4));
|
||||
lua_pop(l, 1); // pop class name
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(l, -4); // copy the user data to be passed as a this pointer.
|
||||
lua_call(l, 1, 1); // call a function with one argument (this pointer) and 1 result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_remove(l, metaTableIndex); // remove the metatable
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// Class__NewIndex
|
||||
// [3/22/2012]
|
||||
@@ -826,30 +901,6 @@ namespace AZ
|
||||
return 1;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ClassMetatable__Index
|
||||
// [3/24/2012]
|
||||
//=========================================================================
|
||||
int ClassMetatable__Index(lua_State* l)
|
||||
{
|
||||
// since the Class__Index is generic function (ask for the class metatable)
|
||||
// we can reuse the code for the base metatable (which is a metatable
|
||||
// of the class metatable)
|
||||
return Class__Index(l);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ClassMetatable__NewIndex
|
||||
// [3/30/2012]
|
||||
//=========================================================================
|
||||
int ClassMetatable__NewIndex(lua_State* l)
|
||||
{
|
||||
// since the Class__NewIndex is generic function (ask for the class metatable)
|
||||
// we can reuse the code for the base metatable (which is a metatable
|
||||
// of the class metatable)
|
||||
return Class__NewIndex(l);
|
||||
}
|
||||
|
||||
inline size_t BufferStringCopy(const char* source, char* destination, size_t destinationSize)
|
||||
{
|
||||
size_t srcLen = strlen(source);
|
||||
@@ -5053,9 +5104,20 @@ LUA_API const Node* lua_getDummyNode()
|
||||
lua_pushcclosure(m_lua, &DefaultBehaviorCaller::Destroy, 0);
|
||||
lua_rawset(m_lua, -3);
|
||||
|
||||
lua_pushliteral(m_lua, "__index");
|
||||
lua_pushcclosure(m_lua, &Internal::Class__Index, 0);
|
||||
lua_rawset(m_lua, -3);
|
||||
{
|
||||
lua_pushliteral(m_lua, "__index");
|
||||
|
||||
if (FindAttribute(Script::Attributes::UseClassIndexAllowNil, behaviorClass->m_attributes))
|
||||
{
|
||||
lua_pushcclosure(m_lua, &Internal::Class__IndexAllowNil, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushcclosure(m_lua, &Internal::Class__Index, 0);
|
||||
}
|
||||
|
||||
lua_rawset(m_lua, -3);
|
||||
}
|
||||
|
||||
lua_pushliteral(m_lua, "__newindex");
|
||||
lua_pushcclosure(m_lua, &Internal::Class__NewIndex, 0);
|
||||
|
||||
@@ -16,19 +16,20 @@ namespace AZ
|
||||
{
|
||||
namespace Attributes
|
||||
{
|
||||
const static AZ::Crc32 Ignore = AZ_CRC("ScriptIgnore", 0xeb7615e1); ///< Don't use the element in the script reflection
|
||||
const static AZ::Crc32 ClassNameOverride = AZ_CRC("ScriptClassNameOverride", 0x891238a3); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
|
||||
const static AZ::Crc32 MethodOverride = AZ_CRC("ScriptFunctionOverride", 0xf89a7882); ///< Use a custom function in the attribute instead of the function
|
||||
const static AZ::Crc32 ConstructorOverride = AZ_CRC("ConstructorOverride", 0xef5ce4aa); ///< You can provide a custom constructor to be called when created from Lua script
|
||||
const static AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
|
||||
const static AZ::Crc32 GenericConstructorOverride = AZ_CRC("GenericConstructorOverride", 0xe6a1698e); ///< You can provide a custom constructor to be called when creating a script
|
||||
const static AZ::Crc32 ReaderWriterOverride = AZ_CRC("ReaderWriterOverride", 0x1ad9ce2a); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
|
||||
const static AZ::Crc32 ConstructibleFromNil = AZ_CRC("ConstructibleFromNil", 0x23908169); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided.
|
||||
const static AZ::Crc32 ToolTip = AZ_CRC("ToolTip", 0xa1b95fb0); ///< Add a tooltip for a method/event/property
|
||||
const static AZ::Crc32 Category = AZ_CRC("Category", 0x064c19c1); ///< Provide a category to allow for partitioning/sorting/ordering of the element
|
||||
const static AZ::Crc32 Deprecated = AZ_CRC("Deprecated", 0xfe49a138); ///< Marks a reflected class, method, EBus or property as deprecated.
|
||||
const static AZ::Crc32 DisallowBroadcast = AZ_CRC("DisallowBroadcast", 0x389b0ac7); ///< Marks a reflected EBus as not allowing Broadcasts, only Events.
|
||||
const static AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value
|
||||
static constexpr AZ::Crc32 Ignore = AZ_CRC_CE("ScriptIgnore"); ///< Don't use the element in the script reflection
|
||||
static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
|
||||
static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function
|
||||
static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script
|
||||
static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
|
||||
static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script
|
||||
static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
|
||||
static constexpr AZ::Crc32 ConstructibleFromNil = AZ_CRC_CE("ConstructibleFromNil"); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided.
|
||||
static constexpr AZ::Crc32 ToolTip = AZ_CRC_CE("ToolTip"); ///< Add a tooltip for a method/event/property
|
||||
static constexpr AZ::Crc32 Category = AZ_CRC_CE("Category"); ///< Provide a category to allow for partitioning/sorting/ordering of the element
|
||||
static constexpr AZ::Crc32 Deprecated = AZ_CRC_CE("Deprecated"); ///< Marks a reflected class, method, EBus or property as deprecated.
|
||||
static constexpr AZ::Crc32 DisallowBroadcast = AZ_CRC_CE("DisallowBroadcast"); ///< Marks a reflected EBus as not allowing Broadcasts, only Events.
|
||||
static constexpr AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value
|
||||
static constexpr AZ::Crc32 UseClassIndexAllowNil = AZ_CRC_CE("UseClassIndexAllowNil"); ///< Use the Class__IndexAllowNil method, which will not report an error on accessing undeclared values (allows for nil)
|
||||
|
||||
//! Attribute which stores BehaviorAzEventDescription structure which contains
|
||||
//! the script name of an AZ::Event and the name of it's parameter arguments
|
||||
@@ -39,11 +40,11 @@ namespace AZ
|
||||
static constexpr AZ::Crc32 EventParameterTypes = AZ_CRC_CE("EventParameterTypes");
|
||||
|
||||
///< Recommends that the Lua runtime look up the member function in the meta table of the first argument, rather than in the original table
|
||||
const static AZ::Crc32 TreatAsMemberFunction = AZ_CRC("TreatAsMemberFunction", 0x64be831a);
|
||||
static constexpr AZ::Crc32 TreatAsMemberFunction = AZ_CRC_CE("TreatAsMemberFunction");
|
||||
|
||||
///< This attribute can be attached to the EditContext Attribute of a reflected class, the BehaviorContext Attribute of a reflected class, method, ebus or property.
|
||||
///< ExcludeFlags can be used to prevent elements from appearing in List, Documentation, etc...
|
||||
const static AZ::Crc32 ExcludeFrom = AZ_CRC("ExcludeFrom", 0xa98972fe);
|
||||
static constexpr AZ::Crc32 ExcludeFrom = AZ_CRC_CE("ExcludeFrom");
|
||||
enum ExcludeFlags : AZ::u64
|
||||
{
|
||||
List = 1 << 0, //< The reflected item will be excluded from any list (e.g. node palette)
|
||||
@@ -54,7 +55,7 @@ namespace AZ
|
||||
};
|
||||
|
||||
//! Used to specify the usage of a Behavior Context element (e.g. Class or EBus) designed for automation scripts
|
||||
const static AZ::Crc32 Scope = AZ_CRC("Scope", 0x00af55d3);
|
||||
static constexpr AZ::Crc32 Scope = AZ_CRC_CE("Scope");
|
||||
enum class ScopeFlags : AZ::u64
|
||||
{
|
||||
Launcher = 1 << 0, //< a type meant for game run-time Launcher client (default value)
|
||||
@@ -63,15 +64,15 @@ namespace AZ
|
||||
};
|
||||
|
||||
//! Provide a partition hierarchy in a string dotted notation to namespace a script element
|
||||
const static AZ::Crc32 Module = AZ_CRC("Module", 0x0c242628);
|
||||
static constexpr AZ::Crc32 Module = AZ_CRC_CE("Module");
|
||||
|
||||
//! Provide an alternate name for script elements such as helpful PEP8 Python methods and property aliases
|
||||
const static AZ::Crc32 Alias = AZ_CRC("Alias", 0xe16c6b94);
|
||||
static constexpr AZ::Crc32 Alias = AZ_CRC_CE("Alias");
|
||||
|
||||
const static AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC("ScriptEventParam", 0xa41e4cb0);
|
||||
const static AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC("ScriptEventReturn", 0xf89b5337);
|
||||
static constexpr AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC_CE("ScriptEventParam");
|
||||
static constexpr AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC_CE("ScriptEventReturn");
|
||||
|
||||
const static AZ::Crc32 Storage = AZ_CRC("ScriptStorage", 0xcd95b44d);
|
||||
static constexpr AZ::Crc32 Storage = AZ_CRC_CE("ScriptStorage");
|
||||
enum class StorageType
|
||||
{
|
||||
ScriptOwn, // default, Host allocated memory, Lua will destruct object, Lua will free host-memory via host-supplied function
|
||||
@@ -79,7 +80,7 @@ namespace AZ
|
||||
Value, // Object is Lua allocated memory, Lua will destruct object, Lua will free Lua-memory
|
||||
};
|
||||
|
||||
const static AZ::Crc32 Operator = AZ_CRC("ScriptOperator", 0xfee681b6);
|
||||
static constexpr AZ::Crc32 Operator = AZ_CRC_CE("ScriptOperator");
|
||||
enum class OperatorType
|
||||
{
|
||||
// note storage policy can be T*,T (only if we store raw pointers), shared_ptr<T>, intrusive pointer<T>
|
||||
@@ -100,7 +101,7 @@ namespace AZ
|
||||
IndexWrite, // given a key/index and a value, you can store it in the class
|
||||
};
|
||||
|
||||
const static AZ::Crc32 AssetType = AZ_CRC("AssetType", 0xabbf8d5f); ///< Provide an asset type for a generic AssetId method
|
||||
static constexpr AZ::Crc32 AssetType = AZ_CRC_CE("AssetType"); ///< Provide an asset type for a generic AssetId method
|
||||
} // Attributes
|
||||
} // Script
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace AZ
|
||||
//=========================================================================
|
||||
AZStd::string ExtractUserMessage(const ScriptDataContext& dc)
|
||||
{
|
||||
AZStd::string userMessage = "Condition failed";
|
||||
const int argCount = dc.GetNumArguments();
|
||||
if (argCount > 0 && dc.IsString(argCount - 1))
|
||||
{
|
||||
@@ -33,12 +32,12 @@ namespace AZ
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
userMessage = value;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userMessage;
|
||||
return "ExtractUserMessage from print/Debug.Log/Warn/Error/Assert failed. Consider wrapping your argument in tostring().";
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace AzPhysics
|
||||
AZ::Transform m_start = AZ::Transform::CreateIdentity(); //!< World space start position. Assumes only rotation + translation (no scaling).
|
||||
AZ::Vector3 m_direction = AZ::Vector3::CreateZero(); //!< World space direction (Should be normalized)
|
||||
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfiguration; //!< Shape information.
|
||||
SceneQuery::HitFlags m_hitFlags = SceneQuery::HitFlags::Default; //!< Query behavior flags
|
||||
SceneQuery::HitFlags m_hitFlags = SceneQuery::HitFlags::Default | SceneQuery::HitFlags::MTD; //!< Query behavior flags. MTD Is On by default to correctly report objects that are initially in contact with the start pose.
|
||||
SceneQuery::FilterCallback m_filterCallback = nullptr; //!< Hit filtering function
|
||||
bool m_reportMultipleHits = false; //!< flag to have the cast stop after the first hit or return all hits along the query.
|
||||
};
|
||||
|
||||
+19
-10
@@ -46,10 +46,11 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
}
|
||||
}
|
||||
|
||||
template<typename EntityPtr>
|
||||
void OrganizeEntitiesForSorting(
|
||||
AzFramework::Spawnable::EntityList& entities,
|
||||
AZStd::vector<EntityPtr>& entities,
|
||||
AZStd::unordered_set<AZ::EntityId>& existingEntityIds,
|
||||
AZStd::unordered_map<AZ::EntityId, AzFramework::Spawnable::EntityList>& parentIdToChildren,
|
||||
AZStd::unordered_map<AZ::EntityId, AZStd::vector<EntityPtr>>& parentIdToChildren,
|
||||
AZStd::vector<AZ::EntityId>& candidateIds,
|
||||
size_t& removedEntitiesCount)
|
||||
{
|
||||
@@ -90,7 +91,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
// entities with no transform component will be treated like entities with no parent.
|
||||
AZ::EntityId parentId;
|
||||
if (AZ::TransformInterface* transformInterface =
|
||||
AZ::EntityUtils::FindFirstDerivedComponent<AZ::TransformInterface>(entity.get()))
|
||||
AZ::EntityUtils::FindFirstDerivedComponent<AZ::TransformInterface>(&(*entity)))
|
||||
{
|
||||
parentId = transformInterface->GetParentId();
|
||||
if (parentId == entityId)
|
||||
@@ -104,8 +105,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
}
|
||||
|
||||
auto& children = parentIdToChildren[parentId];
|
||||
children.emplace_back(nullptr);
|
||||
children.back().swap(entity);
|
||||
children.emplace_back(AZStd::move(entity));
|
||||
}
|
||||
|
||||
// clear 'entities', we'll refill it in sorted order.
|
||||
@@ -125,9 +125,10 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
}
|
||||
|
||||
template<typename EntityPtr>
|
||||
void TraceParentingLoop(
|
||||
const AZ::EntityId& parentFromLoopId,
|
||||
const AZStd::unordered_map<AZ::EntityId, AzFramework::Spawnable::EntityList>& parentIdToChildren)
|
||||
const AZStd::unordered_map<AZ::EntityId, AZStd::vector<EntityPtr>>& parentIdToChildren)
|
||||
{
|
||||
|
||||
// Find name to use in warning message
|
||||
@@ -153,16 +154,22 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
parentFromLoopId.ToString().c_str());
|
||||
}
|
||||
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable)
|
||||
{
|
||||
auto& entities = spawnable.GetEntities();
|
||||
SortEntitiesByTransformHierarchy(spawnable.GetEntities());
|
||||
}
|
||||
|
||||
template<typename EntityPtr>
|
||||
void SortEntitiesByTransformHierarchy(AZStd::vector<EntityPtr>& entities)
|
||||
{
|
||||
const size_t originalEntityCount = entities.size();
|
||||
|
||||
// IDs of those present in 'entities'. Does not include parent ID if parent not found in 'entities'
|
||||
AZStd::unordered_set<AZ::EntityId> existingEntityIds;
|
||||
|
||||
// map children by their parent ID (even if parent not found in 'entities')
|
||||
AZStd::unordered_map<AZ::EntityId, AzFramework::Spawnable::EntityList> parentIdToChildren;
|
||||
AZStd::unordered_map<AZ::EntityId, AZStd::vector<EntityPtr>> parentIdToChildren;
|
||||
|
||||
// use 'candidateIds' to track the parent IDs we're going to process next.
|
||||
AZStd::vector<AZ::EntityId> candidateIds;
|
||||
@@ -199,8 +206,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
for (auto& child : foundChildren->second)
|
||||
{
|
||||
candidateIds.push_back(child->GetId());
|
||||
entities.emplace_back(nullptr);
|
||||
entities.back().swap(child);
|
||||
entities.emplace_back(AZStd::move(child));
|
||||
}
|
||||
|
||||
parentIdToChildren.erase(foundChildren);
|
||||
@@ -217,4 +223,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
}
|
||||
|
||||
// Explicit specializations of SortEntitiesByTransformHierarchy (have to be in cpp due to clang errors)
|
||||
template void SortEntitiesByTransformHierarchy(AZStd::vector<AZ::Entity*>& entities);
|
||||
template void SortEntitiesByTransformHierarchy(AZStd::vector<AZStd::unique_ptr<AZ::Entity>>& entities);
|
||||
} // namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
@@ -16,4 +16,8 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
bool CreateSpawnable(AzFramework::Spawnable& spawnable, const PrefabDom& prefabDom, AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& referencedAssets);
|
||||
|
||||
void SortEntitiesByTransformHierarchy(AzFramework::Spawnable& spawnable);
|
||||
|
||||
template <typename EntityPtr>
|
||||
void SortEntitiesByTransformHierarchy(AZStd::vector<EntityPtr>& entities);
|
||||
|
||||
} // namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
Reference in New Issue
Block a user