Merge branch 'main' into mbalfour/spec-6178
This commit is contained in:
@@ -302,10 +302,10 @@ def ProcessExpansionRule(sourceFiles, templateFiles, templateCache, outputDir, p
|
||||
# Due to the lack of wildcards in the output file, we've determined we'll glob all matching input files into the template conversion
|
||||
for filename in fnmatch.filter(sourceFiles, inputFiles):
|
||||
dataInputFiles = [os.path.abspath(file) for file in fnmatch.filter(sourceFiles, inputFiles)]
|
||||
outputFileAbsolute = outputFile.replace("$path", ComputeOutputPath(dataInputFiles, projectDir, outputDir))
|
||||
outputFileAbsolute = SanitizePath(outputFileAbsolute)
|
||||
ProcessTemplateConversion(dataInputSet, dataInputFiles, templateFile, outputFileAbsolute, templateCache, dryrun, verbose)
|
||||
outputFiles.append(outputFileAbsolute)
|
||||
outputFileAbsolute = outputFile.replace("$path", ComputeOutputPath(dataInputFiles, projectDir, outputDir))
|
||||
outputFileAbsolute = SanitizePath(outputFileAbsolute)
|
||||
ProcessTemplateConversion(dataInputSet, dataInputFiles, templateFile, outputFileAbsolute, templateCache, dryrun, verbose)
|
||||
outputFiles.append(outputFileAbsolute)
|
||||
except IOError as e:
|
||||
PrintError('%s : error I/O(%s) accessing %s : %s' % (expansionRule, e.errno, e.filename, e.strerror))
|
||||
except:
|
||||
@@ -357,8 +357,7 @@ if __name__ == '__main__':
|
||||
parser.add_argument("expansionRules", help="set of azcg expansion rules for matching data files to template files")
|
||||
parser.add_argument("-n", "--dryrun", action='store_true', help="does not execute autogen, only outputs the set of files that autogen would generate")
|
||||
parser.add_argument("-v", "--verbose", action='store_true', help="output only the set of files that would be generated by an expansion run")
|
||||
parser.add_argument("-p", "--pythonPaths", action='append', nargs='+', default=[""],
|
||||
help="set of additional python paths to use for module imports")
|
||||
parser.add_argument("-p", "--pythonPaths", action='append', nargs='+', default=[""], help="set of additional python paths to use for module imports")
|
||||
|
||||
args = parser.parse_args()
|
||||
pythonPaths = args.pythonPaths
|
||||
|
||||
@@ -418,16 +418,19 @@ namespace AZ
|
||||
|
||||
void AssetContainer::ListWaitingAssets() const
|
||||
{
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_readyMutex);
|
||||
AZ_TracePrintf("AssetContainer", "Waiting on assets:\n");
|
||||
for (auto& thisAsset : m_waitingAssets)
|
||||
{
|
||||
AZ_TracePrintf("AssetContainer", " %s\n",thisAsset.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetContainer::ListWaitingPreloads(const AssetId& assetId) const
|
||||
void AssetContainer::ListWaitingPreloads([[maybe_unused]] const AssetId& assetId) const
|
||||
{
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> preloadGuard(m_preloadMutex);
|
||||
auto preloadEntry = m_preloadList.find(assetId);
|
||||
if (preloadEntry != m_preloadList.end())
|
||||
@@ -442,6 +445,7 @@ namespace AZ
|
||||
{
|
||||
AZ_TracePrintf("AssetContainer", "%s isn't waiting on any preloads:\n", assetId.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetContainer::AddWaitingAssets(const AZStd::vector<AssetId>& assetList)
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace AZ::Data
|
||||
// Get the results
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
AZ::u64 bytesRead = 0;
|
||||
bool result = streamer->GetReadRequestResult(fileHandle, m_buffer, bytesRead,
|
||||
AZ::IO::IStreamerTypes::ClaimMemory::Yes);
|
||||
streamer->GetReadRequestResult(fileHandle, m_buffer, bytesRead,
|
||||
AZ::IO::IStreamerTypes::ClaimMemory::Yes);
|
||||
auto status = streamer->GetRequestStatus(fileHandle);
|
||||
m_loadedSize = aznumeric_cast<size_t>(bytesRead);
|
||||
|
||||
|
||||
@@ -1750,7 +1750,6 @@ namespace AZ
|
||||
{
|
||||
AssetData* data = asset.Get();
|
||||
{
|
||||
const AZ::Data::AssetId& assetId = asset.GetId();
|
||||
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
|
||||
if (data)
|
||||
|
||||
@@ -362,11 +362,20 @@ namespace AZ
|
||||
ComponentApplication::ComponentApplication()
|
||||
: ComponentApplication(0, nullptr)
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == nullptr)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
}
|
||||
|
||||
ComponentApplication::ComponentApplication(int argC, char** argV)
|
||||
: m_eventLogger{}
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == nullptr)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
|
||||
if (argV)
|
||||
{
|
||||
m_argC = argC;
|
||||
@@ -462,6 +471,11 @@ namespace AZ
|
||||
//=========================================================================
|
||||
ComponentApplication::~ComponentApplication()
|
||||
{
|
||||
if (Interface<ComponentApplicationRequests>::Get() == this)
|
||||
{
|
||||
Interface<ComponentApplicationRequests>::Unregister(this);
|
||||
}
|
||||
|
||||
if (m_isStarted)
|
||||
{
|
||||
Destroy();
|
||||
@@ -495,8 +509,7 @@ namespace AZ
|
||||
DestroyAllocator();
|
||||
}
|
||||
|
||||
Entity* ComponentApplication::Create(const Descriptor& descriptor,
|
||||
const StartupParameters& startupParameters)
|
||||
Entity* ComponentApplication::Create(const Descriptor& descriptor, const StartupParameters& startupParameters)
|
||||
{
|
||||
AZ_Assert(!m_isStarted, "Component application already started!");
|
||||
|
||||
@@ -943,6 +956,16 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_entityAddedEvent);
|
||||
}
|
||||
|
||||
void ComponentApplication::RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler)
|
||||
{
|
||||
handler.Connect(m_entityRemovedEvent);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// AddEntity
|
||||
// [5/30/2012]
|
||||
@@ -954,7 +977,7 @@ namespace AZ
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entityAddedEvent.Signal(entity);
|
||||
return m_entities.insert(AZStd::make_pair(entity->GetId(), entity)).second;
|
||||
}
|
||||
|
||||
@@ -969,7 +992,7 @@ namespace AZ
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_entityRemovedEvent.Signal(entity);
|
||||
return (m_entities.erase(entity->GetId()) == 1);
|
||||
}
|
||||
|
||||
@@ -982,6 +1005,7 @@ namespace AZ
|
||||
Entity* entity = FindEntity(id);
|
||||
if (entity)
|
||||
{
|
||||
m_entityRemovedEvent.Signal(entity);
|
||||
delete entity;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -193,8 +193,7 @@ namespace AZ
|
||||
* You will need to setup all system components manually.
|
||||
* \returns pointer to the system entity.
|
||||
*/
|
||||
virtual Entity* Create(const Descriptor& descriptor,
|
||||
const StartupParameters& startupParameters = StartupParameters());
|
||||
virtual Entity* Create(const Descriptor& descriptor, const StartupParameters& startupParameters = StartupParameters());
|
||||
virtual void Destroy();
|
||||
virtual void DestroyAllocator(); // Called at the end of Destroy(). Applications can override to do tear down work right before allocator is destroyed.
|
||||
|
||||
@@ -202,6 +201,8 @@ namespace AZ
|
||||
// ComponentApplicationRequests
|
||||
void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) override final;
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) override final;
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) override final;
|
||||
bool AddEntity(Entity* entity) override;
|
||||
bool RemoveEntity(Entity* entity) override;
|
||||
bool DeleteEntity(const EntityId& id) override;
|
||||
@@ -380,6 +381,8 @@ namespace AZ
|
||||
float m_deltaTime{ 0.0f };
|
||||
AZStd::unique_ptr<ModuleManager> m_moduleManager;
|
||||
AZStd::unique_ptr<SettingsRegistryInterface> m_settingsRegistry;
|
||||
EntityAddedEvent m_entityAddedEvent;
|
||||
EntityRemovedEvent m_entityRemovedEvent;
|
||||
AZ::IConsole* m_console{};
|
||||
Descriptor m_descriptor;
|
||||
bool m_isStarted{ false };
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/string/osstring.h>
|
||||
@@ -69,160 +70,138 @@ namespace AZ
|
||||
inline bool ApplicationTypeQuery::IsGame() const { return (m_maskValue & Masks::Game) == Masks::Game; }
|
||||
inline bool ApplicationTypeQuery::IsValid() const { return m_maskValue != Masks::Invalid; }
|
||||
|
||||
/**
|
||||
* Event bus that components use to make requests of the main application.
|
||||
* Only one application can exist at a time, which is why this bus
|
||||
* supports only one listener.
|
||||
*/
|
||||
using EntityAddedEvent = AZ::Event<AZ::Entity*>;
|
||||
using EntityRemovedEvent = AZ::Event<AZ::Entity*>;
|
||||
|
||||
//! Interface that components can use to make requests of the main application.
|
||||
class ComponentApplicationRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(ComponentApplicationRequests, "{E8BE41B7-615F-4FE8-B611-8A9E441290A8}");
|
||||
|
||||
/**
|
||||
* Destroys the event bus that components use to make requests of the main application.
|
||||
*/
|
||||
virtual ~ComponentApplicationRequests() {}
|
||||
//! Destroys the event bus that components use to make requests of the main application.
|
||||
virtual ~ComponentApplicationRequests() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides - application is a singleton
|
||||
/**
|
||||
* Overrides the default AZ::EBusTraits handler policy to allow one
|
||||
* listener only, because only one application can exist at a time.
|
||||
*/
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; // We sort components on m_initOrder.
|
||||
/**
|
||||
* Overrides the default AZ::EBusTraits mutex type to the AZStd implementation of
|
||||
* a recursive mutex with exclusive ownership semantics. A mutex prevents multiple
|
||||
* threads from accessing shared data simultaneously.
|
||||
*/
|
||||
typedef AZStd::recursive_mutex MutexType;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Registers a component descriptor with the application.
|
||||
* @param descriptor A component descriptor.
|
||||
*/
|
||||
//! Registers a component descriptor with the application.
|
||||
//! @param descriptor A component descriptor.
|
||||
virtual void RegisterComponentDescriptor(const ComponentDescriptor* descriptor) = 0;
|
||||
/**
|
||||
* Unregisters a component descriptor with the application.
|
||||
* @param descriptor A component descriptor.
|
||||
*/
|
||||
|
||||
//! Unregisters a component descriptor with the application.
|
||||
//! @param descriptor A component descriptor.
|
||||
virtual void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) = 0;
|
||||
/**
|
||||
* Gets a pointer to the application.
|
||||
* @return A pointer to the application.
|
||||
*/
|
||||
virtual ComponentApplication* GetApplication() = 0;
|
||||
|
||||
/**
|
||||
* Adds an entity to the application's registry.
|
||||
* Calling Init() on an entity automatically performs this operation.
|
||||
* @param entity A pointer to the entity to add to the application's registry.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool AddEntity(Entity* entity) = 0;
|
||||
/**
|
||||
* Removes the specified entity from the application's registry.
|
||||
* Deleting an entity automatically performs this operation.
|
||||
* @param entity A pointer to the entity that will be removed from the application's registry.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool RemoveEntity(Entity* entity) = 0;
|
||||
/**
|
||||
* Unregisters and deletes the specified entity.
|
||||
* @param entity A reference to the entity that will be unregistered and deleted.
|
||||
* @return True if the operation succeeded. False if the operation failed.
|
||||
*/
|
||||
virtual bool DeleteEntity(const EntityId& id) = 0;
|
||||
/**
|
||||
* Returns the entity with the matching ID, if the entity is registered with the application.
|
||||
* @param entity A reference to the entity that you are searching for.
|
||||
* @return A pointer to the entity with the specified entity ID.
|
||||
*/
|
||||
virtual Entity* FindEntity(const EntityId& id) = 0;
|
||||
/**
|
||||
* Returns the name of the entity that has the specified entity ID.
|
||||
* Entity names are not unique.
|
||||
* This method exists to facilitate better debugging messages.
|
||||
* @param entity A reference to the entity whose name you are seeking.
|
||||
* @return The name of the entity with the specified entity ID.
|
||||
* If no entity is found for the specified ID, it returns an empty string.
|
||||
*/
|
||||
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); };
|
||||
//! Gets a pointer to the application.
|
||||
//! @return A pointer to the application.
|
||||
virtual ComponentApplication* GetApplication() = 0;
|
||||
|
||||
/**
|
||||
* The type that AZ::ComponentApplicationRequests::EnumerateEntities uses to
|
||||
* pass entity callbacks to the application for enumeration.
|
||||
*/
|
||||
//! Registers an event handler that will be signalled whenever an entity is added.
|
||||
//! @param handler the event handler to signal.
|
||||
virtual void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Registers an event handler that will be signalled whenever an entity is removed.
|
||||
//! @param handler the event handler to signal.
|
||||
virtual void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds an entity to the application's registry.
|
||||
//! Calling Init() on an entity automatically performs this operation.
|
||||
//! @param entity A pointer to the entity to add to the application's registry.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool AddEntity(Entity* entity) = 0;
|
||||
|
||||
//! Removes the specified entity from the application's registry.
|
||||
//! Deleting an entity automatically performs this operation.
|
||||
//! @param entity A pointer to the entity that will be removed from the application's registry.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool RemoveEntity(Entity* entity) = 0;
|
||||
|
||||
//! Unregisters and deletes the specified entity.
|
||||
//! @param entity A reference to the entity that will be unregistered and deleted.
|
||||
//! @return True if the operation succeeded. False if the operation failed.
|
||||
virtual bool DeleteEntity(const EntityId& id) = 0;
|
||||
|
||||
//! Returns the entity with the matching ID, if the entity is registered with the application.
|
||||
//! @param entity A reference to the entity that you are searching for.
|
||||
//! @return A pointer to the entity with the specified entity ID.
|
||||
virtual Entity* FindEntity(const EntityId& id) = 0;
|
||||
|
||||
//! Returns the name of the entity that has the specified entity ID.
|
||||
//! Entity names are not unique.
|
||||
//! This method exists to facilitate better debugging messages.
|
||||
//! @param entity A reference to the entity whose name you are seeking.
|
||||
//! @return The name of the entity with the specified entity ID.
|
||||
//! If no entity is found for the specified ID, it returns an empty string.
|
||||
virtual AZStd::string GetEntityName(const EntityId& id) { (void)id; return AZStd::string(); };
|
||||
|
||||
//! The type that AZ::ComponentApplicationRequests::EnumerateEntities uses to
|
||||
//! pass entity callbacks to the application for enumeration.
|
||||
using EntityCallback = AZStd::function<void(Entity*)>;
|
||||
/**
|
||||
* Enumerates all registered entities and invokes the specified callback for each entity.
|
||||
* @param callback A reference to the callback that is invoked for each entity.
|
||||
*/
|
||||
virtual void EnumerateEntities(const EntityCallback& callback) = 0;
|
||||
/**
|
||||
* Returns the serialize context that was registered with the app.
|
||||
* @return The serialize context, if there is one. SerializeContext is a class that contains reflection data
|
||||
* for serialization and construction of objects.
|
||||
*/
|
||||
|
||||
//! Enumerates all registered entities and invokes the specified callback for each entity.
|
||||
//! @param callback A reference to the callback that is invoked for each entity.
|
||||
virtual void EnumerateEntities(const EntityCallback& callback) = 0;
|
||||
|
||||
//! Returns the serialize context that was registered with the app.
|
||||
//! @return The serialize context, if there is one. SerializeContext is a class that contains reflection data
|
||||
//! for serialization and construction of objects.
|
||||
virtual class SerializeContext* GetSerializeContext() = 0;
|
||||
/**
|
||||
* Returns the behavior context that was registered with the app.
|
||||
* @return The behavior context, if there is one. BehaviorContext is a class that reflects classes, methods,
|
||||
* and EBuses for runtime interaction.
|
||||
*/
|
||||
|
||||
//! Returns the behavior context that was registered with the app.
|
||||
//! @return The behavior context, if there is one. BehaviorContext is a class that reflects classes, methods,
|
||||
//! and EBuses for runtime interaction.
|
||||
virtual class BehaviorContext* GetBehaviorContext() = 0;
|
||||
/**
|
||||
* Returns the Json Registration context that was registered with the app.
|
||||
* @return The Json Registration context, if there is one. JsonRegistrationContext is a class that contains
|
||||
* the serializers used by the best-effort json serialization.
|
||||
*/
|
||||
|
||||
//! Returns the Json Registration context that was registered with the app.
|
||||
//! @return The Json Registration context, if there is one. JsonRegistrationContext is a class that contains
|
||||
//! the serializers used by the best-effort json serialization.
|
||||
virtual class JsonRegistrationContext* GetJsonRegistrationContext() = 0;
|
||||
/**
|
||||
* Gets the name of the working root folder that was registered with the app.
|
||||
* @return A pointer to the name of the app's root folder, if a root folder was registered.
|
||||
*/
|
||||
virtual const char* GetAppRoot() const = 0;
|
||||
/**
|
||||
* Gets the path of the working engine folder that the app is a part of.
|
||||
* @return A pointer to the engine path.
|
||||
*/
|
||||
virtual const char* GetEngineRoot() const = 0;
|
||||
/**
|
||||
* Gets the path to the directory that contains the application's executable.
|
||||
* @return A pointer to the name of the path that contains the application's executable.
|
||||
*/
|
||||
virtual const char* GetExecutableFolder() const = 0;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the driller manager, if driller is enabled.
|
||||
* The driller manager manages all active driller sessions and driller factories.
|
||||
* @return A pointer to the driller manager. If driller is not enabled,
|
||||
* this function returns null.
|
||||
*/
|
||||
virtual Debug::DrillerManager* GetDrillerManager() = 0;
|
||||
//! Gets the name of the working root folder that was registered with the app.
|
||||
//! @return a pointer to the name of the app's root folder, if a root folder was registered.
|
||||
virtual const char* GetAppRoot() const = 0;
|
||||
|
||||
/**
|
||||
* ResolveModulePath is called whenever LoadDynamicModule wants to resolve a module in order to actually load it.
|
||||
* You can override this if you need to load modules from a different path or hijack module loading in some other way.
|
||||
* If you do, ensure that you use platform-specific conventions to do so, as this is called by multiple platforms.
|
||||
* The default implantation prepends the path to the executable to the module path, but you can override this behavior
|
||||
* (Call the base class if you want this behavior to persist in overrides)
|
||||
*/
|
||||
virtual void ResolveModulePath(AZ::OSString& /*modulePath*/) { }
|
||||
//! Gets the path of the working engine folder that the app is a part of.
|
||||
//! @return a pointer to the engine path.
|
||||
virtual const char* GetEngineRoot() const = 0;
|
||||
|
||||
/**
|
||||
* Returns AZ parsed command line structure.
|
||||
* Command Line structure can be queried for switches (-<switch> /<switch>) or positional parameter (<value>)
|
||||
*/
|
||||
//! Gets the path to the directory that contains the application's executable.
|
||||
//! @return a pointer to the name of the path that contains the application's executable.
|
||||
virtual const char* GetExecutableFolder() const = 0;
|
||||
|
||||
//! Returns a pointer to the driller manager, if driller is enabled.
|
||||
//! The driller manager manages all active driller sessions and driller factories.
|
||||
//! @return A pointer to the driller manager. If driller is not enabled, this function returns null.
|
||||
virtual Debug::DrillerManager* GetDrillerManager() = 0;
|
||||
|
||||
//! ResolveModulePath is called whenever LoadDynamicModule wants to resolve a module in order to actually load it.
|
||||
//! You can override this if you need to load modules from a different path or hijack module loading in some other way.
|
||||
//! If you do, ensure that you use platform-specific conventions to do so, as this is called by multiple platforms.
|
||||
//! The default implantation prepends the path to the executable to the module path, but you can override this behavior
|
||||
//! (Call the base class if you want this behavior to persist in overrides)
|
||||
virtual void ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath) { }
|
||||
|
||||
//! Returns AZ parsed command line structure.
|
||||
//! Command Line structure can be queried for switches (-<switch> /<switch>) or positional parameter (<value>)
|
||||
virtual AZ::CommandLine* GetAzCommandLine() { return{}; }
|
||||
|
||||
//! Returns all the flags that are true for the current application.
|
||||
virtual void QueryApplicationType(ApplicationTypeQuery& appType) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used by components to make requests of the component application.
|
||||
*/
|
||||
typedef AZ::EBus<ComponentApplicationRequests> ComponentApplicationBus;
|
||||
class ComponentApplicationRequestsEBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//! EBusTraits overrides - application is a singleton
|
||||
//! Overrides the default AZ::EBusTraits handler policy to allow one
|
||||
//! listener only, because only one application can exist at a time.
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Single; // We sort components on m_initOrder.
|
||||
|
||||
//! Overrides the default AZ::EBusTraits mutex type to the AZStd implementation of
|
||||
//! a recursive mutex with exclusive ownership semantics. A mutex prevents multiple
|
||||
//! threads from accessing shared data simultaneously.
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
};
|
||||
|
||||
//! Used by components to make requests of the component application.
|
||||
using ComponentApplicationBus = AZ::EBus<ComponentApplicationRequests, ComponentApplicationRequestsEBusTraits>;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Component/NamedEntityId.h>
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
@@ -159,10 +159,11 @@ namespace AZ
|
||||
AZ_Assert(m_state == State::Constructed, "Component should be in Constructed state to be Initialized!");
|
||||
SetState(State::Initializing);
|
||||
|
||||
bool result = true;
|
||||
EBUS_EVENT_RESULT(result, ComponentApplicationBus, AddEntity, this);
|
||||
(void)result;
|
||||
AZ_Assert(result, "Failed to add entity '%s' [0x%llx]! Did you already register an entity with this ID?", m_name.c_str(), m_id);
|
||||
if (AZ::Interface<ComponentApplicationRequests>::Get() != nullptr)
|
||||
{
|
||||
[[maybe_unused]] const bool result = AZ::Interface<ComponentApplicationRequests>::Get()->AddEntity(this);
|
||||
AZ_Assert(result, "Failed to add entity '%s' [0x%llx]! Did you already register an entity with this ID?", m_name.c_str(), m_id);
|
||||
}
|
||||
|
||||
for (ComponentArrayType::iterator it = m_components.begin(); it != m_components.end();)
|
||||
{
|
||||
|
||||
@@ -40,10 +40,26 @@ namespace AZ
|
||||
(*idMapper)->SetIsEntityReference(false);
|
||||
}
|
||||
|
||||
JSR::ResultCode idLoadResult =
|
||||
ContinueLoadingFromJsonObjectField(&entityInstance->m_id,
|
||||
azrtti_typeid<decltype(entityInstance->m_id)>(),
|
||||
inputValue, "Id", context);
|
||||
JSR::ResultCode idLoadResult = ContinueLoadingFromJsonObjectField(
|
||||
&entityInstance->m_id, azrtti_typeid<decltype(entityInstance->m_id)>(), inputValue, "Id", context);
|
||||
|
||||
// If the entity has an invalid ID, there's no point in deserializing, the entity will be unusable.
|
||||
// It's also dangerous to generate new IDs here:
|
||||
// - They need to be globally unique
|
||||
// - We don't know *why* it's invalid (maybe just a typo on the name "Id" for example), so we don't know the ramifications
|
||||
// of changing it. There might be many other entities that have references to this one that would become invalid as well
|
||||
// if we try to silently fix it up.
|
||||
// - Unless we save the ID immediately, it will change every time we serialize the data in, which can happen multiple times
|
||||
// during the serialization pipeline. So it either needs to be saved back immediately, or we need a deterministic way
|
||||
// to generate a globally unique ID for the entity.
|
||||
if (!entityInstance->GetId().IsValid())
|
||||
{
|
||||
// Since we're going to halt processing anyways, we just return the error here immediately.
|
||||
return context.Report(
|
||||
JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Invalid),
|
||||
"Invalid or missing entity ID - please add an 'Id' field to this entity with a globally unique id. \n"
|
||||
"Failed to load entity information.");
|
||||
}
|
||||
|
||||
if (hasValidIdMapper)
|
||||
{
|
||||
@@ -93,9 +109,10 @@ namespace AZ
|
||||
inputValue, "IsRuntimeActive", context);
|
||||
}
|
||||
|
||||
return context.Report(result,
|
||||
result.GetProcessing() == JSR::Processing::Halted ? "Succesfully loaded entity information." :
|
||||
"Failed to load entity information.");
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded entity information."
|
||||
: "Failed to load entity information.");
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonEntitySerializer::Store(rapidjson::Value& outputValue,
|
||||
@@ -199,7 +216,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
return context.Report(result,
|
||||
result.GetProcessing() == JSR::Processing::Halted ? "Successfully stored Entity information." :
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored Entity information." :
|
||||
"Failed to store Entity information.");
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/EBus/EventSchedulerSystemComponent.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
@@ -111,8 +110,10 @@ namespace AZ
|
||||
TimeMs currentMilliseconds = GetElapsedTimeMs();
|
||||
if (timedEvent->m_handle == nullptr)
|
||||
{
|
||||
timedEvent->m_handle = AllocateHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent);
|
||||
timedEvent->m_handle = AllocateHandle();
|
||||
}
|
||||
const bool ownsScheduledEvent = false;
|
||||
*(timedEvent->m_handle) = ScheduledEventHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent, ownsScheduledEvent);
|
||||
timedEvent->m_timeInserted = currentMilliseconds;
|
||||
m_queue.push(timedEvent->m_handle);
|
||||
return timedEvent->m_handle;
|
||||
@@ -126,7 +127,9 @@ namespace AZ
|
||||
}
|
||||
|
||||
TimeMs currentMilliseconds = GetElapsedTimeMs();
|
||||
ScheduledEvent* timedEvent = AllocateManagedEvent(TimeMs(currentMilliseconds + durationMs), durationMs, callback, eventName);
|
||||
ScheduledEvent* timedEvent = AllocateManagedEvent(callback, eventName);
|
||||
const bool ownsScheduledEvent = true;
|
||||
*(timedEvent->m_handle) = ScheduledEventHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent, ownsScheduledEvent);
|
||||
timedEvent->m_timeInserted = currentMilliseconds;
|
||||
m_queue.push(timedEvent->m_handle);
|
||||
}
|
||||
@@ -150,10 +153,12 @@ namespace AZ
|
||||
{
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::HandleCount = %u", aznumeric_cast<uint32_t>(GetHandleCount()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::FreeHandleCount = %u", aznumeric_cast<uint32_t>(GetFreeHandleCount()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::OwnedEventCount = %u", aznumeric_cast<uint32_t>(m_ownedEvents.size()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::FreeEventCount = %u", aznumeric_cast<uint32_t>(m_freeEvents.size()));
|
||||
AZLOG_INFO("EventSchedulerSystemComponent::QueueSize = %u", aznumeric_cast<uint32_t>(GetQueueSize()));
|
||||
}
|
||||
|
||||
ScheduledEventHandle* EventSchedulerSystemComponent::AllocateHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent)
|
||||
ScheduledEventHandle* EventSchedulerSystemComponent::AllocateHandle()
|
||||
{
|
||||
ScheduledEventHandle* result = nullptr;
|
||||
if (!m_freeHandles.empty())
|
||||
@@ -166,31 +171,34 @@ namespace AZ
|
||||
m_handles.resize(m_handles.size() + 1);
|
||||
result = &(m_handles.back());
|
||||
}
|
||||
*result = ScheduledEventHandle(executeTimeMs, durationTimeMs, scheduledEvent, false);
|
||||
return result;
|
||||
}
|
||||
|
||||
ScheduledEvent* EventSchedulerSystemComponent::AllocateManagedEvent(TimeMs executeTimeMs, TimeMs durationTimeMs, const AZStd::function<void()>& callback, const Name& eventName)
|
||||
ScheduledEvent* EventSchedulerSystemComponent::AllocateManagedEvent(const AZStd::function<void()>& callback, const Name& eventName)
|
||||
{
|
||||
ScheduledEvent* result = new ScheduledEvent(callback, eventName);
|
||||
ScheduledEventHandle* handle = nullptr;
|
||||
if (!m_freeHandles.empty())
|
||||
ScheduledEvent* scheduledEvent = nullptr;
|
||||
if (!m_freeEvents.empty())
|
||||
{
|
||||
handle = m_freeHandles.back();
|
||||
m_freeHandles.pop_back();
|
||||
scheduledEvent = m_freeEvents.back();
|
||||
m_freeEvents.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_handles.resize(m_handles.size() + 1);
|
||||
handle = &(m_handles.back());
|
||||
m_ownedEvents.resize(m_ownedEvents.size() + 1);
|
||||
scheduledEvent = &(m_ownedEvents.back());
|
||||
}
|
||||
*handle = ScheduledEventHandle(executeTimeMs, durationTimeMs, result, true);
|
||||
result->m_handle = handle;
|
||||
return result;
|
||||
scheduledEvent->m_eventName = eventName;
|
||||
scheduledEvent->m_callback = callback;
|
||||
scheduledEvent->m_handle = AllocateHandle();
|
||||
return scheduledEvent;
|
||||
}
|
||||
|
||||
void EventSchedulerSystemComponent::FreeHandle(ScheduledEventHandle* handle)
|
||||
{
|
||||
if (handle->GetOwnsScheduledEvent())
|
||||
{
|
||||
m_freeEvents.push_back(handle->GetScheduledEvent());
|
||||
}
|
||||
m_freeHandles.push_back(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/EBus/ScheduledEventHandle.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
@@ -89,9 +90,11 @@ namespace AZ
|
||||
//! @}
|
||||
|
||||
private:
|
||||
ScheduledEventHandle* AllocateHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent);
|
||||
// Allocates a single use event to capture the passed in callback. Event is cleaned up on completion.
|
||||
ScheduledEvent* AllocateManagedEvent(TimeMs executeTimeMs, TimeMs durationTimeMs, const AZStd::function<void()>& callback, const Name& eventName);
|
||||
ScheduledEventHandle* AllocateHandle();
|
||||
|
||||
//! Allocates a single use event to capture the passed in callback. Event is cleaned up on completion.
|
||||
ScheduledEvent* AllocateManagedEvent(const AZStd::function<void()>& callback, const Name& eventName);
|
||||
|
||||
void FreeHandle(ScheduledEventHandle* handle);
|
||||
|
||||
// Bind the DumpStats member function to the console as 'EventSchedulerSystemComponent.DumpStats'
|
||||
@@ -100,6 +103,8 @@ namespace AZ
|
||||
// Priority queues of scheduled events sorted by execution time
|
||||
AZStd::priority_queue<ScheduledEventHandle*, AZStd::vector<ScheduledEventHandle*>, CompareScheduledEventPtrs> m_queue;
|
||||
AZStd::priority_queue<ScheduledEventHandle*, AZStd::vector<ScheduledEventHandle*>, PrioritizeScheduledEventPtrs> m_pendingQueue;
|
||||
AZStd::deque<ScheduledEvent> m_ownedEvents;
|
||||
AZStd::vector<ScheduledEvent*> m_freeEvents;
|
||||
AZStd::deque<ScheduledEventHandle> m_handles;
|
||||
AZStd::vector<ScheduledEventHandle*> m_freeHandles;
|
||||
};
|
||||
|
||||
@@ -359,7 +359,7 @@ namespace AZ
|
||||
|
||||
//insert the new handler
|
||||
handler.m_index = aznumeric_cast<int32_t>(AZStd::distance(m_handlers.begin(), insertLocation));
|
||||
auto insertedItr = m_handlers.insert(insertLocation, &handler);
|
||||
m_handlers.insert(insertLocation, &handler);
|
||||
return handler.m_index;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ namespace AZ
|
||||
void ScheduledEvent::Requeue(TimeMs durationMs)
|
||||
{
|
||||
m_durationMs = durationMs;
|
||||
ClearHandle();
|
||||
IEventScheduler* eventScheduler = Interface<IEventScheduler>::Get();
|
||||
if (eventScheduler)
|
||||
{
|
||||
@@ -120,10 +119,6 @@ namespace AZ
|
||||
|
||||
void ScheduledEvent::ClearHandle()
|
||||
{
|
||||
if (m_handle)
|
||||
{
|
||||
m_handle->Clear();
|
||||
m_handle = nullptr;
|
||||
}
|
||||
m_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace AZ
|
||||
class ScheduledEvent
|
||||
{
|
||||
public:
|
||||
//! Default constructor only for AZStd::deque compatibility.
|
||||
ScheduledEvent() = default;
|
||||
|
||||
//! Constructor of ScheduledEvent class.
|
||||
//! @param callback a call back function to be executed when the event triggers
|
||||
//! @param eventName name of the scheduled event for easier debugging
|
||||
@@ -82,8 +85,6 @@ namespace AZ
|
||||
//! Clears any currently set handle pointer.
|
||||
void ClearHandle();
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(ScheduledEvent);
|
||||
|
||||
Name m_eventName; //< Scheduled event name
|
||||
AZStd::function<void()> m_callback; //< A callback function to run when the scheduled event triggers
|
||||
ScheduledEventHandle* m_handle = nullptr; //< Handle pointer to protect running a deleted event callback function
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
ScheduledEventHandle::ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool isAutoDelete)
|
||||
ScheduledEventHandle::ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool ownsScheduledEvent)
|
||||
: m_executeTimeMs(executeTimeMs)
|
||||
, m_durationMs(durationTimeMs)
|
||||
, m_event(scheduledEvent)
|
||||
, m_autoDelete(isAutoDelete)
|
||||
, m_ownsScheduledEvent(ownsScheduledEvent)
|
||||
{
|
||||
;
|
||||
}
|
||||
@@ -49,11 +49,6 @@ namespace AZ
|
||||
else // Not configured to auto-requeue, so remove the handle
|
||||
{
|
||||
m_event->ClearHandle();
|
||||
if (m_autoDelete)
|
||||
{
|
||||
delete m_event;
|
||||
}
|
||||
m_event = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,11 +60,6 @@ namespace AZ
|
||||
return false; // Event has been deleted, so the handle class must be deleted after this function.
|
||||
}
|
||||
|
||||
void ScheduledEventHandle::Clear()
|
||||
{
|
||||
m_event = nullptr;
|
||||
}
|
||||
|
||||
TimeMs ScheduledEventHandle::GetExecuteTimeMs() const
|
||||
{
|
||||
return m_executeTimeMs;
|
||||
@@ -79,4 +69,14 @@ namespace AZ
|
||||
{
|
||||
return m_durationMs;
|
||||
}
|
||||
|
||||
bool ScheduledEventHandle::GetOwnsScheduledEvent() const
|
||||
{
|
||||
return m_ownsScheduledEvent;
|
||||
}
|
||||
|
||||
ScheduledEvent* ScheduledEventHandle::GetScheduledEvent() const
|
||||
{
|
||||
return m_event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace AZ
|
||||
//! @param executeTimeMs an absolute time in ms at which point the scheduled event should trigger
|
||||
//! @param durationTimeMs the interval time in ms used for prioritization as well as re-queueing
|
||||
//! @param scheduledEvent a scheduled event to run
|
||||
//! @param autoDelete if the event handle will be automatically deleted after execution completes
|
||||
ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool isAutoDelete);
|
||||
//! @param ownsScheduledEvent true if the event handle owns its own scheduled event instance
|
||||
ScheduledEventHandle(TimeMs executeTimeMs, TimeMs durationTimeMs, ScheduledEvent* scheduledEvent, bool ownsScheduledEvent = false);
|
||||
|
||||
//! operator of comparing a scheduled event by execute time.
|
||||
//! @param a_Rhs a scheduled event handle to compare
|
||||
@@ -42,9 +42,6 @@ namespace AZ
|
||||
//! @return true for re-queuing a scheduled event or false for deleting this class.
|
||||
bool Notify();
|
||||
|
||||
//! Set nullptr for a scheduled event pointer.
|
||||
void Clear();
|
||||
|
||||
//! Get the execution time in ms for this scheduled event.
|
||||
//! @return the execution time in ms for this scheduled event
|
||||
TimeMs GetExecuteTimeMs() const;
|
||||
@@ -54,12 +51,20 @@ namespace AZ
|
||||
//! @return the duration time in ms for this scheduled event
|
||||
TimeMs GetDurationTimeMs() const;
|
||||
|
||||
//! Gets whether or not the event handle owns its own scheduled event.
|
||||
//! @return true if the event handle owns
|
||||
bool GetOwnsScheduledEvent() const;
|
||||
|
||||
//! Gets the scheduled event instance bound to this event handle.
|
||||
//! @return the scheduled event instance bound to this event handle
|
||||
ScheduledEvent* GetScheduledEvent() const;
|
||||
|
||||
private:
|
||||
|
||||
TimeMs m_executeTimeMs = TimeMs{ 0 }; //< execution time of the scheduled event
|
||||
TimeMs m_durationMs = TimeMs{ 0 }; //< interval time of the scheduled event
|
||||
ScheduledEvent* m_event = nullptr; //< pointer to the scheduled event
|
||||
bool m_autoDelete = false; //< if the handle manages the memory of its own event
|
||||
bool m_ownsScheduledEvent = false; //< if the handle manages the memory of its own event
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -214,6 +214,20 @@ namespace AZ::IO::Internal
|
||||
// logic
|
||||
return IsAbsolute(pathView.begin(), pathView.end(), preferredSeparator);
|
||||
}
|
||||
|
||||
// Compares path segments using either Posix or Windows path rules based on the path separator in use
|
||||
// Posix paths perform a case-sensitive comparison, while Windows paths perform a case-insensitive comparison
|
||||
static int ComparePathSegment(AZStd::string_view left, AZStd::string_view right, char pathSeparator)
|
||||
{
|
||||
const size_t maxCharsToCompare = (AZStd::min)(left.size(), right.size());
|
||||
|
||||
int charCompareResult = pathSeparator == PosixPathSeparator
|
||||
? strncmp(left.data(), right.data(), maxCharsToCompare)
|
||||
: azstrnicmp(left.data(), right.data(), maxCharsToCompare);
|
||||
return charCompareResult == 0
|
||||
? aznumeric_cast<ptrdiff_t>(left.size()) - aznumeric_cast<ptrdiff_t>(right.size())
|
||||
: charCompareResult;
|
||||
}
|
||||
}
|
||||
|
||||
//! PathParser implementation
|
||||
@@ -351,7 +365,6 @@ namespace AZ::IO::parser
|
||||
constexpr void Decrement() noexcept
|
||||
{
|
||||
auto pathStart = m_path_view.begin();
|
||||
auto pathEnd = m_path_view.end();
|
||||
auto currentPathEntry = getCurrentTokenStartPos();
|
||||
|
||||
if (currentPathEntry == pathStart)
|
||||
@@ -613,7 +626,7 @@ namespace AZ::IO::parser
|
||||
{
|
||||
return pathParser->InRootName() ? **pathParser : "";
|
||||
};
|
||||
int res = GetRootName(lhsPathParser).compare(GetRootName(rhsPathParser));
|
||||
int res = Internal::ComparePathSegment(GetRootName(lhsPathParser), GetRootName(rhsPathParser), lhsPathParser->m_preferred_separator);
|
||||
ConsumeRootName(lhsPathParser);
|
||||
ConsumeRootName(rhsPathParser);
|
||||
return res;
|
||||
@@ -642,7 +655,8 @@ namespace AZ::IO::parser
|
||||
|
||||
while (lhsPathParser && rhsPathParser)
|
||||
{
|
||||
if (int res = (*lhsPathParser).compare(*rhsPathParser); res != 0)
|
||||
if (int res = Internal::ComparePathSegment(*lhsPathParser, *rhsPathParser, lhsPathParser.m_preferred_separator);
|
||||
res != 0)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -1033,11 +1047,25 @@ namespace AZ::IO
|
||||
parser::PathParser patternParserEnd(pathPatternView.relative_path_view(), parser::ParserState::PS_AtEnd, pathPatternView.m_preferred_separator);
|
||||
|
||||
// move the parser from the end to a valid filename by decrementing
|
||||
for(--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
// Windows Paths are case-insensitive, while Posix paths are case-sensitive
|
||||
if (m_preferred_separator == PosixPathSeparator)
|
||||
{
|
||||
if (!AZStd::wildcard_match_case(*patternParserEnd, *pathParserEnd))
|
||||
for (--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
{
|
||||
return false;
|
||||
if (!AZStd::wildcard_match_case(*patternParserEnd, *pathParserEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
{
|
||||
if (!AZStd::wildcard_match(*patternParserEnd, *pathParserEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -300,7 +300,6 @@ namespace AZ
|
||||
context.Class<Uuid>("Uuid")->
|
||||
Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)->
|
||||
Attribute(AZ::Script::Attributes::Module, "math")->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)->
|
||||
Attribute(AZ::Script::Attributes::ConstructorOverride, &Internal::ScriptUuidConstructor)->
|
||||
Attribute(AZ::Script::Attributes::GenericConstructorOverride, &Internal::UuidDefaultConstructor)->
|
||||
|
||||
@@ -18,11 +18,8 @@ namespace AZ
|
||||
{
|
||||
Quaternion CreateRandomQuaternion(SimpleLcgRandom& rng)
|
||||
{
|
||||
float u1 = rng.GetRandomFloat();
|
||||
float u2 = rng.GetRandomFloat();
|
||||
float u3 = rng.GetRandomFloat();
|
||||
float c1 = Sqrt(1.0f - u1);
|
||||
float c2 = Sqrt(u1);
|
||||
float x, y, z, w;
|
||||
SinCos(Constants::TwoPi * u2, x, y);
|
||||
SinCos(Constants::TwoPi * u3, z, w);
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace AZ
|
||||
{
|
||||
behaviorContext->Class<Obb>()->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Attribute(Script::Attributes::GenericConstructorOverride, &Internal::ObbDefaultConstructor)->
|
||||
Property("position", &Obb::GetPosition, &Obb::SetPosition)->
|
||||
|
||||
@@ -104,9 +104,9 @@ namespace AZ
|
||||
// As one return value (hit point) is based on the other (hit time), for simplicity, the Lua implementation
|
||||
// just returns all three values: does the ray hit? When does it hit? Where does it hit?
|
||||
|
||||
if (!dc.IsClass<Vector3>(0) || !dc.IsClass<Vector3>(0))
|
||||
if (!dc.IsClass<Vector3>(0) || !dc.IsClass<Vector3>(1))
|
||||
{
|
||||
AZ_Error("Script", false, "ScriptPlane CastRay requires two ScriptVector3s as arguments.");
|
||||
AZ_Error("Script", false, "ScriptPlane IntersectSegment requires two ScriptVector3s as arguments.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ namespace AZ
|
||||
{
|
||||
behaviorContext->Class<Plane>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)->
|
||||
Attribute(AZ::Script::Attributes::GenericConstructorOverride, &Internal::PlaneDefaultConstructor)->
|
||||
Method("ToString", &Internal::PlaneToString)->
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace AZ
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<PolygonPrism>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::RuntimeOwn)
|
||||
->Property("height", BehaviorValueGetter(&PolygonPrism::m_height), nullptr)
|
||||
->Property("vertexContainer", BehaviorValueGetter(&PolygonPrism::m_vertexContainer), nullptr)
|
||||
|
||||
@@ -111,13 +111,11 @@ namespace AZ
|
||||
Property("segmentFraction", BehaviorValueProperty(&SplineAddress::m_segmentFraction));
|
||||
|
||||
behaviorContext->Class<PositionSplineQueryResult>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Property("splineAddress", [](PositionSplineQueryResult* thisPtr) { return thisPtr->m_splineAddress; }, nullptr)->
|
||||
Property("distanceSq", [](PositionSplineQueryResult* thisPtr) { return thisPtr->m_distanceSq; }, nullptr);
|
||||
|
||||
behaviorContext->Class<RaySplineQueryResult>()->
|
||||
Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)->
|
||||
Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)->
|
||||
Property("splineAddress", [](RaySplineQueryResult* thisPtr) { return thisPtr->m_splineAddress; }, nullptr)->
|
||||
Property("distanceSq", [](RaySplineQueryResult* thisPtr) { return thisPtr->m_distanceSq; }, nullptr)->
|
||||
|
||||
@@ -720,9 +720,9 @@ namespace AZ
|
||||
StoragePolicyBase<Allocator>::Destroy(Base::GetModuleAllocatorInstance());
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE static bool IsReady()
|
||||
static bool IsReady()
|
||||
{
|
||||
return true;
|
||||
return Base::GetModuleAllocatorInstance().IsReady();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -515,7 +515,6 @@ namespace AZ
|
||||
->Attribute(AZ::Script::Attributes::EnableAsScriptEventParamType, &IsScriptEventType)
|
||||
->Method("AssignAt", &AssignAt, { { {}, { "Index", "The index at which to assign the element to, resizes the container if necessary", nullptr, BehaviorParameter::Traits::TR_INDEX } } })
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::IndexWrite)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Method("Erase_VM", &ErasePost_VM, { { { "Container", "The container from which to delete", nullptr, {} }, { "Key", "The key to delete", nullptr, {} } } })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Erase", "Containers"))
|
||||
@@ -526,35 +525,29 @@ namespace AZ
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->template Method<void(ContainerType::*)(typename ContainerType::const_reference)>("push_back", &ContainerType::push_back)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Method("PushBack_VM", &PushBack_VM, { { { "Container", "The container into which to add an element to", nullptr, {} }, { "Value", "The value to be added", nullptr, {} } } })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Add Element at End", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "" }, { "ContainerGroup" }))
|
||||
->Method("pop_back", &ContainerType::pop_back)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->template Method<typename ContainerType::reference(ContainerType::*)(typename ContainerType::size_type)>
|
||||
("at", &ContainerType::at, {{ { "Index", "The index to read from", nullptr, BehaviorParameter::Traits::TR_INDEX } }})->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::IndexRead)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Deprecated, true)
|
||||
->template Method<typename ContainerType::reference(ContainerType::*)(typename ContainerType::size_type)>(k_accessElementNameUnchecked, &ContainerType::at, { { { "Index", "The index to read from", nullptr } } })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Element", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::CheckedOperation, CheckedOperationInfo("Has Key", {}, "Out", "Key Not Found"))
|
||||
->Method("size", [](ContainerType& thisPtr) { return aznumeric_cast<int>(thisPtr.size()); })
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Length)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Method("GetSize", [](ContainerType& thisPtr) { return aznumeric_cast<int>(thisPtr.size()); }, { { { "Container", "The container to get the size of", nullptr, {} } } })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Size", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Method("clear", &ContainerType::clear)
|
||||
->template Method<typename ContainerType::reference(ContainerType::*)(typename ContainerType::size_type)>(k_accessElementName, &ContainerType::at, { { { "Index", "The index to read from", nullptr, BehaviorParameter::Traits::TR_INDEX } } })
|
||||
->Method("Capacity", &ContainerType::capacity)
|
||||
->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; }, { { { "Container", "The container to clear", nullptr, {} } } })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" }))
|
||||
->Method("Empty", &ContainerType::empty, { { { "Container", "The container to check if it is empty", nullptr, {} } } })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Is Empty", "Containers"))
|
||||
@@ -798,10 +791,8 @@ namespace AZ
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->template Constructor<const T1&, const T2&>()
|
||||
->Property("first", [](ContainerType& thisPtr) { return thisPtr.first; }, [](ContainerType& thisPtr, const T1& value) { thisPtr.first = value; })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, 0)
|
||||
->Property("second", [](ContainerType& thisPtr) { return thisPtr.second; }, [](ContainerType& thisPtr, const T2& value) { thisPtr.second = value; })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, 1)
|
||||
->Method("ConstructTuple", [](const T1& first, const T2& second) { return AZStd::make_pair(first, second); })
|
||||
;
|
||||
@@ -1013,7 +1004,6 @@ namespace AZ
|
||||
->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" }))
|
||||
->Method(k_iteratorConstructorName, &Iterate_VM)
|
||||
;
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace AZ
|
||||
{
|
||||
const static AZ::Crc32 RuntimeEBusAttribute = AZ_CRC("RuntimeEBus", 0x466b899b); ///< Signals that this reflected ebus should only be available at runtime, helps tools filter out data driven ebuses
|
||||
|
||||
constexpr const char* k_PropertyNameGetterSuffix = "::Getter";
|
||||
constexpr const char* k_PropertyNameSetterSuffix = "::Setter";
|
||||
|
||||
/// Typedef for class unwrapping callback (i.e. used for things like smart_ptr<T> to unwrap for T)
|
||||
using BehaviorClassUnwrapperFunction = void(*)(void* /*classPtr*/, void*& /*unwrappedClass*/, AZ::Uuid& /*unwrappedClassTypeId*/, void* /*userData*/);
|
||||
|
||||
@@ -2525,7 +2528,7 @@ namespace AZ
|
||||
getterPropertyName += "::";
|
||||
}
|
||||
getterPropertyName += m_name;
|
||||
getterPropertyName += "::Getter";
|
||||
getterPropertyName += k_PropertyNameGetterSuffix;
|
||||
m_getter = aznew GetterType(getter, context, getterPropertyName);
|
||||
|
||||
if (AZStd::is_class<typename GetterType::ClassType>::value)
|
||||
@@ -2603,7 +2606,7 @@ namespace AZ
|
||||
setterPropertyName += "::";
|
||||
}
|
||||
setterPropertyName += m_name;
|
||||
setterPropertyName += "::Setter";
|
||||
setterPropertyName += k_PropertyNameSetterSuffix;
|
||||
m_setter = aznew SetterType(setter, context, setterPropertyName);
|
||||
if (AZStd::is_class<typename SetterType::ClassType>::value)
|
||||
{
|
||||
|
||||
@@ -243,6 +243,28 @@ namespace AZ
|
||||
return variance;
|
||||
}
|
||||
|
||||
void RemovePropertyGetterNameArtifacts(AZStd::string& name)
|
||||
{
|
||||
if (name.ends_with(k_PropertyNameGetterSuffix))
|
||||
{
|
||||
AZ::StringFunc::Replace(name, k_PropertyNameGetterSuffix, "");
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePropertySetterNameArtifacts(AZStd::string& name)
|
||||
{
|
||||
if (name.ends_with(k_PropertyNameSetterSuffix))
|
||||
{
|
||||
AZ::StringFunc::Replace(name, k_PropertyNameSetterSuffix, "");
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePropertyNameArtifacts(AZStd::string& name)
|
||||
{
|
||||
RemovePropertyGetterNameArtifacts(name);
|
||||
RemovePropertySetterNameArtifacts(name);
|
||||
}
|
||||
|
||||
AZStd::string ReplaceCppArtifacts(AZStd::string_view sourceName)
|
||||
{
|
||||
using namespace AZ::StringFunc;
|
||||
|
||||
@@ -68,6 +68,12 @@ namespace AZ
|
||||
|
||||
AZStd::vector<AZStd::pair<const BehaviorMethod*, const BehaviorClass*>> OverloadsToVector(const BehaviorMethod&, const BehaviorClass*);
|
||||
|
||||
void RemovePropertyGetterNameArtifacts(AZStd::string& name);
|
||||
|
||||
void RemovePropertySetterNameArtifacts(AZStd::string& name);
|
||||
|
||||
void RemovePropertyNameArtifacts(AZStd::string& name);
|
||||
|
||||
AZStd::string ReplaceCppArtifacts(AZStd::string_view sourceName);
|
||||
|
||||
void StripQualifiers(AZStd::string& name);
|
||||
|
||||
@@ -51,11 +51,11 @@ namespace AZ
|
||||
const static AZ::Crc32 ExcludeFrom = AZ_CRC("ExcludeFrom", 0xa98972fe);
|
||||
enum ExcludeFlags : AZ::u64
|
||||
{
|
||||
List = 1 << 0,
|
||||
Documentation = 1 << 1,
|
||||
Preview = 1 << 2,
|
||||
ListOnly = 1 << 3,
|
||||
All = (List | Documentation | Preview)
|
||||
List = 1 << 0, //< The reflected item will be excluded from any list (e.g. node palette)
|
||||
Documentation = 1 << 1, //< The reflected item will be excluded from the Lua class reference
|
||||
Unused = 1 << 2, //< This flag is unused (deprecated)
|
||||
ListOnly = 1 << 3, //< Some elements should be excluded from lists, but available for documentation
|
||||
All = (List | Documentation) //< Used to exclude reflections from lists and documentation
|
||||
};
|
||||
|
||||
//! Used to specify the usage of a Behavior Context element (e.g. Class or EBus) designed for automation scripts
|
||||
|
||||
@@ -929,7 +929,6 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection)
|
||||
Debug::TraceReflect(behaviorContext);
|
||||
|
||||
behaviorContext->Class<PlatformID>("Platform")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_WINDOWS_64)>("Windows64")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_LINUX_64)>("Linux")
|
||||
->Enum<static_cast<int>(PlatformID::PLATFORM_ANDROID_64)>("Android64")
|
||||
|
||||
@@ -1452,6 +1452,13 @@ namespace AZ
|
||||
|
||||
void* parentPtr = nodeStack.back().m_ptr;
|
||||
DataElementNode* parentDataElement = nodeStack.back().m_dataElement;
|
||||
AZ_Assert(parentDataElement, "parentDataElement is null, cannot enumerate data from data element (%s:%s)",
|
||||
m_element.m_name ? m_element.m_name : "", m_element.m_id.ToString<AZStd::string>().data());
|
||||
if (!parentDataElement)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
if (!m_classData)
|
||||
@@ -1472,7 +1479,6 @@ namespace AZ
|
||||
if (classElementFound)
|
||||
{
|
||||
void* dataAddress = nullptr;
|
||||
void* reserveAddress = nullptr;
|
||||
IDataContainer* dataContainer = parentDataElement->m_classData->m_container;
|
||||
if (dataContainer) // container elements
|
||||
{
|
||||
@@ -1500,7 +1506,7 @@ namespace AZ
|
||||
dataAddress = reinterpret_cast<char*>(parentPtr) + classElement.m_offset;
|
||||
}
|
||||
|
||||
reserveAddress = dataAddress;
|
||||
void* reserveAddress = dataAddress;
|
||||
|
||||
// create a new instance if needed
|
||||
if (classElement.m_flags & SerializeContext::ClassElement::FLG_POINTER)
|
||||
|
||||
@@ -1471,8 +1471,7 @@ namespace AZ
|
||||
{
|
||||
return [serializeContext](AZStd::any::Action action, AZStd::any* dest, const AZStd::any* source)
|
||||
{
|
||||
auto classData = serializeContext->FindClassData(dest->type());
|
||||
AZ_Assert(classData, "Type %s stored in any must be registered with the serialize context", AZ::AzTypeInfo<ValueType>::Name());
|
||||
AZ_Assert(serializeContext->FindClassData(dest->type()), "Type %s stored in any must be registered with the serialize context", AZ::AzTypeInfo<ValueType>::Name());
|
||||
|
||||
switch (action)
|
||||
{
|
||||
|
||||
@@ -502,10 +502,9 @@ namespace AZ
|
||||
altClassElement.m_offset = 0;
|
||||
VariantSerializationInternal::SetupClassElementFromType<AltType>(altClassElement);
|
||||
const AZ::Uuid& altTypeId = altClassElement.m_typeId;
|
||||
const char* altName = AzTypeInfo<AltType>::Name();
|
||||
|
||||
const SerializeContext::ClassData* altClassData = context.FindClassData(altTypeId);
|
||||
AZ_Error("Serialize", altClassData, "Unable to find ClassData for variant alternative with name %s and typeid of %s", altName, altTypeId.ToString<AZStd::string>().data());
|
||||
AZ_Error("Serialize", altClassData, "Unable to find ClassData for variant alternative with name %s and typeid of %s", AzTypeInfo<AltType>::Name(), altTypeId.ToString<AZStd::string>().data());
|
||||
return altClassData ? callContext.m_context->EnumerateInstanceConst(&callContext, &elementAlt, altTypeId, altClassData, &altClassElement) : false;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,18 +30,6 @@
|
||||
|
||||
namespace AZ::Internal
|
||||
{
|
||||
AZ::IO::FixedMaxPath GetExecutableDirectory()
|
||||
{
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> value;
|
||||
|
||||
// Binary folder
|
||||
AZ::Utils::ExecutablePathResult pathResult = Utils::GetExecutableDirectory(value.data(), value.capacity());
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string stored within it
|
||||
value.resize_no_construct(AZStd::char_traits<char>::length(value.data()));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString GetEngineMonikerForProject(
|
||||
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
|
||||
{
|
||||
@@ -146,7 +134,7 @@ namespace AZ::Internal
|
||||
{
|
||||
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
|
||||
if (Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
|
||||
if (AZ::Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
|
||||
// stored within it
|
||||
@@ -494,7 +482,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry)
|
||||
{
|
||||
// Binary folder
|
||||
AZ::IO::FixedMaxPath path = Internal::GetExecutableDirectory();
|
||||
AZ::IO::FixedMaxPath path = AZ::Utils::GetExecutableDirectory();
|
||||
registry.Set(FilePathKey_BinaryFolder, path.LexicallyNormal().Native());
|
||||
|
||||
// Engine root folder - corresponds to the @engroot@ and @devroot@ aliases
|
||||
@@ -601,7 +589,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
void MergeSettingsToRegistry_TargetBuildDependencyRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer)
|
||||
{
|
||||
AZ::IO::FixedMaxPath mergePath = Internal::GetExecutableDirectory();
|
||||
AZ::IO::FixedMaxPath mergePath = AZ::Utils::GetExecutableDirectory();
|
||||
if (!mergePath.empty())
|
||||
{
|
||||
registry.MergeSettingsFolder((mergePath / SettingsRegistryInterface::RegistryFolder).Native(),
|
||||
|
||||
@@ -17,10 +17,12 @@ namespace UnitTest
|
||||
MockComponentApplication::MockComponentApplication()
|
||||
{
|
||||
AZ::ComponentApplicationBus::Handler::BusConnect();
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
|
||||
MockComponentApplication::~MockComponentApplication()
|
||||
{
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Unregister(this);
|
||||
AZ::ComponentApplicationBus::Handler::BusDisconnect();
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace UnitTest
|
||||
@@ -30,6 +31,8 @@ namespace UnitTest
|
||||
MOCK_METHOD0(Destroy, void ());
|
||||
MOCK_METHOD1(RegisterComponentDescriptor, void (const AZ::ComponentDescriptor*));
|
||||
MOCK_METHOD1(UnregisterComponentDescriptor, void (const AZ::ComponentDescriptor*));
|
||||
MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&));
|
||||
MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&));
|
||||
MOCK_METHOD1(RemoveEntity, bool (AZ::Entity*));
|
||||
MOCK_METHOD1(DeleteEntity, bool (const AZ::EntityId&));
|
||||
MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&));
|
||||
|
||||
@@ -636,7 +636,6 @@ namespace AZStd
|
||||
{
|
||||
AZSTD_CONTAINER_ASSERT(!full(), "Cannot emplace on a full fixed_vector");
|
||||
AZSTD_CONTAINER_ASSERT(insertPos >= cbegin() && insertPos <= cend(), "insert position must be in range of container");
|
||||
pointer dataStart = data();
|
||||
pointer dataEnd = data() + size();
|
||||
pointer insertPosPtr = data() + AZStd::distance(cbegin(), insertPos);
|
||||
|
||||
@@ -896,7 +895,7 @@ namespace AZStd
|
||||
if (numInitializedToFill < numElements)
|
||||
{
|
||||
// Copy the elements after insert position.
|
||||
iterator newLast = AZStd::uninitialized_move(insertPosPtr, dataEnd, insertPosPtr + numElements);
|
||||
AZStd::uninitialized_move(insertPosPtr, dataEnd, insertPosPtr + numElements);
|
||||
// get last iterator to use move assignment operator
|
||||
Iterator lastToAssign = AZStd::next(first, numInitializedToFill);
|
||||
|
||||
|
||||
+2
-4
@@ -28,8 +28,7 @@ namespace AZ::Platform
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD error = ::GetLastError();
|
||||
AZ_Assert(event, "Failed to create a required event for IO Scheduler (Error: %u).", error);
|
||||
AZ_Assert(event, "Failed to create a required event for IO Scheduler (Error: %u).", ::GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,8 +42,7 @@ namespace AZ::Platform
|
||||
{
|
||||
if (!::CloseHandle(event))
|
||||
{
|
||||
DWORD error = ::GetLastError();
|
||||
AZ_Assert(false, "Failed to close an event handle for IO Scheduler (Error: %u)", error);
|
||||
AZ_Assert(false, "Failed to close an event handle for IO Scheduler (Error: %u)", ::GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ namespace AZStd
|
||||
// detect a sitaution where the mutex or the cond var are invalid, or the duration
|
||||
AZ_Assert(lastError == AZ_ERROR_TIMEOUT, "Error from SleepConditionVariableCS: 0x%08x\n", lastError);
|
||||
// asserts are continuable so we still check.
|
||||
if (GetLastError() == AZ_ERROR_TIMEOUT)
|
||||
if (lastError == AZ_ERROR_TIMEOUT)
|
||||
{
|
||||
return cv_status::timeout;
|
||||
}
|
||||
|
||||
@@ -70,5 +70,4 @@ set(FILES
|
||||
AzCore/Utils/Utils_iOS.mm
|
||||
../Common/Apple/AzCore/Utils/Utils_Apple.cpp
|
||||
../Common/UnixLike/AzCore/Utils/Utils_UnixLike.cpp
|
||||
../Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp
|
||||
)
|
||||
|
||||
@@ -1769,7 +1769,6 @@ namespace UnitTest
|
||||
{
|
||||
return "HelloWorld";
|
||||
};
|
||||
constexpr const TypeParam* compileTimeString1 = MakeCompileTimeString1();
|
||||
constexpr basic_string_view<TypeParam> modifierView("HelloWorld");
|
||||
// A constexpr lambda is used to evaluate non constexpr string_view instances' member functions which
|
||||
// have been marked as constexpr at compile time
|
||||
@@ -2334,7 +2333,6 @@ namespace UnitTest
|
||||
const char* filter1{ "*" };
|
||||
const char* filter2{ "*?" };
|
||||
const char* filter3{ "?*" };
|
||||
const char* testValue{ "" };
|
||||
EXPECT_TRUE(wildcard_match(filter1, "Hello"));
|
||||
EXPECT_TRUE(wildcard_match(filter1, "?"));
|
||||
EXPECT_TRUE(wildcard_match(filter1, "*"));
|
||||
|
||||
@@ -53,35 +53,27 @@ namespace UnitTest
|
||||
{
|
||||
// Trvially validate that we can create and destroy an asset manager instance, and that it's only ready while it's created.
|
||||
|
||||
// Before creation, IsReady() should be false and trying to get an Instance() should cause an assert.
|
||||
// Before creation, IsReady() should be false.
|
||||
EXPECT_FALSE(AssetManager::IsReady());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
auto& badInstance = AssetManager::Instance();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
AssetManager::Descriptor desc;
|
||||
AssetManager::Create(desc);
|
||||
|
||||
// After creation, the system should be ready and queryable via Instance().
|
||||
EXPECT_TRUE(AssetManager::IsReady());
|
||||
auto& goodInstance = AssetManager::Instance();
|
||||
AssetManager::Instance();
|
||||
|
||||
AssetManager::Destroy();
|
||||
|
||||
// After destruction, these should fail again
|
||||
EXPECT_FALSE(AssetManager::IsReady());
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
auto& badInstance2 = AssetManager::Instance();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_CREATE_DESTROY_TEST
|
||||
|
||||
TEST_F(AssetManagerSystemTest, AssetManager_SetInstance_TriviallyWorks)
|
||||
{
|
||||
// There shouldn't be an instance yet.
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
auto& badInstance = AssetManager::Instance();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
EXPECT_FALSE(AssetManager::IsReady());
|
||||
|
||||
// Create an instance and set it.
|
||||
AssetManager::Descriptor desc;
|
||||
@@ -669,7 +661,6 @@ namespace UnitTest
|
||||
EmptyAssetWithInstanceCount* origData = assetWithData.Get();
|
||||
AssetId origId = assetWithData.GetId();
|
||||
AssetType origType = assetWithData.GetType();
|
||||
AssetLoadBehavior origBehavior = assetWithData.GetAutoLoadBehavior();
|
||||
|
||||
Asset<EmptyAssetWithInstanceCount> assetWithData2(AZStd::move(assetWithData));
|
||||
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
@@ -29,10 +31,12 @@ namespace UnitTest
|
||||
m_behaviorContext = aznew AZ::BehaviorContext();
|
||||
|
||||
AZ::ComponentApplicationBus::Handler::BusConnect();
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Register(this);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
AZ::Interface<AZ::ComponentApplicationRequests>::Unregister(this);
|
||||
AZ::ComponentApplicationBus::Handler::BusDisconnect();
|
||||
|
||||
// Just destroy everything before we complete the tear down.
|
||||
@@ -45,7 +49,8 @@ namespace UnitTest
|
||||
// ComponentApplicationBus
|
||||
AZ::ComponentApplication* GetApplication() override { return nullptr; }
|
||||
void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override {}
|
||||
|
||||
void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override {}
|
||||
void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override {}
|
||||
void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override {}
|
||||
bool AddEntity(AZ::Entity*) override { return true; }
|
||||
bool RemoveEntity(AZ::Entity*) override { return true; }
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace AZ::Debug
|
||||
|
||||
realLogger.Start(logFilePath.c_str());
|
||||
|
||||
LargeBlock& block = logger->RecordEventBegin<LargeBlock>(largeBlockId);
|
||||
logger->RecordEventBegin<LargeBlock>(largeBlockId);
|
||||
logger->RecordEventEnd();
|
||||
|
||||
logger->RecordStringEvent(MessageId, message);
|
||||
|
||||
@@ -97,8 +97,6 @@ namespace UnitTest
|
||||
SAFE_EXPECT_EQ(AZ::ClampedIntegralLimits<ValueType, ClampType>::Max(), (std::numeric_limits<ValueType>::max)());
|
||||
|
||||
// Expect the natural numerical limits of ValueType to be equal to the natural numerical limits of ClampType
|
||||
ValueType vMin = AZ::ClampedIntegralLimits<ValueType, ClampType>::Min();
|
||||
ClampType cMin = std::numeric_limits<ClampType>::lowest();
|
||||
SAFE_EXPECT_EQ(AZ::ClampedIntegralLimits<ValueType, ClampType>::Min(), std::numeric_limits<ClampType>::lowest());
|
||||
SAFE_EXPECT_EQ(AZ::ClampedIntegralLimits<ValueType, ClampType>::Max(), (std::numeric_limits<ClampType>::max)());
|
||||
|
||||
|
||||
@@ -149,7 +149,6 @@ namespace UnitTest
|
||||
::testing::Values(
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("test/foo", "test/foo"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("test/foo", "test\\foo"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("test/foo", "test\\foo"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("test////foo", "test///foo"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("test/bar/baz//foo", "test/bar/baz\\\\\\foo")
|
||||
));
|
||||
@@ -159,17 +158,35 @@ namespace UnitTest
|
||||
constexpr AZ::IO::FixedMaxPath path1{ "foo/bar" };
|
||||
constexpr AZ::IO::FixedMaxPath path2{ "foo/bap" };
|
||||
constexpr AZ::IO::PathView pathView{ "foo/bar" };
|
||||
static_assert(path1 == pathView);
|
||||
static_assert(path1 != path2);
|
||||
static_assert(path2 < path1);
|
||||
static_assert(pathView <= path1);
|
||||
static_assert(path1 > path2);
|
||||
static_assert(pathView >= path2);
|
||||
EXPECT_EQ(path1, pathView);
|
||||
EXPECT_NE(path1, path2);
|
||||
EXPECT_LT(path2, path1);
|
||||
EXPECT_LE(pathView, path1);
|
||||
EXPECT_GT(path1, path2);
|
||||
EXPECT_GE(pathView, path2);
|
||||
|
||||
static_assert(pathView <= pathView);
|
||||
static_assert(pathView >= pathView);
|
||||
EXPECT_LE(pathView, pathView);
|
||||
EXPECT_GE(pathView, pathView);
|
||||
}
|
||||
|
||||
using WindowsPathCompareParamFixture = PathParamFixture;
|
||||
|
||||
TEST_P(WindowsPathCompareParamFixture, OperatorEqual_ComparesPathCaseInsensitively)
|
||||
{
|
||||
AZ::IO::Path path1{ AZStd::get<0>(GetParam()), AZ::IO::WindowsPathSeparator };
|
||||
AZ::IO::Path path2{ AZStd::get<1>(GetParam()), AZ::IO::WindowsPathSeparator };
|
||||
EXPECT_EQ(path1, path2);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
CompareWindowsPaths,
|
||||
WindowsPathCompareParamFixture,
|
||||
::testing::Values(
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>("C:/test/foo", R"(c:\test/foo)"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>(R"(D:\test/bar/baz//foo)", "d:/test/bar/baz\\\\\\foo"),
|
||||
AZStd::tuple<AZStd::string_view, AZStd::string_view>(R"(foO/Bar)", "foo/bar")
|
||||
));
|
||||
|
||||
class PathSingleParamFixture
|
||||
: public ScopedAllocatorSetupFixture
|
||||
, public ::testing::WithParamInterface<AZStd::tuple<AZStd::string_view>>
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x3 result = AZ::Matrix3x3::CreateIdentity();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -78,7 +78,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x3 result = AZ::Matrix3x3::CreateZero();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -134,7 +134,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x3 result = AZ::Matrix3x3::CreateFromRowMajorFloat9(s_mat3x3testArray);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -146,7 +146,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x3 result = AZ::Matrix3x3::CreateFromColumnMajorFloat9(s_mat3x3testArray);
|
||||
benchmark::DoNotOptimize(result);
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x4 result = AZ::Matrix3x4::CreateIdentity();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -96,7 +96,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix3x4 result = AZ::Matrix3x4::CreateZero();
|
||||
benchmark::DoNotOptimize(result);
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateIdentity();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -74,7 +74,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateZero();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -122,7 +122,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateFromValue(1.0f);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -134,7 +134,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateFromRowMajorFloat16(s_mat4x4testArray);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -146,7 +146,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateFromColumnMajorFloat16(s_mat4x4testArray);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -158,7 +158,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateProjection(s_mat4x4testArray[0], s_mat4x4testArray[1], s_mat4x4testArray[2], s_mat4x4testArray[3]);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -170,7 +170,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = AZ::Matrix4x4::CreateProjectionFov(s_mat4x4testArray[0], s_mat4x4testArray[1], s_mat4x4testArray[2], s_mat4x4testArray[3]);
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -550,7 +550,7 @@ namespace Benchmark
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Matrix4x4 result = mat.GetInverseTransform();
|
||||
benchmark::DoNotOptimize(result);
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion result = AZ::Quaternion::CreateIdentity();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -102,7 +102,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion result = AZ::Quaternion::CreateZero();
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -153,7 +153,7 @@ namespace Benchmark
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion result = AZ::Quaternion::CreateShortestArc(vec1, vec2); //result should transform vec1 into vec2
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -168,7 +168,7 @@ namespace Benchmark
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion result = AZ::Quaternion::CreateShortestArc(vec1, vec2); //result should transform vec1 into vec2
|
||||
benchmark::DoNotOptimize(result);
|
||||
@@ -308,7 +308,7 @@ namespace Benchmark
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion quat;
|
||||
quat.Set(vec, 8.0f);
|
||||
@@ -322,7 +322,7 @@ namespace Benchmark
|
||||
const float quatArray[4] = { 5.0f, 6.0f, 7.0f, 8.0f };
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& quatData : m_quatDataArray)
|
||||
for ([[maybe_unused]] auto& quatData : m_quatDataArray)
|
||||
{
|
||||
AZ::Quaternion quat;
|
||||
quat.Set(quatArray);
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Benchmark
|
||||
{
|
||||
for (auto _ : state)
|
||||
{
|
||||
for (auto& testData : m_testDataArray)
|
||||
for ([[maybe_unused]] auto& testData : m_testDataArray)
|
||||
{
|
||||
AZ::Transform result = AZ::Transform::CreateIdentity();
|
||||
benchmark::DoNotOptimize(result);
|
||||
|
||||
-1
@@ -755,7 +755,6 @@ namespace AZ::IO
|
||||
path.InitFromAbsolutePath(m_dummyFilepath + "/Broken/Path.txt");
|
||||
|
||||
request->CreateRead(nullptr, buffer, readSize, path, 0, readSize);
|
||||
bool resultSet = false;
|
||||
EXPECT_CALL(*mock, QueueRequest(request)).
|
||||
WillOnce([this](AZ::IO::FileRequest* request)
|
||||
{
|
||||
|
||||
@@ -1230,6 +1230,8 @@ namespace UnitTest
|
||||
ComponentApplication* GetApplication() override { return nullptr; }
|
||||
void RegisterComponentDescriptor(const ComponentDescriptor*) override { }
|
||||
void UnregisterComponentDescriptor(const ComponentDescriptor*) override { }
|
||||
void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { }
|
||||
void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { }
|
||||
bool AddEntity(Entity*) override { return false; }
|
||||
bool RemoveEntity(Entity*) override { return false; }
|
||||
bool DeleteEntity(const EntityId&) override { return false; }
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace SettingsRegistryScriptUtilsTests
|
||||
|
||||
TEST_F(SettingsRegistryBehaviorContextFixture, GlobalSettingsRegistry_CanBeQueried_Succeeds)
|
||||
{
|
||||
constexpr const char* IsValidMethodName = "IsValid";
|
||||
constexpr const char* GlobalSettingsRegistryPropertyName = "g_SettingsRegistry";
|
||||
auto propIt = m_behaviorContext->m_properties.find(GlobalSettingsRegistryPropertyName);
|
||||
ASSERT_NE(m_behaviorContext->m_properties.end(), propIt);
|
||||
|
||||
@@ -1188,8 +1188,8 @@ namespace AZ::IO
|
||||
if (az_archive_verbosity)
|
||||
{
|
||||
char fileNameBuffer[AZ_MAX_PATH_LEN];
|
||||
const char* fileName = AZ::IO::FileIOBase::GetDirectInstance()->GetFilename(fileHandle, fileNameBuffer, AZ_ARRAY_SIZE(fileNameBuffer))
|
||||
? fileNameBuffer : "unknown";
|
||||
[[maybe_unused]] const char* fileName = AZ::IO::FileIOBase::GetDirectInstance()->GetFilename(fileHandle, fileNameBuffer,
|
||||
AZ_ARRAY_SIZE(fileNameBuffer)) ? fileNameBuffer : "unknown";
|
||||
AZ_TracePrintf("Archive", R"(Perf Warning: First call to read file "%s" made from multiple threads concurrently)" "\n",
|
||||
fileName);
|
||||
}
|
||||
@@ -1914,7 +1914,6 @@ namespace AZ::IO
|
||||
AZ::IO::StackString pathStr{ szPathIn };
|
||||
// Determine if there is a period ('.') after the last slash to determine if the path contains a file.
|
||||
// This used to be a strchr on the whole path which could contain a period in a path, such as network domain paths (domain.user).
|
||||
bool bPathContainsFile = false;
|
||||
size_t findDotFromPos = pathStr.rfind(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
if (findDotFromPos == AZ::IO::StackString::npos)
|
||||
{
|
||||
@@ -2046,7 +2045,6 @@ namespace AZ::IO
|
||||
|
||||
uint8_t pMem[dwChunkSize];
|
||||
|
||||
uint32_t dwSize = 0;
|
||||
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
if (!fileIO)
|
||||
@@ -2453,11 +2451,13 @@ namespace AZ::IO
|
||||
ArchiveLocationPriority Archive::GetPakPriority() const
|
||||
{
|
||||
int pakPriority = aznumeric_cast<int>(ArchiveVars{}.nPriority);
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
if (auto console = AZ::Interface<AZ::IConsole>::Get(); console != nullptr)
|
||||
{
|
||||
AZ::GetValueResult getCvarResult = console->GetCvarValue("sys_PakPriority", pakPriority);
|
||||
AZ_Error("Archive", getCvarResult == AZ::GetValueResult::Success, "Lookup of 'sys_PakPriority console variable failed with error %s", AZ::GetEnumString(getCvarResult));
|
||||
}
|
||||
#endif
|
||||
return static_cast<ArchiveLocationPriority>(pakPriority);
|
||||
}
|
||||
|
||||
@@ -2580,10 +2580,6 @@ namespace AZ::IO
|
||||
return static_cast<EStreamSourceMediaType>(0);
|
||||
}
|
||||
|
||||
ZipDir::CachePtr pZip;
|
||||
uint32_t archFlags;
|
||||
ZipDir::FileEntry* pFileEntry = FindPakFileEntry(szFullPath->Native(), archFlags, &pZip, false);
|
||||
|
||||
enum StreamMediaType : int32_t
|
||||
{
|
||||
TypeUnknown = 0,
|
||||
|
||||
@@ -831,7 +831,7 @@ namespace AZ::IO::ZipDir
|
||||
//arrFiles.SortByFileOffset();
|
||||
size_t nSizeCDR = arrFiles.GetStats().nSizeCDR;
|
||||
void* pCDR = m_allocator->Allocate(nSizeCDR, alignof(uint8_t), 0, "Cache::WriteCDR");
|
||||
size_t nSizeCDRSerialized = arrFiles.MakeZipCDR(m_lCDROffset, pCDR);
|
||||
[[maybe_unused]] size_t nSizeCDRSerialized = arrFiles.MakeZipCDR(m_lCDROffset, pCDR);
|
||||
AZ_Assert(nSizeCDRSerialized == nSizeCDR, "Serialized CDR size %zu does not match size in memory %zu", nSizeCDRSerialized, nSizeCDR);
|
||||
if (m_encryptedHeaders == ZipFile::HEADERS_ENCRYPTED_TEA)
|
||||
{
|
||||
|
||||
@@ -343,7 +343,6 @@ namespace AZ::IO::ZipDir
|
||||
{
|
||||
AZ::IO::HandleType realFileHandle = m_fileHandle;
|
||||
size_t nFileSize = ~0;
|
||||
int64_t offset = 0;
|
||||
|
||||
AZ::u64 fileSize = 0;
|
||||
if (!m_fileIOBase->Size(realFileHandle, fileSize))
|
||||
|
||||
@@ -1014,7 +1014,6 @@ namespace AzFramework
|
||||
behaviorContext->Constant("EditorTransformComponentTypeId", BehaviorConstant(AZ::EditorTransformComponentTypeId));
|
||||
|
||||
behaviorContext->Class<AZ::TransformConfig>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::ConstructorOverride, &AZ::TransformConfigConstructor)
|
||||
->Enum<(int)AZ::TransformConfig::ParentActivationTransformMode::MaintainOriginalRelativeTransform>("MaintainOriginalRelativeTransform")
|
||||
->Enum<(int)AZ::TransformConfig::ParentActivationTransformMode::MaintainCurrentWorldTransform>("MaintainCurrentWorldTransform")
|
||||
|
||||
@@ -167,8 +167,6 @@ namespace AzFramework
|
||||
|
||||
for (auto && bound : m_bounds)
|
||||
{
|
||||
bool satisfies = false;
|
||||
|
||||
if (bound.m_comparison == Comp::TwiddleWakka)
|
||||
{
|
||||
// Lower bound
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace AzFramework
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<BehaviorComponentId>("ComponentId")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Constructor()
|
||||
->Method("IsValid", &BehaviorComponentId::IsValid)
|
||||
@@ -136,7 +135,6 @@ namespace AzFramework
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<BehaviorEntity>("Entity")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Attribute(AZ::Script::Attributes::ConstructorOverride, &Internal::BehaviorEntityScriptConstructor)
|
||||
->Constructor()
|
||||
|
||||
@@ -643,8 +643,6 @@ namespace AZ
|
||||
return ResultCode::Error;
|
||||
}
|
||||
|
||||
bool bSourceExcluded = false;
|
||||
bool bDestinationExcluded = false;
|
||||
|
||||
//else both are remote so just issue the remote copy command
|
||||
AzFramework::AssetSystem::FileCopyRequest request(sourceFilePath, destinationFilePath);
|
||||
@@ -697,8 +695,6 @@ namespace AZ
|
||||
}
|
||||
|
||||
//we are going to access shared memory so lock and copy the results into our memory
|
||||
bool bSourceExcluded = false;
|
||||
bool bDestinationExcluded = false;
|
||||
|
||||
//if the source and destination are the same, shortcut
|
||||
if (!strcmp(sourceFilePath, destinationFilePath))
|
||||
|
||||
@@ -130,13 +130,11 @@ namespace AzFramework
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<InputSystemNotificationBus>("InputSystemNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Input")
|
||||
->Handler<InputSystemNotificationBusBehaviorHandler>()
|
||||
;
|
||||
|
||||
behaviorContext->EBus<InputSystemRequestBus>("InputSystemRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Input")
|
||||
->Event("RecreateEnabledInputDevices", &InputSystemRequestBus::Events::RecreateEnabledInputDevices)
|
||||
;
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace AzFramework
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->EBus<NetBindingHandlerBus>("NetBindingHandlerBus")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::Preview)
|
||||
->Event("IsEntityBoundToNetwork", &NetBindingHandlerBus::Events::IsEntityBoundToNetwork)
|
||||
->Event("IsEntityAuthoritative", &NetBindingHandlerBus::Events::IsEntityAuthoritative)
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Physics
|
||||
behaviorContext->EBus<Physics::CollisionFilteringRequestBus>("CollisionFilteringBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "physics")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::Preview)
|
||||
->Attribute(AZ::Script::Attributes::Category, "PhysX")
|
||||
->Event("SetCollisionLayer", &Physics::CollisionFilteringRequestBus::Events::SetCollisionLayer)
|
||||
->Event("GetCollisionLayerName", &Physics::CollisionFilteringRequestBus::Events::GetCollisionLayerName)
|
||||
|
||||
@@ -93,9 +93,9 @@ namespace AzFramework
|
||||
"DataSet31","DataSet32"
|
||||
};
|
||||
|
||||
if (s_chunkIndex > AZ_ARRAY_SIZE(s_nameArray) && AZ_ARRAY_SIZE(s_nameArray) >= 0)
|
||||
if ((s_chunkIndex >= AZ_ARRAY_SIZE(s_nameArray)) && (AZ_ARRAY_SIZE(s_nameArray) >= 0))
|
||||
{
|
||||
s_chunkIndex = s_chunkIndex%AZ_ARRAY_SIZE(s_nameArray);
|
||||
s_chunkIndex = s_chunkIndex % AZ_ARRAY_SIZE(s_nameArray);
|
||||
}
|
||||
|
||||
return s_nameArray[s_chunkIndex++];
|
||||
|
||||
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "CameraInput.h"
|
||||
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Math/Plane.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void CameraSystem::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& cursor_motion = AZStd::get_if<CursorMotionEvent>(&event))
|
||||
{
|
||||
m_currentCursorPosition = cursor_motion->m_position;
|
||||
}
|
||||
else if (const auto& scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
m_scrollDelta = scroll->m_delta;
|
||||
}
|
||||
|
||||
m_cameras.HandleEvents(event);
|
||||
}
|
||||
|
||||
Camera CameraSystem::StepCamera(const Camera& targetCamera, float deltaTime)
|
||||
{
|
||||
const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value()
|
||||
? m_currentCursorPosition.value() - m_lastCursorPosition.value()
|
||||
: ScreenVector(0, 0);
|
||||
|
||||
if (m_currentCursorPosition.has_value())
|
||||
{
|
||||
m_lastCursorPosition = m_currentCursorPosition;
|
||||
}
|
||||
|
||||
const auto nextCamera = m_cameras.StepCamera(targetCamera, cursorDelta, m_scrollDelta, deltaTime);
|
||||
|
||||
m_scrollDelta = 0.0f;
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> camera_input)
|
||||
{
|
||||
m_idleCameraInputs.push_back(AZStd::move(camera_input));
|
||||
}
|
||||
|
||||
void Cameras::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
for (auto& camera_input : m_activeCameraInputs)
|
||||
{
|
||||
camera_input->HandleEvents(event);
|
||||
}
|
||||
|
||||
for (auto& camera_input : m_idleCameraInputs)
|
||||
{
|
||||
camera_input->HandleEvents(event);
|
||||
}
|
||||
}
|
||||
|
||||
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, const float deltaTime)
|
||||
{
|
||||
for (int i = 0; i < m_idleCameraInputs.size();)
|
||||
{
|
||||
auto& camera_input = m_idleCameraInputs[i];
|
||||
const bool can_begin = camera_input->Beginning() &&
|
||||
std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(),
|
||||
[](const auto& input) { return !input->Exclusive(); }) &&
|
||||
(!camera_input->Exclusive() || (camera_input->Exclusive() && m_activeCameraInputs.empty()));
|
||||
if (can_begin)
|
||||
{
|
||||
m_activeCameraInputs.push_back(camera_input);
|
||||
using AZStd::swap;
|
||||
swap(m_idleCameraInputs[i], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
|
||||
m_idleCameraInputs.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// accumulate
|
||||
Camera nextCamera = targetCamera;
|
||||
for (auto& camera_input : m_activeCameraInputs)
|
||||
{
|
||||
nextCamera = camera_input->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_activeCameraInputs.size();)
|
||||
{
|
||||
auto& camera_input = m_activeCameraInputs[i];
|
||||
if (camera_input->Ending())
|
||||
{
|
||||
camera_input->ClearActivation();
|
||||
m_idleCameraInputs.push_back(camera_input);
|
||||
using AZStd::swap;
|
||||
swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
|
||||
m_activeCameraInputs.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
camera_input->ContinueActivation();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void Cameras::Reset()
|
||||
{
|
||||
for (int i = 0; i < m_activeCameraInputs.size();)
|
||||
{
|
||||
m_activeCameraInputs[i]->Reset();
|
||||
m_idleCameraInputs.push_back(m_activeCameraInputs[i]);
|
||||
m_activeCameraInputs[i] = m_activeCameraInputs[m_activeCameraInputs.size() - 1];
|
||||
m_activeCameraInputs.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void RotateCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == m_channelId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera RotateCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
nextCamera.m_pitch += float(cursorDelta.m_y) * m_props.m_rotateSpeed;
|
||||
nextCamera.m_yaw += float(cursorDelta.m_x) * m_props.m_rotateSpeed;
|
||||
|
||||
auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoOverPi, AZ::Constants::TwoOverPi); };
|
||||
|
||||
nextCamera.m_yaw = clamp_rotation(nextCamera.m_yaw);
|
||||
// clamp pitch to be +-90 degrees
|
||||
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::Pi * 0.5f, AZ::Constants::Pi * 0.5f);
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void PanCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceMouse::Button::Middle)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera PanCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto pan_axes = m_panAxesFn(nextCamera);
|
||||
|
||||
const auto delta_pan_x = float(cursorDelta.m_x) * pan_axes.m_horizontalAxis * m_props.m_panSpeed;
|
||||
const auto delta_pan_y = float(cursorDelta.m_y) * pan_axes.m_verticalAxis * m_props.m_panSpeed;
|
||||
|
||||
const auto inv = [](const bool invert) {
|
||||
constexpr float Dir[] = {1.0f, -1.0f};
|
||||
return Dir[static_cast<int>(invert)];
|
||||
};
|
||||
|
||||
nextCamera.m_lookAt += delta_pan_x * inv(m_props.m_panInvertX);
|
||||
nextCamera.m_lookAt += delta_pan_y * -inv(m_props.m_panInvertY);
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
TranslateCameraInput::TranslationType TranslateCameraInput::translationFromKey(InputChannelId channelId)
|
||||
{
|
||||
// note: remove hard-coded InputDevice keys
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericW)
|
||||
{
|
||||
return TranslationType::Forward;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericS)
|
||||
{
|
||||
return TranslationType::Backward;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericA)
|
||||
{
|
||||
return TranslationType::Left;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericD)
|
||||
{
|
||||
return TranslationType::Right;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericQ)
|
||||
{
|
||||
return TranslationType::Down;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericE)
|
||||
{
|
||||
return TranslationType::Up;
|
||||
}
|
||||
|
||||
return TranslationType::Nil;
|
||||
}
|
||||
|
||||
void TranslateCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Updated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_translation |= translationFromKey(input->m_channelId);
|
||||
if (m_translation != TranslationType::Nil)
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
{
|
||||
m_boost = true;
|
||||
}
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
m_translation ^= translationFromKey(input->m_channelId);
|
||||
if (m_translation == TranslationType::Nil)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
{
|
||||
m_boost = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera TranslateCameraInput::StepCamera(
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
|
||||
const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto translation_basis = m_translationAxesFn(nextCamera);
|
||||
const auto axisX = translation_basis.GetBasisX();
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
const auto axisZ = translation_basis.GetBasisZ();
|
||||
|
||||
const float speed = [boost = m_boost, props = m_props]() {
|
||||
return props.m_translateSpeed * (boost ? props.m_boostMultiplier : 1.0f);
|
||||
}();
|
||||
|
||||
if ((m_translation & TranslationType::Forward) == TranslationType::Forward)
|
||||
{
|
||||
nextCamera.m_lookAt += axisY * speed * deltaTime;
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Backward) == TranslationType::Backward)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisY * speed * deltaTime;
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Left) == TranslationType::Left)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisX * speed * deltaTime;
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Right) == TranslationType::Right)
|
||||
{
|
||||
nextCamera.m_lookAt += axisX * speed * deltaTime;
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Up) == TranslationType::Up)
|
||||
{
|
||||
nextCamera.m_lookAt += axisZ * speed * deltaTime;
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Down) == TranslationType::Down)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisZ * speed * deltaTime;
|
||||
}
|
||||
|
||||
if (Ending())
|
||||
{
|
||||
m_translation = TranslationType::Nil;
|
||||
}
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void TranslateCameraInput::ResetImpl()
|
||||
{
|
||||
m_translation = TranslationType::Nil;
|
||||
m_boost = false;
|
||||
}
|
||||
|
||||
void OrbitCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto* input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierAltL)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Updated)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
if (Active())
|
||||
{
|
||||
m_orbitCameras.HandleEvents(event);
|
||||
}
|
||||
}
|
||||
|
||||
Camera OrbitCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
if (Beginning())
|
||||
{
|
||||
float hit_distance = 0.0f;
|
||||
if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateZero())
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY() * m_props.m_maxOrbitDistance, hit_distance))
|
||||
{
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -m_props.m_defaultOrbitDistance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * m_props.m_defaultOrbitDistance;
|
||||
}
|
||||
}
|
||||
|
||||
if (Active())
|
||||
{
|
||||
// todo: need to return nested cameras to idle state when ending
|
||||
nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
}
|
||||
|
||||
if (Ending())
|
||||
{
|
||||
m_orbitCameras.Reset();
|
||||
|
||||
nextCamera.m_lookAt = nextCamera.Translation();
|
||||
nextCamera.m_lookDist = 0.0f;
|
||||
}
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void OrbitDollyScrollCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
}
|
||||
|
||||
Camera OrbitDollyScrollCameraInput::StepCamera(
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
|
||||
[[maybe_unused]] float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_props.m_dollySpeed, 0.0f);
|
||||
EndActivation();
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void OrbitDollyCursorMoveCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceMouse::Button::Right)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Camera OrbitDollyCursorMoveCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_props.m_dollySpeed, 0.0f);
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void ScrollTranslationCameraInput::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
{
|
||||
BeginActivation();
|
||||
}
|
||||
}
|
||||
|
||||
Camera ScrollTranslationCameraInput::StepCamera(
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto translation_basis = LookTranslation(nextCamera);
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * m_props.m_translateSpeed;
|
||||
|
||||
EndActivation();
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, const float deltaTime)
|
||||
{
|
||||
const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
|
||||
|
||||
// keep yaw in 0 - 360 range
|
||||
float target_yaw = clamp_rotation(targetCamera.m_yaw);
|
||||
const float current_yaw = clamp_rotation(currentCamera.m_yaw);
|
||||
|
||||
auto sign = [](const float value) { return static_cast<float>((0.0f < value) - (value < 0.0f)); };
|
||||
|
||||
// ensure smooth transition when moving across 0 - 360 boundary
|
||||
const float yaw_delta = target_yaw - current_yaw;
|
||||
if (std::abs(yaw_delta) >= AZ::Constants::Pi)
|
||||
{
|
||||
target_yaw -= AZ::Constants::TwoPi * sign(yaw_delta);
|
||||
}
|
||||
|
||||
Camera camera;
|
||||
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
|
||||
// article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
|
||||
const float lookRate = std::exp2(props.m_lookSmoothness);
|
||||
const float lookT = std::exp2(-lookRate * deltaTime);
|
||||
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT);
|
||||
camera.m_yaw = AZ::Lerp(target_yaw, current_yaw, lookT);
|
||||
const float moveRate = std::exp2(props.m_moveSmoothness);
|
||||
const float moveT = std::exp2(-moveRate * deltaTime);
|
||||
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
|
||||
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT);
|
||||
return camera;
|
||||
}
|
||||
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize)
|
||||
{
|
||||
const auto& inputChannelId = inputChannel.GetInputChannelId();
|
||||
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
|
||||
|
||||
if (inputChannelId == InputDeviceMouse::SystemCursorPosition)
|
||||
{
|
||||
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
|
||||
InputSystemCursorRequestBus::EventResult(
|
||||
systemCursorPositionNormalized, inputDeviceId, &InputSystemCursorRequestBus::Events::GetSystemCursorPositionNormalized);
|
||||
|
||||
return CursorMotionEvent{ScreenPoint(
|
||||
systemCursorPositionNormalized.GetX() * windowSize.m_width, systemCursorPositionNormalized.GetY() * windowSize.m_height)};
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
return ScrollEvent{inputChannel.GetValue()};
|
||||
}
|
||||
else if (InputDeviceMouse::IsMouseDevice(inputDeviceId) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
|
||||
{
|
||||
return DiscreteInputEvent{inputChannelId, inputChannel.GetState()};
|
||||
}
|
||||
|
||||
return AZStd::monostate{};
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Math/Matrix3x3.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzFramework/Input/Channels/InputChannel.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct WindowSize;
|
||||
|
||||
struct Camera
|
||||
{
|
||||
AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero,
|
||||
//!< or position of m_lookAt when m_lookDist is greater
|
||||
//!< than zero.
|
||||
float m_yaw{0.0};
|
||||
float m_pitch{0.0};
|
||||
float m_lookDist{0.0}; //!< Zero gives first person free look, otherwise orbit about m_lookAt
|
||||
|
||||
//! View camera transform (v in MVP).
|
||||
AZ::Transform View() const;
|
||||
//! World camera transform.
|
||||
AZ::Transform Transform() const;
|
||||
//! World rotation.
|
||||
AZ::Matrix3x3 Rotation() const;
|
||||
//! World translation.
|
||||
AZ::Vector3 Translation() const;
|
||||
};
|
||||
|
||||
inline AZ::Transform Camera::View() const
|
||||
{
|
||||
return Transform().GetInverse();
|
||||
}
|
||||
|
||||
inline AZ::Transform Camera::Transform() const
|
||||
{
|
||||
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationX(m_pitch) *
|
||||
AZ::Transform::CreateRotationZ(m_yaw) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisZ(m_lookDist));
|
||||
}
|
||||
|
||||
inline AZ::Matrix3x3 Camera::Rotation() const
|
||||
{
|
||||
return AZ::Matrix3x3::CreateFromQuaternion(Transform().GetRotation());
|
||||
}
|
||||
|
||||
inline AZ::Vector3 Camera::Translation() const
|
||||
{
|
||||
return Transform().GetTranslation();
|
||||
}
|
||||
|
||||
struct CursorMotionEvent
|
||||
{
|
||||
ScreenPoint m_position;
|
||||
};
|
||||
|
||||
struct ScrollEvent
|
||||
{
|
||||
float m_delta;
|
||||
};
|
||||
|
||||
struct DiscreteInputEvent
|
||||
{
|
||||
InputChannelId m_channelId; //!< Channel type. (e.g. Keyboard key, mouse button or other device input).
|
||||
InputChannel::State m_state; //!< Channel state. (e.g. Begin/update/end event).
|
||||
};
|
||||
|
||||
using InputEvent = AZStd::variant<AZStd::monostate, CursorMotionEvent, ScrollEvent, DiscreteInputEvent>;
|
||||
|
||||
class CameraInput
|
||||
{
|
||||
public:
|
||||
enum class Activation
|
||||
{
|
||||
Idle,
|
||||
Begin,
|
||||
Active,
|
||||
End
|
||||
};
|
||||
|
||||
virtual ~CameraInput() = default;
|
||||
|
||||
bool Beginning() const
|
||||
{
|
||||
return m_activation == Activation::Begin;
|
||||
}
|
||||
|
||||
bool Ending() const
|
||||
{
|
||||
return m_activation == Activation::End;
|
||||
}
|
||||
|
||||
bool Idle() const
|
||||
{
|
||||
return m_activation == Activation::Idle;
|
||||
}
|
||||
|
||||
bool Active() const
|
||||
{
|
||||
return m_activation == Activation::Active;
|
||||
}
|
||||
|
||||
void BeginActivation()
|
||||
{
|
||||
m_activation = Activation::Begin;
|
||||
}
|
||||
|
||||
void EndActivation()
|
||||
{
|
||||
m_activation = Activation::End;
|
||||
}
|
||||
|
||||
void ContinueActivation()
|
||||
{
|
||||
m_activation = Activation::Active;
|
||||
}
|
||||
|
||||
void ClearActivation()
|
||||
{
|
||||
m_activation = Activation::Idle;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ClearActivation();
|
||||
ResetImpl();
|
||||
}
|
||||
|
||||
virtual void HandleEvents(const InputEvent& event) = 0;
|
||||
virtual Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) = 0;
|
||||
|
||||
virtual bool Exclusive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void ResetImpl()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
Activation m_activation = Activation::Idle;
|
||||
};
|
||||
|
||||
struct SmoothProps
|
||||
{
|
||||
float m_lookSmoothness = 5.0f;
|
||||
float m_moveSmoothness = 5.0f;
|
||||
};
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, float deltaTime);
|
||||
|
||||
class Cameras
|
||||
{
|
||||
public:
|
||||
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
|
||||
void HandleEvents(const InputEvent& event);
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime);
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs;
|
||||
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_idleCameraInputs;
|
||||
};
|
||||
|
||||
class CameraSystem
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event);
|
||||
Camera StepCamera(const Camera& targetCamera, float deltaTime);
|
||||
|
||||
Cameras m_cameras;
|
||||
|
||||
private:
|
||||
float m_scrollDelta = 0.0f;
|
||||
AZStd::optional<ScreenPoint> m_lastCursorPosition;
|
||||
AZStd::optional<ScreenPoint> m_currentCursorPosition;
|
||||
};
|
||||
|
||||
class RotateCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit RotateCameraInput(const InputChannelId channelId)
|
||||
: m_channelId(channelId)
|
||||
{
|
||||
}
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
InputChannelId m_channelId;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_rotateSpeed = 0.005f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
struct PanAxes
|
||||
{
|
||||
AZ::Vector3 m_horizontalAxis;
|
||||
AZ::Vector3 m_verticalAxis;
|
||||
};
|
||||
|
||||
using PanAxesFn = AZStd::function<PanAxes(const Camera& camera)>;
|
||||
|
||||
inline PanAxes LookPan(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
return {orientation.GetBasisX(), orientation.GetBasisZ()};
|
||||
}
|
||||
|
||||
inline PanAxes OrbitPan(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
|
||||
const auto basisX = orientation.GetBasisX();
|
||||
const auto basisY = [&orientation] {
|
||||
const auto forward = orientation.GetBasisY();
|
||||
return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized();
|
||||
}();
|
||||
|
||||
return {basisX, basisY};
|
||||
}
|
||||
|
||||
class PanCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit PanCameraInput(PanAxesFn panAxesFn)
|
||||
: m_panAxesFn(AZStd::move(panAxesFn))
|
||||
{
|
||||
}
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_panSpeed = 0.01f;
|
||||
bool m_panInvertX = true;
|
||||
bool m_panInvertY = true;
|
||||
} m_props;
|
||||
|
||||
private:
|
||||
PanAxesFn m_panAxesFn;
|
||||
};
|
||||
|
||||
using TranslationAxesFn = AZStd::function<AZ::Matrix3x3(const Camera& camera)>;
|
||||
|
||||
inline AZ::Matrix3x3 LookTranslation(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
|
||||
const auto basisX = orientation.GetBasisX();
|
||||
const auto basisY = orientation.GetBasisY();
|
||||
const auto basisZ = AZ::Vector3::CreateAxisZ();
|
||||
|
||||
return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ);
|
||||
}
|
||||
|
||||
inline AZ::Matrix3x3 OrbitTranslation(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
|
||||
const auto basisX = orientation.GetBasisX();
|
||||
const auto basisY = [&orientation] {
|
||||
const auto forward = orientation.GetBasisY();
|
||||
return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized();
|
||||
}();
|
||||
const auto basisZ = AZ::Vector3::CreateAxisZ();
|
||||
|
||||
return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ);
|
||||
}
|
||||
|
||||
class TranslateCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit TranslateCameraInput(TranslationAxesFn translationAxesFn)
|
||||
: m_translationAxesFn(AZStd::move(translationAxesFn))
|
||||
{
|
||||
}
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
void ResetImpl() override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_translateSpeed = 10.0f;
|
||||
float m_boostMultiplier = 3.0f;
|
||||
} m_props;
|
||||
|
||||
private:
|
||||
enum class TranslationType
|
||||
{
|
||||
// clang-format off
|
||||
Nil = 0,
|
||||
Forward = 1 << 0,
|
||||
Backward = 1 << 1,
|
||||
Left = 1 << 2,
|
||||
Right = 1 << 3,
|
||||
Up = 1 << 4,
|
||||
Down = 1 << 5,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
friend TranslationType operator|(const TranslationType lhs, const TranslationType rhs)
|
||||
{
|
||||
return static_cast<TranslationType>(
|
||||
static_cast<std::underlying_type_t<TranslationType>>(lhs) | static_cast<std::underlying_type_t<TranslationType>>(rhs));
|
||||
}
|
||||
|
||||
friend TranslationType& operator|=(TranslationType& lhs, const TranslationType rhs)
|
||||
{
|
||||
lhs = lhs | rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend TranslationType operator^(const TranslationType lhs, const TranslationType rhs)
|
||||
{
|
||||
return static_cast<TranslationType>(
|
||||
static_cast<std::underlying_type_t<TranslationType>>(lhs) ^ static_cast<std::underlying_type_t<TranslationType>>(rhs));
|
||||
}
|
||||
|
||||
friend TranslationType& operator^=(TranslationType& lhs, const TranslationType rhs)
|
||||
{
|
||||
lhs = lhs ^ rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend TranslationType operator&(const TranslationType lhs, const TranslationType rhs)
|
||||
{
|
||||
return static_cast<TranslationType>(
|
||||
static_cast<std::underlying_type_t<TranslationType>>(lhs) & static_cast<std::underlying_type_t<TranslationType>>(rhs));
|
||||
}
|
||||
|
||||
friend TranslationType& operator&=(TranslationType& lhs, const TranslationType rhs)
|
||||
{
|
||||
lhs = lhs & rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
static TranslationType translationFromKey(InputChannelId channelId);
|
||||
|
||||
TranslationType m_translation = TranslationType::Nil;
|
||||
TranslationAxesFn m_translationAxesFn;
|
||||
bool m_boost = false;
|
||||
};
|
||||
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_dollySpeed = 0.2f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
class OrbitDollyCursorMoveCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_dollySpeed = 0.1f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
class ScrollTranslationCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_translateSpeed = 0.2f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
class OrbitCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
bool Exclusive() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Cameras m_orbitCameras;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_defaultOrbitDistance = 15.0f;
|
||||
float m_maxOrbitDistance = 100.0f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize);
|
||||
} // namespace AzFramework
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
@@ -60,17 +61,18 @@ namespace AzFramework
|
||||
{
|
||||
//! The viewport ID this event was dispatched to.
|
||||
ViewportId m_viewportId;
|
||||
//! The native window handle for the application.
|
||||
NativeWindowHandle m_windowHandle;
|
||||
//! The input channel data for this event.
|
||||
const AzFramework::InputChannel& m_inputChannel;
|
||||
//! The priority this event was dispatched at.
|
||||
ViewportControllerPriority m_priority;
|
||||
|
||||
ViewportControllerInputEvent(
|
||||
ViewportId viewportId,
|
||||
const AzFramework::InputChannel& inputChannel,
|
||||
ViewportControllerPriority priority = ViewportControllerPriority::DispatchToAllPriorities
|
||||
)
|
||||
ViewportId viewportId, NativeWindowHandle windowHandle, const AzFramework::InputChannel& inputChannel,
|
||||
ViewportControllerPriority priority = ViewportControllerPriority::DispatchToAllPriorities)
|
||||
: m_viewportId(viewportId)
|
||||
, m_windowHandle(windowHandle)
|
||||
, m_inputChannel(inputChannel)
|
||||
, m_priority(priority)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace AzFramework
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<BoundsRequestBus>("BoundsRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::Preview)
|
||||
->Event("GetWorldBounds", &BoundsRequestBus::Events::GetWorldBounds)
|
||||
->Event("GetLocalBounds", &BoundsRequestBus::Events::GetLocalBounds);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace AzFramework
|
||||
{
|
||||
TYPE_None = 0,
|
||||
TYPE_Entity = 1 << 0, // All entities
|
||||
TYPE_NetEntity = 1 << 1, // NetBound entities
|
||||
TYPE_RPI_Cullable = 1 << 2 // Cullable by the render system
|
||||
};
|
||||
|
||||
@@ -113,6 +112,4 @@ namespace AzFramework
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
};
|
||||
using IVisibilitySystemRequestBus = AZ::EBus<IVisibilitySystem, IVisibilitySystemRequests>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ set(FILES
|
||||
Viewport/ScreenGeometry.cpp
|
||||
Viewport/CameraState.h
|
||||
Viewport/CameraState.cpp
|
||||
Viewport/CameraInput.h
|
||||
Viewport/CameraInput.cpp
|
||||
Viewport/DisplayContextRequestBus.h
|
||||
Entity/BehaviorEntity.cpp
|
||||
Entity/BehaviorEntity.h
|
||||
@@ -426,4 +428,7 @@ set(FILES
|
||||
Visibility/EntityVisibilityBoundsUnionSystem.cpp
|
||||
Visibility/EntityVisibilityQuery.h
|
||||
Visibility/EntityVisibilityQuery.cpp
|
||||
Dependency/Dependency.h
|
||||
Dependency/Dependency.inl
|
||||
Dependency/Version.h
|
||||
)
|
||||
|
||||
+1
@@ -290,6 +290,7 @@ namespace AzFramework
|
||||
UpdateSystemCursorVisibility();
|
||||
const bool shouldBeDisabled = (m_systemCursorState == SystemCursorState::ConstrainedAndHidden) ||
|
||||
(m_systemCursorState == SystemCursorState::ConstrainedAndVisible);
|
||||
|
||||
if (!shouldBeDisabled)
|
||||
{
|
||||
DestroyDisabledSystemCursorEventTap();
|
||||
|
||||
@@ -103,6 +103,14 @@ namespace AzNetworking
|
||||
//! @return the connection identifier for this connection instance
|
||||
ConnectionId GetConnectionId() const;
|
||||
|
||||
//! Sets connection user data to the provided value.
|
||||
//! @param userData the user data value to bind to this connection
|
||||
void SetUserData(void* userData);
|
||||
|
||||
//! Retrieves the connection user data bound to this instance.
|
||||
//! @return the connection user data bound to this instance
|
||||
void* GetUserData() const;
|
||||
|
||||
//! Sets the remote address for this connection instance.
|
||||
//! @param address the remote address to use for this connection instance
|
||||
void SetRemoteAddress(const IpAddress& address);
|
||||
@@ -122,9 +130,10 @@ namespace AzNetworking
|
||||
private:
|
||||
|
||||
// The following data members are here in the interface for performance reasons
|
||||
ConnectionId m_connectionId;
|
||||
ConnectionId m_connectionId = InvalidConnectionId;
|
||||
IpAddress m_remoteAddress;
|
||||
ConnectionMetrics m_connectionMetrics;
|
||||
void* m_userData = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,16 @@ namespace AzNetworking
|
||||
return m_connectionId;
|
||||
}
|
||||
|
||||
inline void IConnection::SetUserData(void* userData)
|
||||
{
|
||||
m_userData = userData;
|
||||
}
|
||||
|
||||
inline void* IConnection::GetUserData() const
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
inline void IConnection::SetRemoteAddress(const IpAddress& address)
|
||||
{
|
||||
m_remoteAddress = address;
|
||||
|
||||
@@ -33,21 +33,21 @@ namespace AzNetworking
|
||||
//! Sets the specified bit to the provided value.
|
||||
//! @param index index of the bit to set
|
||||
//! @param value value to set the bit to
|
||||
virtual void SetBit(uint32_t index, bool value) override;
|
||||
void SetBit(uint32_t index, bool value) override;
|
||||
|
||||
//! Gets the current value of the specified bit.
|
||||
//! @param index index of the bit to retrieve the value of
|
||||
//! @return boolean true if the bit is set, false otherwise
|
||||
virtual bool GetBit(uint32_t index) const override;
|
||||
bool GetBit(uint32_t index) const override;
|
||||
|
||||
//! Gets the current value of the specified bit.
|
||||
//! @param index index of the bit to retrieve the value of
|
||||
//! @return boolean true if the bit is set, false otherwise
|
||||
virtual bool AnySet() const override;
|
||||
bool AnySet() const override;
|
||||
|
||||
//! Returns the number of bits that are represented in this fixed size bitset.
|
||||
//! @return the number of bits that are represented in this fixed size bitset
|
||||
virtual uint32_t GetValidBitCount() const override;
|
||||
uint32_t GetValidBitCount() const override;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4c103b1259ce2203c4af26f4e4f4fa9bf06af50614c949d7e59e0bdd688e7562
|
||||
size 1979
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c3082c3a282d8578b1ba9c9fe74857d7155ee918721d9bfed4ef3d00ee09211c
|
||||
size 1890
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b7f859801eca4bb6cac2566000a2bbae7a597c0d50caa00a83c4e15dc739f1d4
|
||||
size 1917
|
||||
@@ -383,6 +383,9 @@
|
||||
<file>img/UI20/toolbar/Y_axis.svg</file>
|
||||
<file>img/UI20/toolbar/Z_axis.svg</file>
|
||||
<file>img/UI20/toolbar/XY2_copy.svg</file>
|
||||
<file>img/triangle0.png</file>
|
||||
<file>img/triangle0_highlighted.png</file>
|
||||
<file>img/line.png</file>
|
||||
</qresource>
|
||||
<qresource>
|
||||
<file alias="Editor/Style/EditorStylesheetVariables_Dark.json">../../../../Sandbox/Editor/Style/EditorStylesheetVariables_Dark.json</file>
|
||||
|
||||
@@ -27,7 +27,7 @@ MenuPage::MenuPage(QWidget* parent)
|
||||
|
||||
const auto actionText = QStringLiteral("Option");
|
||||
menu->addAction(actionText);
|
||||
auto searchAction = menu->addAction(QIcon(QStringLiteral(":/stylesheet/img/search.svg")), QStringLiteral("Search"));
|
||||
menu->addAction(QIcon(QStringLiteral(":/stylesheet/img/search.svg")), QStringLiteral("Search"));
|
||||
menu->addSeparator();
|
||||
|
||||
auto shortcutAction = menu->addAction(actionText);
|
||||
@@ -96,4 +96,4 @@ MenuPage::~MenuPage()
|
||||
{
|
||||
}
|
||||
|
||||
#include <Gallery/moc_MenuPage.cpp>
|
||||
#include <Gallery/moc_MenuPage.cpp>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Oval 6</title>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Inspector-2" transform="translate(-1724.000000, -285.000000)" fill="#FFFFFF" fill-rule="nonzero">
|
||||
<g id="Group" transform="translate(1714.000000, 255.000000)">
|
||||
<path d="M17.75,30.25 C22.0302068,30.25 25.5,33.7197932 25.5,38 C25.5,42.2802068 22.0302068,45.75 17.75,45.75 C13.4697932,45.75 10,42.2802068 10,38 C10,33.7197932 13.4697932,30.25 17.75,30.25 Z M21.9230842,36.8875321 C21.590362,36.5777872 21.1499255,36.4637717 20.393435,36.8875321 L20.393435,36.8875321 L20.393435,39.1247335 C20.3078139,39.3862214 19.5880467,39.0740522 19.5880467,39.3471973 L19.5880467,39.3471973 L19.5880467,40.1832625 C19.5880467,40.5490163 20.373798,40.4179507 20.9265311,40.4179507 C21.2398827,40.5640832 21.1499255,41.1654284 21.1499255,41.3219178 C20.8009407,41.3219178 20.8107092,42.1358461 19.7108476,42.1358461 C19.4749079,42.1358461 19.2067566,42.3782747 18.9063936,42.8631318 C18.5774755,42.9572 18.3585318,42.9572 18.2495624,42.8631318 C17.9917698,42.6405913 18.0639002,42.5929236 18.0639002,42.1358461 C17.7490706,42.0583816 17.2421758,42.0157944 16.5432157,42.0080847 L16.5432157,42.0080847 L16.5432157,41.3219178 L16.5432157,41.3219178 L15.7192213,41.3219178 C15.4649524,41.467548 15.2659138,41.7388575 15.1221055,42.1358461 L15.1221055,42.1358461 L13.4562289,42.1358461 C13.4562289,42.8631318 14.2746545,42.6643305 14.2746545,43.4057505 C14.2746545,43.70763 15.5932808,43.3136142 15.7192213,44.0188584 C15.8451617,44.7241026 18.0966562,44.6297834 19.5880467,44.2327119 C22.4562289,43.4690805 23.8820008,41.1463376 24.2040243,39.5905304 C24.5260478,38.0347231 24.343851,37.5466972 23.6034998,37.5466972 L23.6034998,37.5466972 L22.6881842,37.5466972 C22.2173073,37.5466972 22.8191026,38.3115454 22.4884098,38.3115454 C22.157717,38.3115454 21.9230842,38.3612916 21.9230842,37.7457914 L21.9230842,37.7457914 Z M17.4663725,31.3904088 C15.1901696,31.3764381 13.5194447,31.7569095 11.3640944,36.6864363 C11.3640944,37.0394323 11.4375107,37.3715778 11.6947367,37.4223367 C11.9057364,37.4639736 12.6046349,37.4223367 12.8218274,37.4223367 C13.3401431,37.4223367 13.4562289,37.4223367 13.4562289,38.1786887 C13.4562289,38.5903116 14.2573076,38.7864722 14.2573076,39.3471973 C14.2573076,39.9079225 14.7600011,40.1509551 15.1221055,40.5685872 L15.8282319,40.5685872 L15.8282319,40.5685872 L15.8282319,39.0899479 L15.8282319,39.0899479 C15.8282319,38.9733116 16.5432157,38.9733116 16.9178106,39.0064924 C17.4032805,39.0064924 17.4032805,38.3483287 17.1722779,38.301168 C16.741164,38.2131535 15.8282319,38.301168 15.8282319,37.9037493 L15.8282319,36.3094851 L15.8282319,36.3094851 C15.8282319,35.6193344 16.5432157,36.2438976 16.5432157,35.553747 L16.5432157,33.4007819 L16.5432157,33.4007819 C16.5432157,32.7363875 16.8954156,32.83074 17.4663725,32.83074 C18.2495624,32.3799956 17.9300811,31.7569095 17.4663725,31.3904088 Z M18.9263619,34.4814505 C18.2495624,34.3404349 17.832423,34.3404349 17.2855835,34.4814505 C17.1345093,34.795806 17.1345093,34.9935976 17.2855835,35.1536992 C18.2495624,35.1450754 18.9263619,35.3316464 18.9263619,35.8792081 C19.0692871,36.0410209 19.4229255,36.0410209 19.7108476,35.8792081 C19.683443,35.3640449 19.683443,34.9051922 18.9263619,34.4814505 Z" id="Oval-6"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
@@ -7,6 +7,9 @@
|
||||
<file alias="prefab.svg">Entity/prefab.svg</file>
|
||||
<file alias="prefab_edit.svg">Entity/prefab_edit.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/Level">
|
||||
<file alias="level.svg">Level/level.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/Notifications">
|
||||
<file alias="checkmark.svg">Notifications/checkmark.svg</file>
|
||||
<file alias="download.svg">Notifications/download.svg</file>
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#define AZ_TRAIT_DISABLE_FAILED_AUDIO_SYSTEM_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_AUDIO_WWISE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_EMOTION_FX_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_GAMELIFT_CLIENT_SESSION_TEST true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_GRADIENT_SIGNAL_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_GRIDMATE_TESTS true
|
||||
#define AZ_TRAIT_DISABLE_FAILED_JOB_BASIC_TESTS true
|
||||
|
||||
@@ -255,10 +255,8 @@ namespace AzToolsFramework::AssetUtils
|
||||
return configFiles;
|
||||
}
|
||||
|
||||
bool UpdateFilePathToCorrectCase(const QString& root, QString& relativePathFromRoot)
|
||||
bool UpdateFilePathToCorrectCase(AZStd::string_view rootPath, AZStd::string& relPathFromRoot)
|
||||
{
|
||||
AZStd::string rootPath(root.toUtf8().data());
|
||||
AZStd::string relPathFromRoot(relativePathFromRoot.toUtf8().data());
|
||||
AZ::StringFunc::Path::Normalize(relPathFromRoot);
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
AZ::StringFunc::Tokenize(relPathFromRoot.c_str(), tokens, AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING);
|
||||
@@ -321,7 +319,6 @@ namespace AzToolsFramework::AssetUtils
|
||||
{
|
||||
relPathFromRoot.clear();
|
||||
AZ::StringFunc::Join(relPathFromRoot, tokens.begin(), tokens.end(), AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING);
|
||||
relativePathFromRoot = relPathFromRoot.c_str();
|
||||
}
|
||||
|
||||
return success;
|
||||
|
||||
@@ -52,5 +52,5 @@ namespace AzToolsFramework::AssetUtils
|
||||
//! which will be normalized and updated to be correct casing.
|
||||
//! @return if such a file does NOT exist, it returns FALSE, else returns TRUE.
|
||||
//! @note A very expensive function! Call sparingly.
|
||||
bool UpdateFilePathToCorrectCase(const QString& root, QString& relativePathFromRoot);
|
||||
bool UpdateFilePathToCorrectCase(AZStd::string_view root, AZStd::string& relativePathFromRoot);
|
||||
} //namespace AzToolsFramework::AssetUtils
|
||||
|
||||
+10
-3
@@ -191,10 +191,17 @@ namespace AzToolsFramework
|
||||
{
|
||||
if (componentClass->m_editData->m_name == componentTypeNames[i])
|
||||
{
|
||||
// Although it is rare, it can happen that two (or more) components can have the same name.
|
||||
// We should only count the first occurrence, so that none of the names in componentTypeNames
|
||||
// get skipped, but whichever component type that is encountered last will be the one
|
||||
// that is captured in order to preserve the pre-existing behavior.
|
||||
if (foundTypeIds[i].IsNull())
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
|
||||
foundTypeIds[i] = componentClass->m_typeId;
|
||||
++counter;
|
||||
//Although it is rare, it can happen that two components can have the same name.
|
||||
//We will capture only the first occurrence.
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ namespace AzToolsFramework
|
||||
int written = uuid.ToString(buffer, aznumeric_caster(bufferSize), false);
|
||||
if (written > 0)
|
||||
{
|
||||
if (bufferSize - written > 0)
|
||||
if (bufferSize > written)
|
||||
{
|
||||
buffer[written - 1] = '\n';
|
||||
buffer[written] = 0;
|
||||
|
||||
+1
@@ -453,6 +453,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
loadedSuccessfully = static_cast<PrefabEditorEntityOwnershipService*>(m_entityOwnershipService.get())->LoadFromStream(
|
||||
stream, AZStd::string_view(levelPakFile.toUtf8(), levelPakFile.size()) );
|
||||
|
||||
}
|
||||
|
||||
LoadFromStreamComplete(loadedSuccessfully);
|
||||
|
||||
+39
@@ -11,8 +11,10 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
|
||||
@@ -21,6 +23,7 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabLoader.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -91,23 +94,47 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(templateId);
|
||||
}
|
||||
m_rootInstance->Reset();
|
||||
|
||||
AzFramework::EntityOwnershipServiceNotificationBus::Event(
|
||||
m_entityContextId, &AzFramework::EntityOwnershipServiceNotificationBus::Events::OnEntityOwnershipServiceReset);
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::AddEntity(AZ::Entity* entity)
|
||||
{
|
||||
AZ_Assert(IsInitialized(), "Tried to add an entity without initializing the Entity Ownership Service");
|
||||
ScopedUndoBatch undoBatch("Undo adding entity");
|
||||
Prefab::PrefabDom instanceDomBeforeUpdate;
|
||||
Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
|
||||
|
||||
m_rootInstance->AddEntity(*entity);
|
||||
HandleEntitiesAdded({ entity });
|
||||
AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
|
||||
|
||||
Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
*m_rootInstance, "Undo adding entity", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
void PrefabEditorEntityOwnershipService::AddEntities(const EntityList& entities)
|
||||
{
|
||||
AZ_Assert(IsInitialized(), "Tried to add entities without initializing the Entity Ownership Service");
|
||||
ScopedUndoBatch undoBatch("Undo adding entities");
|
||||
Prefab::PrefabDom instanceDomBeforeUpdate;
|
||||
Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, instanceDomBeforeUpdate);
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
m_rootInstance->AddEntity(*entity);
|
||||
}
|
||||
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
AZ::TransformBus::Event(entity->GetId(), &AZ::TransformInterface::SetParent, m_rootInstance->m_containerEntity->GetId());
|
||||
}
|
||||
|
||||
Prefab::PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
*m_rootInstance, "Undo adding entities", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
bool PrefabEditorEntityOwnershipService::DestroyEntity(AZ::Entity* entity)
|
||||
@@ -172,6 +199,7 @@ namespace AzToolsFramework
|
||||
m_rootInstance->SetTemplateId(templateId);
|
||||
m_rootInstance->SetTemplateSourcePath(m_loaderInterface->GetRelativePathToProject(filename));
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -295,6 +323,9 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabEditorEntityOwnershipService::StartPlayInEditor()
|
||||
{
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnPreGameEntitiesStarted);
|
||||
|
||||
if (m_rootInstance && !m_playInEditorData.m_isEnabled)
|
||||
{
|
||||
// Construct the runtime entities and products
|
||||
@@ -339,11 +370,16 @@ namespace AzToolsFramework
|
||||
m_playInEditorData.m_assets.emplace_back(product.ReleaseAsset().release(), AZ::Data::AssetLoadBehavior::Default);
|
||||
}
|
||||
|
||||
|
||||
if (rootSpawnableIndex != NoRootSpawnable)
|
||||
{
|
||||
m_playInEditorData.m_entities.Reset(m_playInEditorData.m_assets[rootSpawnableIndex]);
|
||||
m_playInEditorData.m_entities.SpawnAllEntities();
|
||||
}
|
||||
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(
|
||||
&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesStarted);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -402,6 +438,9 @@ namespace AzToolsFramework
|
||||
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
|
||||
});
|
||||
m_playInEditorData.m_entities.Clear();
|
||||
|
||||
// This is a workaround until the replacement for GameEntityContext is done
|
||||
AzFramework::GameEntityContextEventBus::Broadcast(&AzFramework::GameEntityContextEventBus::Events::OnGameEntitiesReset);
|
||||
}
|
||||
|
||||
m_playInEditorData.m_isEnabled = false;
|
||||
|
||||
@@ -56,16 +56,6 @@ namespace AzToolsFramework
|
||||
|
||||
void EditorPrefabComponent::Activate()
|
||||
{
|
||||
PrefabPublicInterface* prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
|
||||
if (prefabPublicInterface && prefabPublicInterface->IsLevelInstanceContainerEntity(GetEntityId()))
|
||||
{
|
||||
EntityOutlinerWidgetInterface* entityOutlinerWidgetInterface = AZ::Interface<EntityOutlinerWidgetInterface>::Get();
|
||||
if (entityOutlinerWidgetInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetRootEntity(GetEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
PrefabInstanceContainerNotificationBus::Broadcast(
|
||||
&PrefabInstanceContainerNotifications::OnPrefabComponentActivate, GetEntityId());
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace AzToolsFramework
|
||||
if (instanceToTemplateEntityIdIterator != m_instanceToTemplateEntityIdMap.end())
|
||||
{
|
||||
entityAliasToRemove = instanceToTemplateEntityIdIterator->second;
|
||||
bool isEntityRemoved = m_instanceEntityMapper->UnregisterEntity(entityId) &&
|
||||
[[maybe_unused]] bool isEntityRemoved = m_instanceEntityMapper->UnregisterEntity(entityId) &&
|
||||
m_templateToInstanceEntityIdMap.erase(entityAliasToRemove) && m_instanceToTemplateEntityIdMap.erase(entityId);
|
||||
AZ_Assert(isEntityRemoved,
|
||||
"Prefab - Failed to remove entity with id %s with a Prefab Instance derived from source asset %s "
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ namespace AzToolsFramework
|
||||
EntityList entitiesInInstance;
|
||||
entitiesInInstance.reserve(instance->m_entities.size() + 1);
|
||||
|
||||
if (instance->m_containerEntity->GetId().IsValid())
|
||||
if (instance->m_containerEntity && instance->m_containerEntity->GetId().IsValid())
|
||||
{
|
||||
entitiesInInstance.emplace_back(instance->m_containerEntity.get());
|
||||
}
|
||||
|
||||
+2
-4
@@ -43,14 +43,12 @@ namespace AzToolsFramework
|
||||
const PrefabDom& modifiedState, const LinkId linkId) = 0;
|
||||
|
||||
//! Updates the affected template for a given entityId using the providedPatch
|
||||
virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) = 0;
|
||||
|
||||
virtual bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) = 0;
|
||||
virtual bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) = 0;
|
||||
|
||||
virtual void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) = 0;
|
||||
|
||||
//! Updates the template links (updating instances) for the given templateId using the providedPatch
|
||||
virtual void PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId) = 0;
|
||||
virtual bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) = 0;
|
||||
|
||||
virtual void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) = 0;
|
||||
|
||||
|
||||
+14
-54
@@ -107,7 +107,7 @@ namespace AzToolsFramework
|
||||
return result.GetProcessing() != AZ::JsonSerializationResult::Processing::Halted;
|
||||
}
|
||||
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId)
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId)
|
||||
{
|
||||
InstanceOptionalReference instanceOptionalReference = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
|
||||
@@ -119,54 +119,10 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
//get template space associated with instance
|
||||
Instance& instance = instanceOptionalReference->get();
|
||||
TemplateId templateId = instance.GetTemplateId();
|
||||
|
||||
//alias entity goes by in template -> get via owning instance map
|
||||
AZStd::optional<EntityAlias> entityAlias = instance.GetEntityAlias(entityId);
|
||||
|
||||
if (!entityAlias)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to find an entity alias for the provided entity");
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
return PatchEntityInTemplate(providedPatch, entityAlias.value(), templateId);
|
||||
}
|
||||
|
||||
bool InstanceToTemplatePropagator::PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId)
|
||||
{
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
//query into the template dom for the alias
|
||||
PrefabDomValueReference entityList = PrefabDomUtils::FindPrefabDomValue(templateDomReference, PrefabDomUtils::EntitiesName);
|
||||
|
||||
if (!entityList)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Cannot patch entity in Template with id [%llu] because entity couldn't be found in the template", templateId);
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefabDomValueReference entity = PrefabDomUtils::FindPrefabDomValue(entityList->get(), entityAlias.c_str());
|
||||
|
||||
if (!entity)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to aquire entity value reference");
|
||||
return false;
|
||||
}
|
||||
|
||||
//apply patch to section
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(entity->get(),
|
||||
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
|
||||
|
||||
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, "Patch was not successfully applied")
|
||||
|
||||
//trigger propagation
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId);
|
||||
return true;
|
||||
//get template id associated with instance
|
||||
TemplateId templateId = instanceOptionalReference->get().GetTemplateId();
|
||||
AppendEntityAliasToPatchPaths(providedPatch, entityId);
|
||||
return PatchTemplate(providedPatch, templateId);
|
||||
}
|
||||
|
||||
void InstanceToTemplatePropagator::AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId)
|
||||
@@ -216,7 +172,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, const TemplateId& templateId)
|
||||
bool InstanceToTemplatePropagator::PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId)
|
||||
{
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId);
|
||||
|
||||
@@ -224,14 +180,17 @@ namespace AzToolsFramework
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference,
|
||||
templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch);
|
||||
|
||||
AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success,
|
||||
"Patch was not successfully applied");
|
||||
|
||||
//trigger propagation
|
||||
if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success)
|
||||
{
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("Prefab", false, "Patch was not successfully applied");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,6 +247,8 @@ namespace AzToolsFramework
|
||||
|
||||
AddPatchesToLink(patches, linkToApplyPatches);
|
||||
linkToApplyPatches.UpdateTarget();
|
||||
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(linkToApplyPatches.GetTargetTemplateId(), true);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(linkToApplyPatches.GetTargetTemplateId());
|
||||
}
|
||||
|
||||
@@ -314,7 +275,6 @@ namespace AzToolsFramework
|
||||
PrefabDom& linkDom = link.GetLinkDom();
|
||||
PrefabDomValueReference linkPatchesReference =
|
||||
PrefabDomUtils::FindPrefabDomValue(linkDom, PrefabDomUtils::PatchesName);
|
||||
PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(link.GetTargetTemplateId());
|
||||
|
||||
// This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them.
|
||||
if (!linkPatchesReference.has_value())
|
||||
|
||||
+2
-4
@@ -31,21 +31,19 @@ namespace AzToolsFramework
|
||||
bool GeneratePatch(PrefabDom& generatedPatch, const PrefabDom& initialState, const PrefabDom& modifiedState) override;
|
||||
bool GeneratePatchForLink(PrefabDom& generatedPatch, const PrefabDom& initialState,
|
||||
const PrefabDom& modifiedState, LinkId linkId) override;
|
||||
bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const AZ::EntityId& entityId) override;
|
||||
bool PatchEntityInTemplate(PrefabDomValue& providedPatch, const EntityAlias& entityAlias, const TemplateId& templateId) override;
|
||||
bool PatchEntityInTemplate(PrefabDom& providedPatch, AZ::EntityId entityId) override;
|
||||
|
||||
void AppendEntityAliasToPatchPaths(PrefabDom& providedPatch, const AZ::EntityId& entityId) override;
|
||||
|
||||
InstanceOptionalReference GetTopMostInstanceInHierarchy(AZ::EntityId entityId);
|
||||
|
||||
void PatchTemplate(PrefabDomValue& providedPatch, const AzToolsFramework::Prefab::TemplateId& templateId) override;
|
||||
bool PatchTemplate(PrefabDomValue& providedPatch, TemplateId templateId) override;
|
||||
|
||||
void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override;
|
||||
|
||||
void AddPatchesToLink(PrefabDom& patches, Link& link);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
InstanceEntityMapperInterface* m_instanceEntityMapperInterface;
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface;
|
||||
|
||||
+16
-8
@@ -19,6 +19,7 @@
|
||||
#include <AzToolsFramework/Prefab/Instance/Instance.h>
|
||||
#include <AzToolsFramework/Prefab/Instance/TemplateInstanceMapperInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabDomUtils.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/Template/Template.h>
|
||||
#include <AzToolsFramework/UI/Outliner/EntityOutlinerWidgetInterface.h>
|
||||
@@ -121,8 +122,12 @@ namespace AzToolsFramework
|
||||
|
||||
Template& currentTemplate = currentTemplateReference->get();
|
||||
Instance::EntityList newEntities;
|
||||
if (!PrefabDomUtils::LoadInstanceFromPrefabDom(
|
||||
*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
|
||||
if (PrefabDomUtils::LoadInstanceFromPrefabDom(*instanceToUpdate, newEntities, currentTemplate.GetPrefabDom()))
|
||||
{
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
@@ -132,8 +137,6 @@ namespace AzToolsFramework
|
||||
|
||||
isUpdateSuccessful = false;
|
||||
}
|
||||
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
|
||||
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded, newEntities);
|
||||
|
||||
m_instancesUpdateQueue.pop();
|
||||
|
||||
@@ -142,12 +145,17 @@ namespace AzToolsFramework
|
||||
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selectedEntityIds);
|
||||
|
||||
// Enable the Outliner
|
||||
AZ::SystemTickBus::QueueFunction([entityOutlinerWidgetInterface]() {
|
||||
if (entityOutlinerWidgetInterface)
|
||||
if (entityOutlinerWidgetInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
|
||||
|
||||
auto prefabPublicInterface = AZ::Interface<PrefabPublicInterface>::Get();
|
||||
if (prefabPublicInterface)
|
||||
{
|
||||
entityOutlinerWidgetInterface->SetUpdatesEnabled(true);
|
||||
AZ::EntityId rootEntityId = prefabPublicInterface->GetLevelInstanceContainerEntityId();
|
||||
entityOutlinerWidgetInterface->ExpandEntityChildren(rootEntityId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
m_updatingTemplateInstancesInQueue = false;
|
||||
|
||||
@@ -127,12 +127,12 @@ namespace AzToolsFramework
|
||||
InstanceEntityScrubber instanceEntityScrubber(newlyAddedEntities);
|
||||
settings.m_metadata.Add(&instanceEntityScrubber);
|
||||
|
||||
AZ::JsonSerializationResult::ResultCode result =
|
||||
AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Load(instance, prefabDom, settings);
|
||||
|
||||
if (result.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
|
||||
{
|
||||
AZ_Error("Prefab", false,
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"Failed to de-serialize Prefab Instance from Prefab DOM. "
|
||||
"Unable to proceed.");
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace AzToolsFramework
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
AZ_Assert(settingsRegistry, "Settings registry is not set");
|
||||
|
||||
bool result =
|
||||
[[maybe_unused]] bool result =
|
||||
settingsRegistry->Get(m_projectPathWithOsSeparator.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath);
|
||||
AZ_Assert(result, "Couldn't retrieve project root path");
|
||||
m_projectPathWithSlashSeparator = AZ::IO::Path(m_projectPathWithOsSeparator.Native(), '/').MakePreferred();
|
||||
@@ -182,7 +182,6 @@ namespace AzToolsFramework
|
||||
for (PrefabDomValue::MemberIterator instanceIterator = instances.MemberBegin(); instanceIterator != instances.MemberEnd();
|
||||
++instanceIterator)
|
||||
{
|
||||
const PrefabDomValue& instance = instanceIterator->value;
|
||||
if (!LoadNestedInstance(instanceIterator, newTemplateId, progressedFilePathsSet))
|
||||
{
|
||||
isLoadedWithErrors = true;
|
||||
@@ -349,8 +348,7 @@ namespace AzToolsFramework
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplate - Unable to save Prefab Template with id: %llu. "
|
||||
"Template with that id is invalid",
|
||||
templateId
|
||||
);
|
||||
templateId);
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <AzToolsFramework/Prefab/PrefabLoaderInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabSystemComponentInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndo.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabUndoHelpers.h>
|
||||
#include <AzToolsFramework/ToolsComponents/TransformComponent.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -247,23 +248,8 @@ namespace AzToolsFramework
|
||||
|
||||
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::SetSelectedEntities, selection);
|
||||
|
||||
PrefabDom instanceDomAfterUpdate;
|
||||
m_instanceToTemplateInterface->GenerateDomForInstance(instanceDomAfterUpdate, entityOwningInstance);
|
||||
|
||||
// Generate the patch comparing the instance before and after the entity addition.
|
||||
PrefabDom patch;
|
||||
if (!m_instanceToTemplateInterface->GeneratePatch(patch, instanceDomBeforeUpdate, instanceDomAfterUpdate))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format(
|
||||
"A valid patch couldn't be created for adding an entity with id '%llu'", static_cast<AZ::u64>(entityId)));
|
||||
}
|
||||
|
||||
// create undo node
|
||||
PrefabUndoInstance* state = aznew PrefabUndoInstance(AZStd::string::format("%llu", static_cast<AZ::u64>(entityId)));
|
||||
state->Capture(instanceDomBeforeUpdate, instanceDomAfterUpdate, entityOwningInstance.GetTemplateId());
|
||||
state->SetParent(undoBatch.GetUndoBatch());
|
||||
|
||||
state->Redo();
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
entityOwningInstance, "Undo adding entity", instanceDomBeforeUpdate, undoBatch.GetUndoBatch());
|
||||
|
||||
return AZ::Success(entityId);
|
||||
}
|
||||
@@ -643,14 +629,17 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
bool PrefabPublicHandler::RetrieveAndSortPrefabEntitiesAndInstances(
|
||||
const EntityList& inputEntities, const Instance& commonRootEntityOwningInstance,
|
||||
const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const
|
||||
{
|
||||
AZStd::queue<AZ::Entity*> entityQueue;
|
||||
|
||||
for (auto inputEntity : inputEntities)
|
||||
{
|
||||
entityQueue.push(inputEntity);
|
||||
if (inputEntity && !IsLevelInstanceContainerEntity(inputEntity->GetId()))
|
||||
{
|
||||
entityQueue.push(inputEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// Support sets to easily identify if we're processing the same entity multiple times.
|
||||
@@ -664,17 +653,19 @@ namespace AzToolsFramework
|
||||
|
||||
// Get this entity's owning instance.
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entity->GetId());
|
||||
AZ_Assert(owningInstance.has_value(), "An error occored while retrieving entities and prefab instances : "
|
||||
"Owning instance of entity with id '%llu' couldn't be found", entity->GetId());
|
||||
AZ_Assert(
|
||||
owningInstance.has_value(),
|
||||
"An error occored while retrieving entities and prefab instances : "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entity->GetId());
|
||||
|
||||
// Check if this entity is owned by the same instance owning the root.
|
||||
if (&owningInstance->get() == &commonRootEntityOwningInstance)
|
||||
{
|
||||
AZStd::unique_ptr<AZ::Entity> detachedEntity = owningInstance->get().DetachEntity(entity->GetId());
|
||||
// If it's the same instance, we can add this entity to the new instance entities.
|
||||
int priorEntitiesSize = entities.size();
|
||||
|
||||
entities.insert(detachedEntity.release());
|
||||
entities.insert(entity);
|
||||
|
||||
// If the size of entities increased, then it wasn't added before.
|
||||
// In that case, add the children of this entity to the queue.
|
||||
@@ -714,20 +705,18 @@ namespace AzToolsFramework
|
||||
|
||||
// Store results
|
||||
outEntities.clear();
|
||||
outEntities.resize(entities.size());
|
||||
AZStd::copy(entities.begin(), entities.end(), outEntities.begin());
|
||||
outEntities.reserve(entities.size());
|
||||
|
||||
for (AZ::Entity* entity : entities)
|
||||
{
|
||||
outEntities.emplace_back(commonRootEntityOwningInstance.DetachEntity(entity->GetId()).release());
|
||||
}
|
||||
|
||||
outInstances.clear();
|
||||
outInstances.reserve(instances.size());
|
||||
for (Instance* instancePtr : instances)
|
||||
{
|
||||
auto parentInstance = instancePtr->GetParentInstance();
|
||||
|
||||
if (parentInstance.has_value())
|
||||
{
|
||||
auto uniquePtr = parentInstance->get().DetachNestedInstance(instancePtr->GetInstanceAlias());
|
||||
outInstances.push_back(AZStd::move(uniquePtr));
|
||||
}
|
||||
outInstances.push_back(AZStd::move(commonRootEntityOwningInstance.DetachNestedInstance(instancePtr->GetInstanceAlias())));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -745,8 +734,20 @@ namespace AzToolsFramework
|
||||
for (AZ::EntityId entityId : entityIds)
|
||||
{
|
||||
InstanceOptionalReference owningInstance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
|
||||
// If this is the container entity, it actually represents the instance so get its owner
|
||||
if (owningInstance->get().GetContainerEntityId() == entityId)
|
||||
|
||||
if (!owningInstance.has_value())
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"An error occored in function EntitiesBelongToSameInstance: "
|
||||
"Owning instance of entity with id '%llu' couldn't be found",
|
||||
entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a container entity, it actually represents a child instance so get its owner.
|
||||
// The only exception in the level root instance. We leave it as is to streamline operations.
|
||||
if (owningInstance->get().GetContainerEntityId() == entityId && !IsLevelInstanceContainerEntity(entityId))
|
||||
{
|
||||
owningInstance = owningInstance->get().GetParentInstance();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace AzToolsFramework
|
||||
|
||||
private:
|
||||
PrefabOperationResult DeleteFromInstance(const EntityIdList& entityIds, bool deleteDescendants);
|
||||
bool RetrieveAndSortPrefabEntitiesAndInstances(const EntityList& inputEntities, const Instance& commonRootEntityOwningInstance,
|
||||
bool RetrieveAndSortPrefabEntitiesAndInstances(const EntityList& inputEntities, Instance& commonRootEntityOwningInstance,
|
||||
EntityList& outEntities, AZStd::vector<AZStd::unique_ptr<Instance>>& outInstances) const;
|
||||
|
||||
InstanceOptionalReference GetOwnerInstanceByEntityId(AZ::EntityId entityId) const;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user