Merge branch 'stabilization/2106' of https://github.com/aws-lumberyard/o3de into Atom/gallowj/stabilization/2106
This commit is contained in:
@@ -122,29 +122,22 @@ namespace AWSMetrics
|
||||
//! @return Outcome of the operation.
|
||||
AZ::Outcome<void, AZStd::string> SendMetricsToFile(AZStd::shared_ptr<MetricsQueue> metricsQueue);
|
||||
|
||||
//! Check whether the consumer should flush the metrics queue.
|
||||
//! @return whether the limit is hit.
|
||||
bool ShouldSendMetrics();
|
||||
|
||||
//! Push metrics events to the front of the queue for retry.
|
||||
//! @param metricsEventsForRetry Metrics events for retry.
|
||||
void PushMetricsForRetry(MetricsQueue& metricsEventsForRetry);
|
||||
|
||||
void SubmitLocalMetricsAsync();
|
||||
|
||||
////////////////////////////////////////////
|
||||
// These data are protected by m_metricsMutex.
|
||||
AZStd::mutex m_metricsMutex;
|
||||
AZStd::chrono::system_clock::time_point m_lastSendMetricsTime;
|
||||
MetricsQueue m_metricsQueue;
|
||||
////////////////////////////////////////////
|
||||
AZStd::mutex m_metricsMutex; //!< Mutex to protect the metrics queue
|
||||
MetricsQueue m_metricsQueue; //!< Queue fo buffering the metrics events
|
||||
|
||||
AZStd::mutex m_metricsFileMutex; //!< Local metrics file is protected by m_metricsFileMutex
|
||||
AZStd::mutex m_metricsFileMutex; //!< Mutex to protect the local metrics file
|
||||
|
||||
AZStd::atomic<int> m_sendMetricsId;//!< Request ID for sending metrics
|
||||
|
||||
AZStd::thread m_consumerThread; //!< Thread to monitor and consume the metrics queue
|
||||
AZStd::atomic<bool> m_consumerTerminated;
|
||||
AZStd::thread m_monitorThread; //!< Thread to monitor and consume the metrics queue
|
||||
AZStd::atomic<bool> m_monitorTerminated;
|
||||
AZStd::binary_semaphore m_waitEvent;
|
||||
|
||||
// Client Configurations.
|
||||
AZStd::unique_ptr<ClientConfiguration> m_clientConfiguration;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AWSMetrics
|
||||
MetricsManager::MetricsManager()
|
||||
: m_clientConfiguration(AZStd::make_unique<ClientConfiguration>())
|
||||
, m_clientIdProvider(IdentityProvider::CreateIdentityProvider())
|
||||
, m_consumerTerminated(true)
|
||||
, m_monitorTerminated(true)
|
||||
, m_sendMetricsId(0)
|
||||
{
|
||||
}
|
||||
@@ -53,31 +53,27 @@ namespace AWSMetrics
|
||||
|
||||
void MetricsManager::StartMetrics()
|
||||
{
|
||||
if (!m_consumerTerminated)
|
||||
if (!m_monitorTerminated)
|
||||
{
|
||||
// The background thread has been started.
|
||||
return;
|
||||
}
|
||||
|
||||
m_consumerTerminated = false;
|
||||
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
|
||||
m_lastSendMetricsTime = AZStd::chrono::system_clock::now();
|
||||
m_monitorTerminated = false;
|
||||
|
||||
// Start a separate thread to monitor and consume the metrics queue.
|
||||
// Avoid using the job system since the worker is long-running over multiple frames
|
||||
m_consumerThread = AZStd::thread(AZStd::bind(&MetricsManager::MonitorMetricsQueue, this));
|
||||
m_monitorThread = AZStd::thread(AZStd::bind(&MetricsManager::MonitorMetricsQueue, this));
|
||||
}
|
||||
|
||||
void MetricsManager::MonitorMetricsQueue()
|
||||
{
|
||||
while (!m_consumerTerminated)
|
||||
// Continue to loop until the monitor is terminated.
|
||||
while (!m_monitorTerminated)
|
||||
{
|
||||
if (ShouldSendMetrics())
|
||||
{
|
||||
// Flush the metrics queue when the accumulated metrics size or time period hits the limit
|
||||
FlushMetricsAsync();
|
||||
}
|
||||
// The thread will wake up either when the metrics event queue is full (try_acquire_for call returns true),
|
||||
// or the flush period limit is hit (try_acquire_for call returns false).
|
||||
m_waitEvent.try_acquire_for(AZStd::chrono::seconds(m_clientConfiguration->GetQueueFlushPeriodInSeconds()));
|
||||
FlushMetricsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +110,12 @@ namespace AWSMetrics
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
|
||||
m_metricsQueue.AddMetrics(metricsEvent);
|
||||
|
||||
if (m_metricsQueue.GetSizeInBytes() >= m_clientConfiguration->GetMaxQueueSizeInBytes())
|
||||
{
|
||||
// Flush the metrics queue when the accumulated metrics size hits the limit
|
||||
m_waitEvent.release();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -348,9 +350,6 @@ namespace AWSMetrics
|
||||
void MetricsManager::FlushMetricsAsync()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
|
||||
|
||||
m_lastSendMetricsTime = AZStd::chrono::system_clock::now();
|
||||
|
||||
if (m_metricsQueue.GetNumMetrics() == 0)
|
||||
{
|
||||
return;
|
||||
@@ -363,34 +362,20 @@ namespace AWSMetrics
|
||||
SendMetricsAsync(metricsToFlush);
|
||||
}
|
||||
|
||||
bool MetricsManager::ShouldSendMetrics()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
|
||||
|
||||
auto secondsSinceLastFlush = AZStd::chrono::duration_cast<AZStd::chrono::seconds>(AZStd::chrono::system_clock::now() - m_lastSendMetricsTime);
|
||||
if (secondsSinceLastFlush >= AZStd::chrono::seconds(m_clientConfiguration->GetQueueFlushPeriodInSeconds()) ||
|
||||
m_metricsQueue.GetSizeInBytes() >= m_clientConfiguration->GetMaxQueueSizeInBytes())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MetricsManager::ShutdownMetrics()
|
||||
{
|
||||
if (m_consumerTerminated)
|
||||
if (m_monitorTerminated)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Terminate the consumer thread
|
||||
m_consumerTerminated = true;
|
||||
FlushMetricsAsync();
|
||||
// Terminate the monitor thread
|
||||
m_monitorTerminated = true;
|
||||
m_waitEvent.release();
|
||||
|
||||
if (m_consumerThread.joinable())
|
||||
if (m_monitorThread.joinable())
|
||||
{
|
||||
m_consumerThread.join();
|
||||
m_monitorThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +434,12 @@ namespace AWSMetrics
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
|
||||
m_metricsQueue.AddMetrics(offlineRecords[index]);
|
||||
|
||||
if (m_metricsQueue.GetSizeInBytes() >= m_clientConfiguration->GetMaxQueueSizeInBytes())
|
||||
{
|
||||
// Flush the metrics queue when the accumulated metrics size hits the limit
|
||||
m_waitEvent.release();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the local metrics file after reading all its content.
|
||||
|
||||
@@ -355,6 +355,9 @@ namespace AWSMetrics
|
||||
|
||||
TEST_F(MetricsManagerTest, FlushMetrics_NonEmptyQueue_Success)
|
||||
{
|
||||
ResetClientConfig(true, (double)TestMetricsEventSizeInBytes * (MaxNumMetricsEvents + 1) / MbToBytes,
|
||||
DefaultFlushPeriodInSeconds, 1);
|
||||
|
||||
for (int index = 0; index < MaxNumMetricsEvents; ++index)
|
||||
{
|
||||
AZStd::vector<MetricsAttribute> metricsAttributes;
|
||||
@@ -377,7 +380,7 @@ namespace AWSMetrics
|
||||
TEST_F(MetricsManagerTest, ResetOfflineRecordingStatus_ResubmitLocalMetrics_Success)
|
||||
{
|
||||
// Disable offline recording in the config file.
|
||||
ResetClientConfig(false, 0.0, 0, 0);
|
||||
ResetClientConfig(false, (double)TestMetricsEventSizeInBytes * 2 / MbToBytes, 0, 0);
|
||||
|
||||
// Enable offline recording after initialize the metric manager.
|
||||
m_metricsManager->UpdateOfflineRecordingStatus(true);
|
||||
|
||||
@@ -265,6 +265,12 @@ namespace AZ
|
||||
// Update all bindings on this pass that are connected to bindings on other passes
|
||||
void UpdateConnectedBindings();
|
||||
|
||||
// Update input and input/output bindings on this pass that are connected to bindings on other passes
|
||||
void UpdateConnectedInputBindings();
|
||||
|
||||
// Update output bindings on this pass that are connected to bindings on other passes
|
||||
void UpdateConnectedOutputBindings();
|
||||
|
||||
|
||||
protected:
|
||||
explicit Pass(const PassDescriptor& descriptor);
|
||||
|
||||
@@ -1036,6 +1036,26 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void Pass::UpdateConnectedInputBindings()
|
||||
{
|
||||
for (uint8_t idx : m_inputBindingIndices)
|
||||
{
|
||||
UpdateConnectedBinding(m_attachmentBindings[idx]);
|
||||
}
|
||||
for (uint8_t idx : m_inputOutputBindingIndices)
|
||||
{
|
||||
UpdateConnectedBinding(m_attachmentBindings[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
void Pass::UpdateConnectedOutputBindings()
|
||||
{
|
||||
for (uint8_t idx : m_outputBindingIndices)
|
||||
{
|
||||
UpdateConnectedBinding(m_attachmentBindings[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Queuing functions with PassSystem ---
|
||||
|
||||
void Pass::QueueForBuildAndInitialization()
|
||||
@@ -1264,7 +1284,7 @@ namespace AZ
|
||||
AZ_Assert(m_state == PassState::Idle, "Pass::FrameBegin - Pass [%s] is attempting to render, but is not in the Idle state.", m_path.GetCStr());
|
||||
m_state = PassState::Rendering;
|
||||
|
||||
UpdateConnectedBindings();
|
||||
UpdateConnectedInputBindings();
|
||||
UpdateOwnedAttachments();
|
||||
|
||||
CreateTransientAttachments(params.m_frameGraphBuilder->GetAttachmentDatabase());
|
||||
@@ -1273,6 +1293,8 @@ namespace AZ
|
||||
// FrameBeginInternal needs to be the last function be called in FrameBegin because its implementation expects
|
||||
// all the attachments are imported to database (for example, ImageAttachmentPreview)
|
||||
FrameBeginInternal(params);
|
||||
|
||||
UpdateConnectedOutputBindings();
|
||||
}
|
||||
|
||||
void Pass::FrameEnd()
|
||||
|
||||
@@ -20,10 +20,12 @@ namespace CommandSystem
|
||||
SelectionList::SelectionList()
|
||||
{
|
||||
EMotionFX::ActorNotificationBus::Handler::BusConnect();
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
SelectionList::~SelectionList()
|
||||
{
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusDisconnect();
|
||||
EMotionFX::ActorNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
@@ -378,4 +380,9 @@ namespace CommandSystem
|
||||
|
||||
RemoveActor(actor);
|
||||
}
|
||||
|
||||
void SelectionList::OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance)
|
||||
{
|
||||
RemoveActorInstance(actorInstance);
|
||||
}
|
||||
} // namespace CommandSystem
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "CommandSystemConfig.h"
|
||||
#include <EMotionFX/Source/ActorBus.h>
|
||||
#include <EMotionFX/Source/ActorInstance.h>
|
||||
#include <EMotionFX/Source/ActorInstanceBus.h>
|
||||
#include <EMotionFX/Source/Motion.h>
|
||||
#include <EMotionFX/Source/Node.h>
|
||||
#include <EMotionFX/Source/MotionInstance.h>
|
||||
@@ -27,7 +28,8 @@ namespace CommandSystem
|
||||
* specific time stamp in a scene.
|
||||
*/
|
||||
class COMMANDSYSTEM_API SelectionList
|
||||
: EMotionFX::ActorNotificationBus::Handler
|
||||
: private EMotionFX::ActorNotificationBus::Handler
|
||||
, private EMotionFX::ActorInstanceNotificationBus::Handler
|
||||
{
|
||||
MCORE_MEMORYOBJECTCATEGORY(SelectionList, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_COMMANDSYSTEM);
|
||||
|
||||
@@ -400,6 +402,9 @@ namespace CommandSystem
|
||||
// ActorNotificationBus overrides
|
||||
void OnActorDestroyed(EMotionFX::Actor* actor) override;
|
||||
|
||||
// ActorInstanceNotificationBus overrides
|
||||
void OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance) override;
|
||||
|
||||
AZStd::vector<EMotionFX::Node*> mSelectedNodes; /**< Array of selected nodes. */
|
||||
AZStd::vector<EMotionFX::Actor*> mSelectedActors; /**< The selected actors. */
|
||||
AZStd::vector<EMotionFX::ActorInstance*> mSelectedActorInstances; /**< Array of selected actor instances. */
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "NodeGroup.h"
|
||||
#include "Recorder.h"
|
||||
#include "TransformData.h"
|
||||
#include <EMotionFX/Source/ActorInstanceBus.h>
|
||||
#include <EMotionFX/Source/DebugDraw.h>
|
||||
#include <EMotionFX/Source/RagdollInstance.h>
|
||||
|
||||
@@ -153,20 +154,14 @@ namespace EMotionFX
|
||||
// register it
|
||||
GetActorManager().RegisterActorInstance(this);
|
||||
|
||||
// automatically register the actor instance
|
||||
GetEventManager().OnCreateActorInstance(this);
|
||||
|
||||
GetActorManager().GetScheduler()->RecursiveInsertActorInstance(this);
|
||||
|
||||
ActorInstanceNotificationBus::Broadcast(&ActorInstanceNotificationBus::Events::OnActorInstanceCreated, this);
|
||||
}
|
||||
|
||||
// the destructor
|
||||
ActorInstance::~ActorInstance()
|
||||
{
|
||||
// trigger the OnDeleteActorInstance event
|
||||
GetEventManager().OnDeleteActorInstance(this);
|
||||
|
||||
// remove it from the recording
|
||||
GetRecorder().RemoveActorInstanceFromRecording(this);
|
||||
ActorInstanceNotificationBus::Broadcast(&ActorInstanceNotificationBus::Events::OnActorInstanceDestroyed, this);
|
||||
|
||||
// get rid of the motion system
|
||||
if (mMotionSystem)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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/EBus/EBus.h>
|
||||
|
||||
namespace EMotionFX
|
||||
{
|
||||
class ActorInstance;
|
||||
|
||||
/**
|
||||
* EMotion FX Actor Instance Request Bus
|
||||
* Used for making requests to actor instances.
|
||||
*/
|
||||
class ActorInstanceRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
using ActorInstanceRequestBus = AZ::EBus<ActorInstanceRequests>;
|
||||
|
||||
/**
|
||||
* EMotion FX Actor Instance Notification Bus
|
||||
* Used for monitoring events from actor instances.
|
||||
*/
|
||||
class ActorInstanceNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
// Enable multi-threaded access by locking primitive using a mutex when connecting handlers to the EBus or executing events.
|
||||
using MutexType = AZStd::recursive_mutex;
|
||||
|
||||
virtual void OnActorInstanceCreated([[maybe_unused]] ActorInstance* actorInstance) {}
|
||||
|
||||
/**
|
||||
* Called when any of the actor instances gets destructed.
|
||||
* @param actorInstance The actorInstance that gets destructed.
|
||||
*/
|
||||
virtual void OnActorInstanceDestroyed([[maybe_unused]] ActorInstance* actorInstance) {}
|
||||
};
|
||||
|
||||
using ActorInstanceNotificationBus = AZ::EBus<ActorInstanceNotifications>;
|
||||
} // namespace EMotionFX
|
||||
@@ -51,7 +51,6 @@ namespace EMotionFX
|
||||
EVENT_TYPE_MOTION_INSTANCE_LAST_EVENT = EVENT_TYPE_ON_QUEUE_MOTION_INSTANCE,
|
||||
|
||||
EVENT_TYPE_ON_DELETE_ACTOR,
|
||||
EVENT_TYPE_ON_DELETE_ACTOR_INSTANCE,
|
||||
EVENT_TYPE_ON_SIMULATE_PHYSICS,
|
||||
EVENT_TYPE_ON_CUSTOM_EVENT,
|
||||
EVENT_TYPE_ON_DRAW_LINE,
|
||||
@@ -64,7 +63,6 @@ namespace EMotionFX
|
||||
EVENT_TYPE_ON_CREATE_MOTION_INSTANCE,
|
||||
EVENT_TYPE_ON_CREATE_MOTION_SYSTEM,
|
||||
EVENT_TYPE_ON_CREATE_ACTOR,
|
||||
EVENT_TYPE_ON_CREATE_ACTOR_INSTANCE,
|
||||
EVENT_TYPE_ON_POST_CREATE_ACTOR,
|
||||
EVENT_TYPE_ON_DELETE_ANIM_GRAPH,
|
||||
EVENT_TYPE_ON_DELETE_ANIM_GRAPH_INSTANCE,
|
||||
@@ -298,15 +296,6 @@ namespace EMotionFX
|
||||
*/
|
||||
virtual void OnDeleteActor(Actor* actor) { MCORE_UNUSED(actor); }
|
||||
|
||||
/**
|
||||
* The event that gets triggered once an ActorInstance object is being deleted.
|
||||
* You could for example use this event to delete any allocations you have done inside the
|
||||
* custom user data object linked with the ActorInstance object.
|
||||
* You can get and set this data object with the ActorInstance::GetCustomData() and ActorInstance::SetCustomData(...) methods.
|
||||
* @param actorInstance The actorInstance that is being deleted.
|
||||
*/
|
||||
virtual void OnDeleteActorInstance(ActorInstance* actorInstance) { MCORE_UNUSED(actorInstance); }
|
||||
|
||||
virtual void OnSimulatePhysics(float timeDelta) { MCORE_UNUSED(timeDelta); }
|
||||
virtual void OnCustomEvent(uint32 eventType, void* data) { MCORE_UNUSED(eventType); MCORE_UNUSED(data); }
|
||||
|
||||
@@ -321,7 +310,6 @@ namespace EMotionFX
|
||||
virtual void OnCreateMotionInstance(MotionInstance* motionInstance) { MCORE_UNUSED(motionInstance); }
|
||||
virtual void OnCreateMotionSystem(MotionSystem* motionSystem) { MCORE_UNUSED(motionSystem); }
|
||||
virtual void OnCreateActor(Actor* actor) { MCORE_UNUSED(actor); }
|
||||
virtual void OnCreateActorInstance(ActorInstance* actorInstance) { MCORE_UNUSED(actorInstance); }
|
||||
virtual void OnPostCreateActor(Actor* actor) { MCORE_UNUSED(actor); }
|
||||
|
||||
// delete callbacks
|
||||
|
||||
@@ -305,16 +305,6 @@ namespace EMotionFX
|
||||
}
|
||||
|
||||
|
||||
void EventManager::OnDeleteActorInstance(ActorInstance* actorInstance)
|
||||
{
|
||||
const EventHandlerVector& eventHandlers = m_eventHandlersByEventType[EVENT_TYPE_ON_DELETE_ACTOR_INSTANCE];
|
||||
for (EventHandler* eventHandler : eventHandlers)
|
||||
{
|
||||
eventHandler->OnDeleteActorInstance(actorInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// draw a debug triangle
|
||||
void EventManager::OnDrawTriangle(const AZ::Vector3& posA, const AZ::Vector3& posB, const AZ::Vector3& posC, const AZ::Vector3& normalA, const AZ::Vector3& normalB, const AZ::Vector3& normalC, uint32 color)
|
||||
{
|
||||
@@ -670,17 +660,6 @@ namespace EMotionFX
|
||||
}
|
||||
|
||||
|
||||
// create an actor instance
|
||||
void EventManager::OnCreateActorInstance(ActorInstance* actorInstance)
|
||||
{
|
||||
const EventHandlerVector& eventHandlers = m_eventHandlersByEventType[EVENT_TYPE_ON_CREATE_ACTOR_INSTANCE];
|
||||
for (EventHandler* eventHandler : eventHandlers)
|
||||
{
|
||||
eventHandler->OnCreateActorInstance(actorInstance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// on post create actor
|
||||
void EventManager::OnPostCreateActor(Actor* actor)
|
||||
{
|
||||
|
||||
@@ -286,15 +286,6 @@ namespace EMotionFX
|
||||
*/
|
||||
void OnDeleteActor(Actor* actor);
|
||||
|
||||
/**
|
||||
* The event that gets triggered once an ActorInstance object is being deleted.
|
||||
* You could for example use this event to delete any allocations you have done inside the
|
||||
* custom user data object linked with the ActorInstance object.
|
||||
* You can get and set this data object with the ActorInstance::GetCustomData() and ActorInstance::SetCustomData(...) methods.
|
||||
* @param actorInstance The actorInstance that is being deleted.
|
||||
*/
|
||||
void OnDeleteActorInstance(ActorInstance* actorInstance);
|
||||
|
||||
void OnSimulatePhysics(float timeDelta);
|
||||
void OnCustomEvent(uint32 eventType, void* data);
|
||||
void OnDrawTriangle(const AZ::Vector3& posA, const AZ::Vector3& posB, const AZ::Vector3& posC, const AZ::Vector3& normalA, const AZ::Vector3& normalB, const AZ::Vector3& normalC, uint32 color);
|
||||
@@ -343,7 +334,6 @@ namespace EMotionFX
|
||||
void OnCreateMotionInstance(MotionInstance* motionInstance);
|
||||
void OnCreateMotionSystem(MotionSystem* motionSystem);
|
||||
void OnCreateActor(Actor* actor);
|
||||
void OnCreateActorInstance(ActorInstance* actorInstance);
|
||||
void OnPostCreateActor(Actor* actor);
|
||||
|
||||
// delete callbacks
|
||||
|
||||
@@ -106,16 +106,12 @@ namespace EMotionFX
|
||||
mCurrentPlayTime = 0.0f;
|
||||
|
||||
mObjects.SetMemoryCategory(EMFX_MEMCATEGORY_RECORDER);
|
||||
|
||||
GetEMotionFX().GetEventManager()->AddEventHandler(this);
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
Recorder::~Recorder()
|
||||
{
|
||||
if (EventManager* eventManager = GetEMotionFX().GetEventManager())
|
||||
{
|
||||
eventManager->RemoveEventHandler(this);
|
||||
}
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusDisconnect();
|
||||
Clear();
|
||||
}
|
||||
|
||||
@@ -1448,7 +1444,7 @@ namespace EMotionFX
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Recorder::OnDeleteActorInstance(ActorInstance* actorInstance)
|
||||
void Recorder::OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance)
|
||||
{
|
||||
// Actor instances created by actor components do not use the command system and don't call a ClearRecorder command.
|
||||
// Thus, these actor instances will have to be removed from the recorder to avoid dangling data.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <MCore/Source/File.h>
|
||||
#include <MCore/Source/Vector.h>
|
||||
#include <MCore/Source/MultiThreadManager.h>
|
||||
#include <EMotionFX/Source/ActorInstanceBus.h>
|
||||
#include <EMotionFX/Source/AnimGraphObjectIds.h>
|
||||
#include <EMotionFX/Source/EventHandler.h>
|
||||
#include <EMotionFX/Source/EventInfo.h>
|
||||
@@ -47,7 +48,7 @@ namespace EMotionFX
|
||||
|
||||
class EMFX_API Recorder
|
||||
: public BaseObject
|
||||
, public EventHandler
|
||||
, private EMotionFX::ActorInstanceNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR_DECL
|
||||
@@ -319,9 +320,8 @@ namespace EMotionFX
|
||||
void RemoveActorInstanceFromRecording(ActorInstance* actorInstance);
|
||||
void RemoveAnimGraphFromRecording(AnimGraph* animGraph);
|
||||
|
||||
// EventHandler overrides
|
||||
const AZStd::vector<EventTypes> GetHandledEventTypes() const override { return {EMotionFX::EVENT_TYPE_ON_DELETE_ACTOR_INSTANCE}; }
|
||||
void OnDeleteActorInstance(ActorInstance* actorInstance) override;
|
||||
// ActorInstanceNotificationBus overrides
|
||||
void OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance) override;
|
||||
|
||||
void SampleAndApplyTransforms(float timeInSeconds, ActorInstance* actorInstance) const;
|
||||
void SampleAndApplyMainTransform(float timeInSeconds, ActorInstance* actorInstance) const;
|
||||
|
||||
+22
-15
@@ -17,25 +17,26 @@
|
||||
#include "../../../../EMStudioSDK/Source/EMStudioCore.h"
|
||||
#include <MCore/Source/LogManager.h>
|
||||
#include <EMotionFX/CommandSystem/Source/CommandManager.h>
|
||||
#include <EMotionFX/Source/ActorManager.h>
|
||||
#include <EMotionFX/Source/MorphSetup.h>
|
||||
#include "../../../../EMStudioSDK/Source/EMStudioManager.h"
|
||||
|
||||
|
||||
namespace EMStudio
|
||||
{
|
||||
// constructor
|
||||
MorphTargetsWindowPlugin::MorphTargetsWindowPlugin()
|
||||
: EMStudio::DockWidgetPlugin()
|
||||
{
|
||||
mDialogStack = nullptr;
|
||||
mCurrentActorInstance = nullptr;
|
||||
mDialogStack = nullptr;
|
||||
mCurrentActorInstance = nullptr;
|
||||
mStaticTextWidget = nullptr;
|
||||
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
MorphTargetsWindowPlugin::~MorphTargetsWindowPlugin()
|
||||
{
|
||||
EMotionFX::ActorInstanceNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
// unregister the command callbacks and get rid of the memory
|
||||
for (auto callback : m_callbacks)
|
||||
{
|
||||
@@ -110,14 +111,16 @@ namespace EMStudio
|
||||
mMorphTargetGroups.clear();
|
||||
}
|
||||
|
||||
|
||||
// reinit the morph target dialog, e.g. if selection changes
|
||||
void MorphTargetsWindowPlugin::ReInit(bool forceReInit)
|
||||
{
|
||||
// get the selected actorinstance
|
||||
const CommandSystem::SelectionList& selection = GetCommandManager()->GetCurrentSelection();
|
||||
EMotionFX::ActorInstance* actorInstance = selection.GetSingleActorInstance();
|
||||
const CommandSystem::SelectionList& selection = GetCommandManager()->GetCurrentSelection();
|
||||
EMotionFX::ActorInstance* actorInstance = selection.GetSingleActorInstance();
|
||||
ReInit(actorInstance, forceReInit);
|
||||
}
|
||||
|
||||
void MorphTargetsWindowPlugin::ReInit(EMotionFX::ActorInstance* actorInstance, bool forceReInit)
|
||||
{
|
||||
// show hint if no/multiple actor instances is/are selected
|
||||
if (actorInstance == nullptr)
|
||||
{
|
||||
@@ -135,10 +138,7 @@ namespace EMStudio
|
||||
return;
|
||||
}
|
||||
|
||||
// get our selected actor instance and the corresponding actor
|
||||
EMotionFX::Actor* actor = actorInstance->GetActor();
|
||||
|
||||
// only reinit the morph targets if actorinstance changed
|
||||
// only reinit the morph targets if actor instance changed
|
||||
if (mCurrentActorInstance != actorInstance || forceReInit)
|
||||
{
|
||||
// set the current actor instance in any case
|
||||
@@ -150,7 +150,7 @@ namespace EMStudio
|
||||
AZStd::vector<EMotionFX::MorphSetupInstance::MorphTarget*> phonemeInstances;
|
||||
AZStd::vector<EMotionFX::MorphSetupInstance::MorphTarget*> defaultMorphTargetInstances;
|
||||
|
||||
// get the morph target setup
|
||||
EMotionFX::Actor* actor = actorInstance->GetActor();
|
||||
EMotionFX::MorphSetup* morphSetup = actor->GetMorphSetup(actorInstance->GetLODLevel());
|
||||
if (morphSetup == nullptr)
|
||||
{
|
||||
@@ -278,6 +278,13 @@ namespace EMStudio
|
||||
}
|
||||
}
|
||||
|
||||
void MorphTargetsWindowPlugin::OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance)
|
||||
{
|
||||
if (mCurrentActorInstance == actorInstance)
|
||||
{
|
||||
ReInit(/*actorInstance=*/nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// Command callbacks
|
||||
|
||||
+6
@@ -16,6 +16,7 @@
|
||||
#include <MysticQt/Source/DialogStack.h>
|
||||
#include "../../../../EMStudioSDK/Source/DockWidgetPlugin.h"
|
||||
#include <EMotionFX/CommandSystem/Source/SelectionCommands.h>
|
||||
#include <EMotionFX/Source/ActorInstanceBus.h>
|
||||
#include "MorphTargetGroupWidget.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
@@ -26,6 +27,7 @@ namespace EMStudio
|
||||
{
|
||||
class MorphTargetsWindowPlugin
|
||||
: public EMStudio::DockWidgetPlugin
|
||||
, private EMotionFX::ActorInstanceNotificationBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
MCORE_MEMORYOBJECTCATEGORY(MorphTargetsWindowPlugin, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_STANDARDPLUGINS);
|
||||
@@ -54,6 +56,7 @@ namespace EMStudio
|
||||
EMStudioPlugin* Clone() override;
|
||||
|
||||
// update the morph targets window based on the current selection
|
||||
void ReInit(EMotionFX::ActorInstance* actorInstance, bool forceReInit = false);
|
||||
void ReInit(bool forceReInit = false);
|
||||
|
||||
// clear all widgets from the window
|
||||
@@ -70,6 +73,9 @@ namespace EMStudio
|
||||
void WindowReInit(bool visible);
|
||||
|
||||
private:
|
||||
// ActorInstanceNotificationBus overrides
|
||||
void OnActorInstanceDestroyed(EMotionFX::ActorInstance* actorInstance) override;
|
||||
|
||||
// declare the callbacks
|
||||
MCORE_DEFINECOMMANDCALLBACK(CommandSelectCallback);
|
||||
MCORE_DEFINECOMMANDCALLBACK(CommandUnselectCallback);
|
||||
|
||||
@@ -15,6 +15,7 @@ set(FILES
|
||||
Source/ActorBus.h
|
||||
Source/ActorInstance.cpp
|
||||
Source/ActorInstance.h
|
||||
Source/ActorInstanceBus.h
|
||||
Source/ActorManager.cpp
|
||||
Source/ActorManager.h
|
||||
Source/ActorUpdateScheduler.h
|
||||
|
||||
+9962
-10725
File diff suppressed because it is too large
Load Diff
@@ -360,6 +360,8 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
AzToolsFramework::ScopedUndoBatch undo("Update Entity With New SC Graph");
|
||||
AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId());
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user