Merge branch 'development' into memory/benchmarks
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/scoped_ptr.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
|
||||
@@ -22,7 +21,7 @@ namespace AzFramework
|
||||
AZStd::scoped_ptr<ProcessWatcher> pWatcher(LaunchProcess(processLaunchInfo, communicationType));
|
||||
if (!pWatcher)
|
||||
{
|
||||
AZ_TracePrintf("Process Watcher", "ProcessWatcher::LaunchProcessAndRetrieveOutput: Unable to launch process '%s %s'\n", processLaunchInfo.m_processExecutableString.c_str(), processLaunchInfo.m_commandlineParameters.c_str());
|
||||
AZ_TracePrintf("Process Watcher", "ProcessWatcher::LaunchProcessAndRetrieveOutput: Unable to launch process '%s %s'\n", processLaunchInfo.m_processExecutableString.c_str(), processLaunchInfo.GetCommandLineParametersAsString().c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -31,7 +30,7 @@ namespace AzFramework
|
||||
ProcessCommunicator* pCommunicator = pWatcher->GetCommunicator();
|
||||
if (!pCommunicator || !pCommunicator->IsValid())
|
||||
{
|
||||
AZ_TracePrintf("Process Watcher", "ProcessWatcher::LaunchProcessAndRetrieveOutput: No communicator for watcher's process (%s %s)!\n", processLaunchInfo.m_processExecutableString.c_str(), processLaunchInfo.m_commandlineParameters.c_str());
|
||||
AZ_TracePrintf("Process Watcher", "ProcessWatcher::LaunchProcessAndRetrieveOutput: No communicator for watcher's process (%s %s)!\n", processLaunchInfo.m_processExecutableString.c_str(), processLaunchInfo.GetCommandLineParametersAsString().c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzFramework/Process/ProcessCommon_fwd.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -37,7 +38,7 @@ namespace AzFramework
|
||||
* On windows, the command line will be passed as-is to the shell (with quotes)
|
||||
* on UNIX/OSX, the command line will be converted as appropriate (quotes removed, but used to chop up parameters)
|
||||
*/
|
||||
AZStd::string m_commandlineParameters;
|
||||
AZStd::variant<AZStd::string, AZStd::vector<AZStd::string>> m_commandlineParameters;
|
||||
|
||||
/**
|
||||
* (optional) If you specify a working directory, the command will be executed with that directory as the current directory.
|
||||
@@ -50,6 +51,8 @@ namespace AzFramework
|
||||
|
||||
//Not Supported On Mac
|
||||
bool m_showWindow = true;
|
||||
|
||||
AZStd::string GetCommandLineParametersAsString() const;
|
||||
};
|
||||
|
||||
static const AZ::u32 INFINITE_TIMEOUT = (AZ::u32) -1;
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AzFramework::ProjectManager
|
||||
return ProjectPathCheckResult::ProjectManagerLaunchFailed;
|
||||
}
|
||||
|
||||
bool LaunchProjectManager([[maybe_unused]]const AZStd::string& commandLineArgs)
|
||||
bool LaunchProjectManager([[maybe_unused]] const AZStd::vector<AZStd::string>& commandLineArgs)
|
||||
{
|
||||
bool launchSuccess = false;
|
||||
#if (AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER)
|
||||
@@ -105,7 +105,12 @@ namespace AzFramework::ProjectManager
|
||||
}
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
processLaunchInfo.m_commandlineParameters = executablePath.String() + commandLineArgs;
|
||||
|
||||
AZStd::vector<AZStd::string> launchCmd = { executablePath.String() };
|
||||
launchCmd.insert(launchCmd.end(), commandLineArgs.begin(), commandLineArgs.end());
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZStd::move(launchCmd);
|
||||
|
||||
launchSuccess = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
}
|
||||
if (ownsSystemAllocator)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AzFramework::ProjectManager
|
||||
@@ -29,5 +30,5 @@ namespace AzFramework::ProjectManager
|
||||
//! current executable. Requires the o3de cli and python.
|
||||
//! @param commandLineArgs additional command line arguments to provide to the project manager
|
||||
//! @return true on success, false if failed to find or launch the executable
|
||||
bool LaunchProjectManager(const AZStd::string& commandLineArgs = "");
|
||||
bool LaunchProjectManager(const AZStd::vector<AZStd::string>& commandLineArgs = {});
|
||||
} // AzFramework::ProjectManager
|
||||
|
||||
@@ -63,25 +63,30 @@ namespace AzFramework::Terrain
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Terrain")
|
||||
->Attribute(AZ::Script::Attributes::Module, "terrain")
|
||||
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetNormal)
|
||||
->Event("GetMaxSurfaceWeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeight)
|
||||
->Event("GetMaxSurfaceWeightFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetMaxSurfaceWeightFromVector2)
|
||||
->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeights)
|
||||
->Event("GetSurfaceWeightsFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeightsFromVector2)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetHeight)
|
||||
->Event("GetHeightFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetHeightFromFloats)
|
||||
->Event("GetHeightFromVector2", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetHeightFromVector2)
|
||||
->Event("GetNormal", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetNormal)
|
||||
->Event("GetMaxSurfaceWeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetMaxSurfaceWeight)
|
||||
->Event(
|
||||
"GetMaxSurfaceWeightFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetMaxSurfaceWeightFromVector2)
|
||||
->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfaceWeights)
|
||||
->Event(
|
||||
"GetSurfaceWeightsFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfaceWeightsFromVector2)
|
||||
->Event("GetIsHole", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHole)
|
||||
->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats)
|
||||
->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePoint)
|
||||
->Event("GetSurfacePointFromVector2",
|
||||
->Event(
|
||||
"GetSurfacePointFromVector2",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePointFromVector2)
|
||||
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
|
||||
->Event("GetTerrainHeightQueryResolution",
|
||||
->Event(
|
||||
"GetTerrainHeightQueryResolution",
|
||||
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
|
||||
->Event("GetHeight", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightVal)
|
||||
->Event("GetHeightFromVector2", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightValFromVector2)
|
||||
->Event("GetHeightFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetHeightValFromFloats)
|
||||
;
|
||||
;
|
||||
|
||||
behaviorContext->EBus<AzFramework::Terrain::TerrainDataNotificationBus>("TerrainDataNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
|
||||
@@ -150,24 +150,49 @@ namespace AzFramework
|
||||
GetSurfacePointFromVector2(inPosition, result, sampleFilter);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Functions without the optional bool* parameter that can be used from Python tests.
|
||||
float GetHeightVal(AZ::Vector3 position, Sampler sampler = Sampler::BILINEAR) const
|
||||
// Private variations of the GetHeight.., GetNormal..., GetMaxSurfaceWeight..., GetSurfaceWeights... APIs
|
||||
// exposed to BehaviorContext that does not use the terrainExists "out" parameter.
|
||||
float BehaviorContextGetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR)
|
||||
{
|
||||
bool terrainExists;
|
||||
return GetHeight(position, sampler, &terrainExists);
|
||||
return GetHeight(position, sampler, nullptr);
|
||||
}
|
||||
|
||||
float GetHeightValFromVector2(AZ::Vector2 position, Sampler sampler = Sampler::BILINEAR) const
|
||||
float BehaviorContextGetHeightFromVector2(const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR)
|
||||
{
|
||||
bool terrainExists;
|
||||
return GetHeightFromVector2(position, sampler, &terrainExists);
|
||||
return GetHeightFromVector2(position, sampler, nullptr);
|
||||
}
|
||||
|
||||
float GetHeightValFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR) const
|
||||
float BehaviorContextGetHeightFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR)
|
||||
{
|
||||
bool terrainExists;
|
||||
return GetHeightFromFloats(x, y, sampler, &terrainExists);
|
||||
return GetHeightFromFloats(x, y, sampler, nullptr);
|
||||
}
|
||||
AZ::Vector3 BehaviorContextGetNormal(const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR)
|
||||
{
|
||||
return GetNormal(position, sampleFilter, nullptr);
|
||||
}
|
||||
SurfaceData::SurfaceTagWeight BehaviorContextGetMaxSurfaceWeight(
|
||||
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR)
|
||||
{
|
||||
return GetMaxSurfaceWeight(position, sampleFilter, nullptr);
|
||||
}
|
||||
SurfaceData::SurfaceTagWeight BehaviorContextGetMaxSurfaceWeightFromVector2(
|
||||
const AZ::Vector2& inPosition, Sampler sampleFilter = Sampler::DEFAULT)
|
||||
{
|
||||
return GetMaxSurfaceWeightFromVector2(inPosition, sampleFilter, nullptr);
|
||||
}
|
||||
SurfaceData::SurfaceTagWeightList BehaviorContextGetSurfaceWeights(
|
||||
const AZ::Vector3& inPosition,
|
||||
Sampler sampleFilter = Sampler::DEFAULT)
|
||||
{
|
||||
SurfaceData::SurfaceTagWeightList list;
|
||||
GetSurfaceWeights(inPosition, list, sampleFilter, nullptr);
|
||||
return list;
|
||||
}
|
||||
SurfaceData::SurfaceTagWeightList BehaviorContextGetSurfaceWeightsFromVector2(
|
||||
const AZ::Vector2& inPosition,
|
||||
Sampler sampleFilter = Sampler::DEFAULT)
|
||||
{
|
||||
SurfaceData::SurfaceTagWeightList list;
|
||||
GetSurfaceWeightsFromVector2(inPosition, list, sampleFilter, nullptr);
|
||||
return list;
|
||||
}
|
||||
};
|
||||
using TerrainDataRequestBus = AZ::EBus<TerrainDataRequests>;
|
||||
|
||||
@@ -335,10 +335,13 @@ namespace AzFramework
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const float rotateSpeed = m_rotateSpeedFn();
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
const float deltaPitch = aznumeric_cast<float>(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
const float deltaYaw = aznumeric_cast<float>(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
|
||||
nextCamera.m_pitch -= deltaPitch;
|
||||
nextCamera.m_yaw -= deltaYaw;
|
||||
nextCamera.m_yaw = WrapYawRotation(nextCamera.m_yaw);
|
||||
|
||||
if (m_constrainPitch())
|
||||
{
|
||||
nextCamera.m_pitch = ClampPitchRotation(nextCamera.m_pitch);
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace AzFramework
|
||||
|
||||
struct WindowSize;
|
||||
|
||||
//! Tolerance to use when limiting pitch to avoid reaching +/-Pi/2 exactly.
|
||||
constexpr float CameraPitchTolerance = 1.0e-4f;
|
||||
|
||||
//! Returns Euler angles (pitch, roll, yaw) for the incoming orientation.
|
||||
//! @note Order of rotation is Z, Y, X.
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
|
||||
@@ -318,11 +321,26 @@ namespace AzFramework
|
||||
return m_handlingEvents;
|
||||
}
|
||||
|
||||
//! Clamps pitch to be +/-90 degrees (-Pi/2, Pi/2).
|
||||
//! Returns min/max values for camera pitch (in radians).
|
||||
inline AZStd::tuple<float, float> CameraPitchMinMaxRadians()
|
||||
{
|
||||
return { -AZ::Constants::HalfPi, AZ::Constants::HalfPi };
|
||||
}
|
||||
|
||||
//! Returns min/max values for camera pitch (in radians) including a small tolerance at each
|
||||
//! extreme (looking directly up or down) to avoid floating point accuracy issues.
|
||||
inline AZStd::tuple<float, float> CameraPitchMinMaxRadiansWithTolerance()
|
||||
{
|
||||
const auto [pitchMinRadians, pitchMaxRadians] = CameraPitchMinMaxRadians();
|
||||
return { pitchMinRadians + CameraPitchTolerance, pitchMaxRadians - CameraPitchTolerance };
|
||||
}
|
||||
|
||||
//! Clamps pitch to be +/-90 degrees (-Pi/2, Pi/2) with a minor tolerance at each extreme.
|
||||
//! @param pitch Pitch angle in radians.
|
||||
inline float ClampPitchRotation(const float pitch)
|
||||
{
|
||||
return AZ::GetClamp(pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
|
||||
const auto [pitchMin, pitchMax] = CameraPitchMinMaxRadiansWithTolerance();
|
||||
return AZ::GetClamp(pitch, pitchMin, pitchMax);
|
||||
}
|
||||
|
||||
//! Ensures yaw wraps between 0 and 360 degrees (0, 2Pi).
|
||||
|
||||
+20
-1
@@ -6,10 +6,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -83,4 +83,23 @@ namespace AzFramework
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
|
||||
{
|
||||
struct CommandLineParametersVisitor
|
||||
{
|
||||
AZStd::string operator()(const AZStd::string& commandLine) const
|
||||
{
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
AZStd::string operator()(const AZStd::vector<AZStd::string>& commandLineArray) const
|
||||
{
|
||||
AZStd::string commandLineResult;
|
||||
AZ::StringFunc::Join(commandLineResult, commandLineArray.begin(), commandLineArray.end(), " ");
|
||||
return commandLineResult;
|
||||
}
|
||||
};
|
||||
return AZStd::visit(CommandLineParametersVisitor{}, m_commandlineParameters);
|
||||
}
|
||||
} //namespace AzFramework
|
||||
|
||||
+64
-30
@@ -10,12 +10,11 @@
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
@@ -220,36 +219,52 @@ namespace AzFramework
|
||||
// this is so that the callers (which could be numerous) do not have to worry about this and sprinkle ifdefs
|
||||
// all over their code.
|
||||
// We'll convert this to UNIX style command line parameters by counting and eliminating quotes:
|
||||
|
||||
AZStd::vector<AZStd::string> commandTokens;
|
||||
|
||||
AZStd::string outputString;
|
||||
bool inQuotes = false;
|
||||
for (const char currentChar : processLaunchInfo.m_commandlineParameters)
|
||||
{
|
||||
if (currentChar == '"')
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else if ((currentChar == ' ') && (!inQuotes))
|
||||
{
|
||||
// its a space outside of quotes, so it ends the current parameter
|
||||
commandTokens.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Its a normal character, or its a space inside quotes
|
||||
outputString.push_back(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outputString.empty())
|
||||
// Struct uses overloaded operator() to quote command line arguments based
|
||||
// on whether a string or a vector<string> was supplied
|
||||
struct EscapeCommandArguments
|
||||
{
|
||||
commandTokens.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
|
||||
void operator()(const AZStd::string& commandParameterString)
|
||||
{
|
||||
AZStd::string outputString;
|
||||
bool inQuotes = false;
|
||||
for (size_t pos = 0; pos < commandParameterString.size(); ++pos)
|
||||
{
|
||||
char currentChar = commandParameterString[pos];
|
||||
if (currentChar == '"')
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else if ((currentChar == ' ') && (!inQuotes))
|
||||
{
|
||||
// its a space outside of quotes, so it ends the current parameter
|
||||
commandArray.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Its a normal character, or its a space inside quotes
|
||||
outputString.push_back(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outputString.empty())
|
||||
{
|
||||
commandArray.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const AZStd::vector<AZStd::string>& commandParameterArray)
|
||||
{
|
||||
commandArray = commandParameterArray;
|
||||
}
|
||||
AZStd::vector<AZStd::string>& commandArray;
|
||||
};
|
||||
|
||||
AZStd::vector<AZStd::string> commandTokens;
|
||||
AZStd::visit(EscapeCommandArguments{ commandTokens }, processLaunchInfo.m_commandlineParameters);
|
||||
|
||||
if (!processLaunchInfo.m_processExecutableString.empty())
|
||||
{
|
||||
commandTokens.insert(commandTokens.begin(), processLaunchInfo.m_processExecutableString);
|
||||
@@ -452,4 +467,23 @@ namespace AzFramework
|
||||
|
||||
kill(m_pWatcherData->m_childProcessId, SIGKILL);
|
||||
}
|
||||
|
||||
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
|
||||
{
|
||||
struct CommandLineParametersVisitor
|
||||
{
|
||||
AZStd::string operator()(const AZStd::string& commandLine) const
|
||||
{
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
AZStd::string operator()(const AZStd::vector<AZStd::string>& commandLineArray) const
|
||||
{
|
||||
AZStd::string commandLineResult;
|
||||
AZ::StringFunc::Join(commandLineResult, commandLineArray.begin(), commandLineArray.end(), " ");
|
||||
return commandLineResult;
|
||||
}
|
||||
};
|
||||
return AZStd::visit(CommandLineParametersVisitor{}, m_commandlineParameters);
|
||||
}
|
||||
} //namespace AzFramework
|
||||
|
||||
+64
-41
@@ -11,13 +11,12 @@
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
@@ -210,46 +209,51 @@ namespace AzFramework
|
||||
// this is so that the callers (which could be numerous) do not have to worry about this and sprinkle ifdefs
|
||||
// all over their code.
|
||||
// We'll convert this to UNIX style command line parameters by counting and eliminating quotes:
|
||||
|
||||
|
||||
// Struct uses overloaded operator() to quote command line arguments based
|
||||
// on whether a string or a vector<string> was supplied
|
||||
struct EscapeCommandArguments
|
||||
{
|
||||
void operator()(const AZStd::string& commandParameterString)
|
||||
{
|
||||
AZStd::string outputString;
|
||||
bool inQuotes = false;
|
||||
for (size_t pos = 0; pos < commandParameterString.size(); ++pos)
|
||||
{
|
||||
char currentChar = commandParameterString[pos];
|
||||
if (currentChar == '"')
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else if ((currentChar == ' ') && (!inQuotes))
|
||||
{
|
||||
// its a space outside of quotes, so it ends the current parameter
|
||||
commandArray.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Its a normal character, or its a space inside quotes
|
||||
outputString.push_back(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outputString.empty())
|
||||
{
|
||||
commandArray.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const AZStd::vector<AZStd::string>& commandParameterArray)
|
||||
{
|
||||
commandArray = commandParameterArray;
|
||||
}
|
||||
AZStd::vector<AZStd::string>& commandArray;
|
||||
};
|
||||
|
||||
AZStd::vector<AZStd::string> commandTokens;
|
||||
|
||||
AZStd::string outputString;
|
||||
bool inQuotes = false;
|
||||
for (size_t pos = 0; pos < processLaunchInfo.m_commandlineParameters.size(); ++pos)
|
||||
{
|
||||
char currentChar = processLaunchInfo.m_commandlineParameters[pos];
|
||||
if (currentChar == '"')
|
||||
{
|
||||
// Allow quote literals to go through as quotes which do NOT alter our "in quotes" bool below
|
||||
// This is to conform with our PC parameter strings which will sometimes include path parameters which
|
||||
// Can have spaces and commas and need to be output as paramname="\"Some pa,ram\"" in order to capture both correctly
|
||||
if (outputString.length() && outputString.back() == '\\')
|
||||
{
|
||||
outputString.back() = currentChar;
|
||||
}
|
||||
else
|
||||
{
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
}
|
||||
else if ((currentChar == ' ') && (!inQuotes))
|
||||
{
|
||||
// its a space outside of quotes, so it ends the current parameter
|
||||
commandTokens.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Its a normal character, or its a space inside quotes
|
||||
outputString.push_back(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outputString.empty())
|
||||
{
|
||||
commandTokens.push_back(outputString);
|
||||
outputString.clear();
|
||||
}
|
||||
AZStd::visit(EscapeCommandArguments{ commandTokens }, processLaunchInfo.m_commandlineParameters);
|
||||
|
||||
if (!processLaunchInfo.m_processExecutableString.empty())
|
||||
{
|
||||
@@ -417,5 +421,24 @@ namespace AzFramework
|
||||
kill(m_pWatcherData->m_childProcessId, SIGKILL);
|
||||
waitpid(m_pWatcherData->m_childProcessId, NULL, 0);
|
||||
}
|
||||
|
||||
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
|
||||
{
|
||||
struct CommandLineParametersVisitor
|
||||
{
|
||||
AZStd::string operator()(const AZStd::string& commandLine) const
|
||||
{
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
AZStd::string operator()(const AZStd::vector<AZStd::string>& commandLineArray) const
|
||||
{
|
||||
AZStd::string commandLineResult;
|
||||
AZ::StringFunc::Join(commandLineResult, commandLineArray.begin(), commandLineArray.end(), " ");
|
||||
return commandLineResult;
|
||||
}
|
||||
};
|
||||
return AZStd::visit(CommandLineParametersVisitor{}, m_commandlineParameters);
|
||||
}
|
||||
} //namespace AzFramework
|
||||
|
||||
|
||||
+39
-1
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
@@ -99,7 +100,7 @@ namespace AzFramework
|
||||
AZStd::wstring editableCommandLine;
|
||||
AZStd::wstring processExecutableString;
|
||||
AZStd::wstring workingDirectory;
|
||||
AZStd::to_wstring(editableCommandLine, processLaunchInfo.m_commandlineParameters);
|
||||
AZStd::to_wstring(editableCommandLine, processLaunchInfo.GetCommandLineParametersAsString());
|
||||
AZStd::to_wstring(processExecutableString, processLaunchInfo.m_processExecutableString);
|
||||
AZStd::to_wstring(workingDirectory, processLaunchInfo.m_workingDirectory);
|
||||
|
||||
@@ -355,4 +356,41 @@ namespace AzFramework
|
||||
::TerminateProcess(m_pWatcherData->processInformation.hProcess, exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
|
||||
{
|
||||
struct CommandLineParametersVisitor
|
||||
{
|
||||
AZStd::string operator()(const AZStd::string& commandLine) const
|
||||
{
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
AZStd::string operator()(const AZStd::vector<AZStd::string>& commandLineArray) const
|
||||
{
|
||||
AZStd::string commandLineResult;
|
||||
|
||||
// When re-constructing a command line from an argument list (on windows), if an argument
|
||||
// is double-quoted, then the double-quotes must be escaped properly otherwise
|
||||
// it will be absorbed by the native argument parser and possibly evaluated as
|
||||
// multiple values for arguments
|
||||
AZStd::string_view escapedDoubleQuote = R"("\")";
|
||||
|
||||
AZStd::vector<AZStd::string> preprocessedCommandArray;
|
||||
|
||||
for (const auto& commandArg : commandLineArray)
|
||||
{
|
||||
AZStd::string replacedArg = commandArg;
|
||||
AZ::StringFunc::Replace(replacedArg, R"(")", R"("\")", false, true, true);
|
||||
preprocessedCommandArray.emplace_back(replacedArg);
|
||||
}
|
||||
AZ::StringFunc::Join(commandLineResult, preprocessedCommandArray.begin(), preprocessedCommandArray.end(), " ");
|
||||
|
||||
return commandLineResult;
|
||||
}
|
||||
};
|
||||
|
||||
return AZStd::visit(CommandLineParametersVisitor{}, m_commandlineParameters);
|
||||
}
|
||||
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzFramework/Process/ProcessCommunicator.h>
|
||||
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -83,4 +83,23 @@ namespace AzFramework
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
|
||||
{
|
||||
struct CommandLineParametersVisitor
|
||||
{
|
||||
AZStd::string operator()(const AZStd::string& commandLine) const
|
||||
{
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
AZStd::string operator()(const AZStd::vector<AZStd::string>& commandLineArray) const
|
||||
{
|
||||
AZStd::string commandLineResult;
|
||||
Az::StringFunc::Join(commandLineResult, commandLineArray.begin(), commandLineArray.end(), " ");
|
||||
return commandLineResult;
|
||||
}
|
||||
};
|
||||
return AZStd::visit(CommandLineParametersVisitor{}, m_commandlineParameters);
|
||||
}
|
||||
} //namespace AzFramework
|
||||
|
||||
@@ -322,6 +322,17 @@ namespace UnitTest
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(CameraInput, CameraPitchIsClampedWithExpectedTolerance)
|
||||
{
|
||||
const auto [expectedMinPitch, expectedMaxPitch] = AzFramework::CameraPitchMinMaxRadiansWithTolerance();
|
||||
const float minPitch = AzFramework::ClampPitchRotation(-AZ::Constants::HalfPi);
|
||||
const float maxPitch = AzFramework::ClampPitchRotation(AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(minPitch, FloatNear(expectedMinPitch, AzFramework::CameraPitchTolerance));
|
||||
EXPECT_THAT(maxPitch, FloatNear(expectedMaxPitch, AzFramework::CameraPitchTolerance));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitRotateCameraInputRotatesPitchOffsetByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3::CreateAxisY(-20.0f);
|
||||
|
||||
@@ -75,7 +75,8 @@ namespace UnitTest
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest";
|
||||
processLaunchInfo.m_commandlineParameters.emplace<AZStd::string>(AZStd::string(AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest"));
|
||||
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
@@ -90,7 +91,9 @@ namespace UnitTest
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest -param1 param1val -param2=param2val";
|
||||
processLaunchInfo.m_commandlineParameters.emplace<AZStd::vector<AZStd::string>>(
|
||||
AZStd::vector<AZStd::string>{AZStd::string(AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest"), "-param1", "param1val","-param2", "param2val"});
|
||||
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
@@ -117,14 +120,16 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
TEST_F(ProcessLaunchParseTests, DISABLED_ProcessLauncher_StringsWithCommas_Success)
|
||||
#else
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_StringsWithCommas_Success)
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_WithCommas_Success)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
{
|
||||
ProcessLaunchParseTests::ParsedArgMap argMap;
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER R"(ProcessLaunchTest -param1 "\"param,1val\"" -param2="\"param2v,al\"")";
|
||||
processLaunchInfo.m_commandlineParameters.emplace<AZStd::vector<AZStd::string>>(
|
||||
AZStd::vector<AZStd::string>{AZStd::string(AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest"), "-param1", "param,1val","-param2", "param2v,al"});
|
||||
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
@@ -137,28 +142,32 @@ namespace UnitTest
|
||||
EXPECT_NE(param1itr, argMap.end());
|
||||
AZStd::vector<AZStd::string> param1{ param1itr->second };
|
||||
|
||||
EXPECT_EQ(param1.size(), 1);
|
||||
EXPECT_EQ(param1[0], "param,1val");
|
||||
EXPECT_EQ(param1.size(), 2);
|
||||
EXPECT_EQ(param1[0], "param");
|
||||
EXPECT_EQ(param1[1], "1val");
|
||||
|
||||
auto param2itr = argMap.find("param2");
|
||||
EXPECT_NE(param2itr, argMap.end());
|
||||
AZStd::vector<AZStd::string> param2{ param2itr->second };
|
||||
|
||||
EXPECT_EQ(param2.size(), 1);
|
||||
EXPECT_EQ(param2[0], "param2v,al");
|
||||
EXPECT_EQ(param2.size(), 2);
|
||||
EXPECT_EQ(param2[0], "param2v");
|
||||
EXPECT_EQ(param2[1], "al");
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
TEST_F(ProcessLaunchParseTests, DISABLED_ProcessLauncher_StringsWithSpaces_Success)
|
||||
#else
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_StringsWithSpaces_Success)
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_WithSpaces_Success)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
{
|
||||
ProcessLaunchParseTests::ParsedArgMap argMap;
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER R"(ProcessLaunchTest -param1 "\"param 1val\"" -param2="\"param2v al\"")";
|
||||
processLaunchInfo.m_commandlineParameters.emplace<AZStd::vector<AZStd::string>>(AZStd::vector<AZStd::string>{
|
||||
AZStd::string(AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest"), "-param1", R"("param 1val")", R"(-param2="param2v al")" });
|
||||
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
@@ -185,14 +194,16 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
TEST_F(ProcessLaunchParseTests, DISABLED_ProcessLauncher_StringsWithSpacesAndComma_Success)
|
||||
#else
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_StringsWithSpacesAndComma_Success)
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_WithSpacesAndComma_Success)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS
|
||||
{
|
||||
ProcessLaunchParseTests::ParsedArgMap argMap;
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER R"(ProcessLaunchTest -param1 "\"par,am 1val\"" -param2="\"param,2v al\"")";
|
||||
processLaunchInfo.m_commandlineParameters.emplace<AZStd::vector<AZStd::string>>(AZStd::vector<AZStd::string>{
|
||||
AZStd::string(AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest"), "-param1", R"("param, 1val")", R"(-param2="param,2v al")" });
|
||||
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
@@ -206,7 +217,7 @@ namespace UnitTest
|
||||
AZStd::vector<AZStd::string> param1{ param1itr->second };
|
||||
|
||||
EXPECT_EQ(param1.size(), 1);
|
||||
EXPECT_EQ(param1[0], "par,am 1val");
|
||||
EXPECT_EQ(param1[0], "param, 1val");
|
||||
|
||||
auto param2itr = argMap.find("param2");
|
||||
EXPECT_NE(param2itr, argMap.end());
|
||||
@@ -216,35 +227,4 @@ namespace UnitTest
|
||||
EXPECT_EQ(param2[0], "param,2v al");
|
||||
}
|
||||
|
||||
TEST_F(ProcessLaunchParseTests, ProcessLauncher_CommaStringNoQuotes_Success)
|
||||
{
|
||||
ProcessLaunchParseTests::ParsedArgMap argMap;
|
||||
AzFramework::ProcessOutput processOutput;
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = AZ_TRAIT_TEST_ROOT_FOLDER "ProcessLaunchTest -param1 param,1val -param2=param2v,al";
|
||||
processLaunchInfo.m_workingDirectory = AZ::Test::GetCurrentExecutablePath();
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
bool launchReturn = AzFramework::ProcessWatcher::LaunchProcessAndRetrieveOutput(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_STDINOUT, processOutput);
|
||||
|
||||
EXPECT_EQ(launchReturn, true);
|
||||
|
||||
argMap = ProcessLaunchParseTests::ParseParameters(processOutput.outputResult);
|
||||
|
||||
auto param1itr = argMap.find("param1");
|
||||
EXPECT_NE(param1itr, argMap.end());
|
||||
AZStd::vector<AZStd::string> param1{ param1itr->second };
|
||||
|
||||
EXPECT_EQ(param1.size(), 2);
|
||||
EXPECT_EQ(param1[0], "param");
|
||||
EXPECT_EQ(param1[1], "1val");
|
||||
|
||||
auto param2itr = argMap.find("param2");
|
||||
EXPECT_NE(param2itr, argMap.end());
|
||||
AZStd::vector<AZStd::string> param2{ param2itr->second };
|
||||
|
||||
EXPECT_EQ(param2.size(), 2);
|
||||
EXPECT_EQ(param2[0], "param2v");
|
||||
EXPECT_EQ(param2[1], "al");
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#define AZ_TRAIT_UNIT_TEST_ENTITY_ID_GEN_TEST_COUNT 10000
|
||||
#define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000
|
||||
|
||||
#define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true
|
||||
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ATOM_RPI_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS true
|
||||
|
||||
@@ -23,7 +21,6 @@
|
||||
#define AZ_TRAIT_DISABLE_FAILED_GRADIENT_SIGNAL_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MULTIPLAYER_GRIDMATE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_NATIVE_WINDOWS_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_PROCESS_LAUNCHER_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_DLL_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_MODULE_TESTS true
|
||||
|
||||
+2
-1
@@ -64,7 +64,8 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
if (clickOutcome == AzFramework::ClickDetector::ClickOutcome::Release)
|
||||
if (clickOutcome == AzFramework::ClickDetector::ClickOutcome::Release ||
|
||||
clickOutcome == AzFramework::ClickDetector::ClickOutcome::Click)
|
||||
{
|
||||
if (m_leftMouseUp)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user