Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -32,7 +32,7 @@ namespace ScriptEvents
for (const auto& eventPair : m_ebus->m_events)
{
const auto* event = (eventPair.second.m_event != nullptr) ? eventPair.second.m_event : eventPair.second.m_broadcast;
auto* event = (eventPair.second.m_event != nullptr) ? eventPair.second.m_event : eventPair.second.m_broadcast;
if (event)
{
@@ -118,14 +118,9 @@ namespace ScriptEvents
if (functionIndex >= 0 && functionIndex < eventHandler->GetEvents().size())
{
const AZ::BehaviorEBusHandler::BusForwarderEvent& forwarderEvent = eventHandler->GetEvents()[functionIndex];
if (!forwarderEvent.m_function)
{
// Note, this may be OK if it happened in Script Canvas, we can't reasonably expect every event to be handled, I just need to be sure that
// if there is a handler node that we don't get this.
AZ_WarningOnce("Script Events", forwarderEvent.m_function, "Function %s not found for event: %s in script: %s - if needed, provide an implementation.", parameter.m_eventName.data(), m_scriptEventName.data(), eventHandler->GetScriptPath().c_str());
}
else
if (forwarderEvent.m_function)
{
// A handler function is installed, we will call it
Call(forwarderEvent, functionIndex, parameter);
}
}
@@ -140,12 +135,9 @@ namespace ScriptEvents
if (functionIndex >= 0 && functionIndex < eventHandler->GetEvents().size())
{
const AZ::BehaviorEBusHandler::BusForwarderEvent& forwarderEvent = eventHandler->GetEvents()[functionIndex];
if (!forwarderEvent.m_function)
{
AZ_WarningOnce("Script Events", forwarderEvent.m_function, "Function %s not found for event: %s in script: %s - if needed, provide an implementation.", parameter.m_eventName.data(), m_scriptEventName.data(), eventHandler->GetScriptPath().c_str());
}
else
if (forwarderEvent.m_function)
{
// A handler function is installed, we will call it
Call(forwarderEvent, functionIndex, parameter);
}
}
@@ -217,8 +209,8 @@ namespace ScriptEvents
if (functionIndex >= 0 && functionIndex < handler->GetEvents().size())
{
AZ::BehaviorEBusHandler::BusForwarderEvent forwarderEvent = handler->GetEvents()[functionIndex];
AZ_WarningOnce("Script Events", forwarderEvent.m_function, "Function %s not found for event: %s in script: %s - if needed, provide an implementation.", parameter.m_eventName.data(), m_scriptEventName.data(), handler->GetScriptPath().c_str());
// A handler function is installed, we will call it
if (forwarderEvent.m_function)
{
Call(forwarderEvent, functionIndex, parameter);
@@ -13,12 +13,14 @@
#include "precompiled.h"
#include "ScriptEvent.h"
#include "ScriptEventRegistration.h"
#include <ScriptEvents/ScriptEventsBus.h>
#include <ScriptEvents/ScriptEventFundamentalTypes.h>
#include <ScriptEvents/ScriptEventsAsset.h>
#include <ScriptEvents/Internal/BehaviorContextBinding/ScriptEventMethod.h>
#include <ScriptEvents/Internal/BehaviorContextBinding/ScriptEventBroadcast.h>
#include "ScriptEventDefinition.h"
namespace ScriptEvents
{
@@ -173,7 +175,7 @@ namespace ScriptEvents
return bus;
}
bool Utils::DestroyScriptEventBehaviorEBus(AZStd::string_view ebusName)
{
AZ::BehaviorContext* behaviorContext = nullptr;
@@ -199,130 +201,5 @@ namespace ScriptEvents
return erasedBus;
}
ScriptEvent::~ScriptEvent()
{
for (auto ebusPair : m_behaviorEBus)
{
Utils::DestroyScriptEventBehaviorEBus(ebusPair.second->m_name);
}
m_scriptEventBindings.clear();
}
void ScriptEvent::Init(AZ::Data::AssetId scriptEventAssetId)
{
AZ_Assert(scriptEventAssetId.IsValid(), "Script Event requires a valid Asset Id");
m_assetId = scriptEventAssetId;
AZ::Data::AssetBus::Handler::BusConnect(scriptEventAssetId);
auto asset = AZ::Data::AssetManager::Instance().FindAsset<ScriptEvents::ScriptEventsAsset>(m_assetId, AZ::Data::AssetLoadBehavior::Default);
if (asset && asset.IsReady())
{
CompleteRegistration(asset);
}
}
void ScriptEvent::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
CompleteRegistration(asset);
}
void ScriptEvent::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
CompleteRegistration(asset);
}
void ScriptEvent::CompleteRegistration(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
m_assetId = asset.GetId();
const ScriptEvents::ScriptEvent& definition = asset.GetAs<ScriptEvents::ScriptEventsAsset>()->m_definition;
if (m_behaviorEBus.find(definition.GetVersion()) != m_behaviorEBus.end())
{
return;
}
AZ::BehaviorContext* behaviorContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationBus::Events::GetBehaviorContext);
AZ_Assert(behaviorContext, "Script Events require a valid Behavior Context");
m_busName = definition.GetName();
auto behaviorEbusEntry = behaviorContext->m_ebuses.find(definition.GetBehaviorContextName());
if (behaviorEbusEntry != behaviorContext->m_ebuses.end())
{
m_behaviorEBus[definition.GetVersion()] = behaviorEbusEntry->second;
if (m_maxVersion < definition.GetVersion())
{
m_maxVersion = definition.GetVersion();
}
m_scriptEventBindings[m_assetId] = AZStd::make_unique<ScriptEventBinding>(behaviorContext, m_busName.c_str(), definition.GetAddressType());
ScriptEventNotificationBus::Broadcast(&ScriptEventNotifications::OnRegistered, definition);
return;
}
AZ::BehaviorEBus* bus = Utils::ConstructAndRegisterScriptEventBehaviorEBus(definition);
if (bus == nullptr)
{
return;
}
m_behaviorEBus[definition.GetVersion()] = bus;
if (m_maxVersion < definition.GetVersion())
{
m_maxVersion = definition.GetVersion();
}
AZ::BehaviorContextBus::Broadcast(&AZ::BehaviorContextBus::Events::OnAddEBus, m_busName.c_str(), bus);
m_scriptEventBindings[m_assetId] = AZStd::make_unique<ScriptEventBinding>(behaviorContext, m_busName.c_str(), definition.GetAddressType());
ScriptEventNotificationBus::Event(m_assetId, &ScriptEventNotifications::OnRegistered, definition);
asset.Release();
m_isReady = true;
}
bool ScriptEvent::GetMethod(AZStd::string_view eventName, AZ::BehaviorMethod*& outMethod)
{
AZ::BehaviorEBus* ebus = GetBehaviorBus();
AZ_Assert(ebus, "BehaviorEBus is invalid: %s", m_busName.c_str());
const auto& method = ebus->m_events.find(eventName);
if (method == ebus->m_events.end())
{
AZ_Error("Script Events", false, "No method by name of %s found in the script event: %s", eventName.data(), m_busName.c_str());
return false;
}
AZ::EBusAddressPolicy addressPolicy
= (ebus->m_idParam.m_typeId.IsNull() || ebus->m_idParam.m_typeId == AZ::AzTypeInfo<void>::Uuid())
? AZ::EBusAddressPolicy::Single
: AZ::EBusAddressPolicy::ById;
AZ::BehaviorMethod* behaviorMethod
= ebus->m_queueFunction
? (addressPolicy == AZ::EBusAddressPolicy::ById ? method->second.m_queueEvent : method->second.m_queueBroadcast)
: (addressPolicy == AZ::EBusAddressPolicy::ById ? method->second.m_event : method->second.m_broadcast);
if (!behaviorMethod)
{
AZ_Error("Script Canvas", false, "Queue function mismatch in %s-%s", eventName.data(), m_busName.c_str());
return false;
}
outMethod = behaviorMethod;
return true;
}
}
}
@@ -12,9 +12,15 @@
#pragma once
#include <AzCore/PlatformIncl.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include "ScriptEventsAsset.h"
#include <ScriptEvents/Internal/BehaviorContextBinding/BehaviorContextFactoryMethods.h>
#include <ScriptEvents/Internal/BehaviorContextBinding/ScriptEventBinding.h>
#include <ScriptEvents/Internal/VersionedProperty.h>
@@ -34,86 +40,5 @@ namespace ScriptEvents
static AZ::BehaviorEBus* ConstructAndRegisterScriptEventBehaviorEBus(const ScriptEvents::ScriptEvent& definition);
static bool DestroyScriptEventBehaviorEBus(AZStd::string_view ebusName);
};
//! This is the internal object that represents a ScriptEvent.
//! It provides the binding between the BehaviorContext and the messaging functionality.
//! It is ref counted so that it remains alive as long as anything is referencing it, this can happen
//! when multiple scripts or script canvas graphs are sending or receiving events defined in a given script event.
class ScriptEvent
: public AZ::Data::AssetBus::Handler
{
public:
AZ_RTTI(ScriptEvent, "{B8801400-65CD-49D5-B797-58E56D705A0A}");
AZ_CLASS_ALLOCATOR(ScriptEvent, AZ::SystemAllocator, 0);
AZ::AttributeArray* m_currentAttributes;
ScriptEvent() = default;
virtual ~ScriptEvent();
ScriptEvent(AZ::Data::AssetId scriptEventAssetId)
{
Init(scriptEventAssetId);
}
void Init(AZ::Data::AssetId scriptEventAssetId);
bool GetMethod(AZStd::string_view eventName, AZ::BehaviorMethod*& outMethod);
AZ::BehaviorEBus* GetBehaviorBus(AZ::u32 version = std::numeric_limits<AZ::u32>::max())
{
if (version == std::numeric_limits<AZ::u32>::max())
{
return m_behaviorEBus[m_maxVersion];
}
return m_behaviorEBus[version];
}
void CompleteRegistration(AZ::Data::Asset<AZ::Data::AssetData> asset);
AZStd::string GetBusName() const
{
return m_busName;
}
bool IsReady() const { return m_isReady; }
private:
AZ::u32 m_maxVersion = 0;
AZ::Data::AssetId m_assetId;
AZStd::string m_busName;
AZStd::unordered_map<AZ::u32, AZ::BehaviorEBus*> m_behaviorEBus; // version, ebus
AZStd::unordered_map<AZ::Data::AssetId, AZStd::unique_ptr<ScriptEventBinding>> m_scriptEventBindings;
bool m_isReady = false;
// AZ::Data::AssetBus::Handler
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
//
// Reference count for intrusive_ptr
template<class T>
friend struct AZStd::IntrusivePtrCountPolicy;
mutable unsigned int m_refCount = 0;
AZ_FORCE_INLINE void add_ref() { ++m_refCount; }
AZ_FORCE_INLINE void release()
{
AZ_Assert(m_refCount > 0, "Reference count logic error, trying to release reference when there are none left.");
if (--m_refCount == 0)
{
AZ::Data::AssetBus::Handler::BusDisconnect();
delete this;
}
}
AZStd::string m_previousName;
int m_previousVersion;
};
}
}
@@ -0,0 +1,163 @@
/*
* 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 "precompiled.h"
#include "ScriptEventRegistration.h"
#include "ScriptEvent.h"
#include "ScriptEventsBus.h"
namespace ScriptEvents
{
namespace Internal
{
ScriptEventRegistration::~ScriptEventRegistration()
{
for (auto ebusPair : m_behaviorEBus)
{
Utils::DestroyScriptEventBehaviorEBus(ebusPair.second->m_name);
}
m_scriptEventBindings.clear();
AZ::SystemTickBus::Handler::BusDisconnect();
}
void ScriptEventRegistration::Init(AZ::Data::AssetId scriptEventAssetId)
{
AZ_Assert(scriptEventAssetId.IsValid(), "Script Event requires a valid Asset Id");
m_assetId = scriptEventAssetId;
AZ::Data::AssetBus::Handler::BusConnect(scriptEventAssetId);
m_asset = AZ::Data::AssetManager::Instance().FindAsset<ScriptEvents::ScriptEventsAsset>(m_assetId, AZ::Data::AssetLoadBehavior::PreLoad);
if (m_asset && m_asset.IsReady())
{
CompleteRegistration(m_asset);
}
}
void ScriptEventRegistration::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
m_asset = asset;
AZ::SystemTickBus::Handler::BusConnect();
}
void ScriptEventRegistration::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
m_asset = asset;
AZ::SystemTickBus::Handler::BusConnect();
}
void ScriptEventRegistration::OnSystemTick()
{
AZ::SystemTickBus::Handler::BusDisconnect();
CompleteRegistration(m_asset);
}
void ScriptEventRegistration::CompleteRegistration(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
OnScopeEnd clearAsset([&]() { this->m_asset = {}; });
if (!asset)
{
return;
}
m_assetId = asset.GetId();
const ScriptEvents::ScriptEvent& definition = asset.GetAs<ScriptEvents::ScriptEventsAsset>()->m_definition;
if (m_behaviorEBus.find(definition.GetVersion()) != m_behaviorEBus.end())
{
return;
}
AZ::BehaviorContext* behaviorContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationBus::Events::GetBehaviorContext);
AZ_Assert(behaviorContext, "Script Events require a valid Behavior Context");
m_busName = definition.GetName();
auto behaviorEbusEntry = behaviorContext->m_ebuses.find(definition.GetBehaviorContextName());
if (behaviorEbusEntry != behaviorContext->m_ebuses.end())
{
m_behaviorEBus[definition.GetVersion()] = behaviorEbusEntry->second;
if (m_maxVersion < definition.GetVersion())
{
m_maxVersion = definition.GetVersion();
}
m_scriptEventBindings[m_assetId] = AZStd::make_unique<ScriptEventBinding>(behaviorContext, m_busName.c_str(), definition.GetAddressType());
ScriptEventNotificationBus::Broadcast(&ScriptEventNotifications::OnRegistered, definition);
return;
}
AZ::BehaviorEBus* bus = Utils::ConstructAndRegisterScriptEventBehaviorEBus(definition);
if (bus == nullptr)
{
return;
}
m_behaviorEBus[definition.GetVersion()] = bus;
if (m_maxVersion < definition.GetVersion())
{
m_maxVersion = definition.GetVersion();
}
AZ::BehaviorContextBus::Broadcast(&AZ::BehaviorContextBus::Events::OnAddEBus, m_busName.c_str(), bus);
m_scriptEventBindings[m_assetId] = AZStd::make_unique<ScriptEventBinding>(behaviorContext, m_busName.c_str(), definition.GetAddressType());
ScriptEventNotificationBus::Event(m_assetId, &ScriptEventNotifications::OnRegistered, definition);
m_isReady = true;
}
bool ScriptEventRegistration::GetMethod(AZStd::string_view eventName, AZ::BehaviorMethod*& outMethod)
{
AZ::BehaviorEBus* ebus = GetBehaviorBus();
AZ_Assert(ebus, "BehaviorEBus is invalid: %s", m_busName.c_str());
const auto& method = ebus->m_events.find(eventName);
if (method == ebus->m_events.end())
{
AZ_Error("Script Events", false, "No method by name of %s found in the script event: %s", eventName.data(), m_busName.c_str());
return false;
}
AZ::EBusAddressPolicy addressPolicy
= (ebus->m_idParam.m_typeId.IsNull() || ebus->m_idParam.m_typeId == AZ::AzTypeInfo<void>::Uuid())
? AZ::EBusAddressPolicy::Single
: AZ::EBusAddressPolicy::ById;
AZ::BehaviorMethod* behaviorMethod
= ebus->m_queueFunction
? (addressPolicy == AZ::EBusAddressPolicy::ById ? method->second.m_queueEvent : method->second.m_queueBroadcast)
: (addressPolicy == AZ::EBusAddressPolicy::ById ? method->second.m_event : method->second.m_broadcast);
if (!behaviorMethod)
{
AZ_Error("Script Canvas", false, "Queue function mismatch in %s-%s", eventName.data(), m_busName.c_str());
return false;
}
outMethod = behaviorMethod;
return true;
}
}
}
@@ -0,0 +1,137 @@
/*
* 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/Component/TickBus.h>
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <ScriptEvents/Internal/BehaviorContextBinding/ScriptEventBinding.h>
#include "ScriptEventsAsset.h"
namespace ScriptEvents
{
namespace Internal
{
//! This is the internal object that represents a ScriptEvent.
//! It provides the binding between the BehaviorContext and the messaging functionality.
//! It is ref counted so that it remains alive as long as anything is referencing it, this can happen
//! when multiple scripts or script canvas graphs are sending or receiving events defined in a given script event.
class ScriptEventRegistration
: public AZ::Data::AssetBus::Handler
, public AZ::SystemTickBus::Handler
{
public:
AZ_RTTI(ScriptEventRegistration, "{B8801400-65CD-49D5-B797-58E56D705A0A}");
AZ_CLASS_ALLOCATOR(ScriptEventRegistration, AZ::SystemAllocator, 0);
AZ::AttributeArray* m_currentAttributes;
ScriptEventRegistration() = default;
virtual ~ScriptEventRegistration();
ScriptEventRegistration(AZ::Data::AssetId scriptEventAssetId)
{
Init(scriptEventAssetId);
}
void Init(AZ::Data::AssetId scriptEventAssetId);
bool GetMethod(AZStd::string_view eventName, AZ::BehaviorMethod*& outMethod);
AZ::BehaviorEBus* GetBehaviorBus(AZ::u32 version = (std::numeric_limits<AZ::u32>::max)())
{
if (version == (std::numeric_limits<AZ::u32>::max)())
{
return m_behaviorEBus[m_maxVersion];
}
return m_behaviorEBus[version];
}
void CompleteRegistration(AZ::Data::Asset<AZ::Data::AssetData> asset);
AZStd::string GetBusName() const
{
return m_busName;
}
bool IsReady() const { return m_isReady; }
protected:
void OnSystemTick() override;
private:
AZ::u32 m_maxVersion = 0;
AZ::Data::AssetId m_assetId;
AZStd::string m_busName;
AZStd::unordered_map<AZ::u32, AZ::BehaviorEBus*> m_behaviorEBus; // version, ebus
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> m_asset;
AZStd::unordered_map<AZ::Data::AssetId, AZStd::unique_ptr<ScriptEventBinding>> m_scriptEventBindings;
bool m_isReady = false;
// AZ::Data::AssetBus::Handler
void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
void OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
//
// Reference count for intrusive_ptr
template<class T>
friend struct AZStd::IntrusivePtrCountPolicy;
mutable unsigned int m_refCount = 0;
AZ_FORCE_INLINE void add_ref() { ++m_refCount; }
AZ_FORCE_INLINE void release()
{
AZ_Assert(m_refCount > 0, "Reference count logic error, trying to release reference when there are none left.");
if (--m_refCount == 0)
{
AZ::Data::AssetBus::Handler::BusDisconnect();
delete this;
}
}
AZStd::string m_previousName;
int m_previousVersion;
};
class OnScopeEnd
{
public:
using ScopeEndFunctor = std::function<void()>;
private:
ScopeEndFunctor m_functor;
public:
OnScopeEnd(ScopeEndFunctor&& functor)
: m_functor(AZStd::move(functor))
{}
OnScopeEnd(const ScopeEndFunctor& functor)
: m_functor(functor)
{}
~OnScopeEnd()
{
m_functor();
}
};
}
}
@@ -14,10 +14,11 @@
#include "ScriptEventSystem.h"
#include "ScriptEventDefinition.h"
#include "ScriptEventsAsset.h"
#include "ScriptEvent.h"
namespace ScriptEvents
{
AZStd::intrusive_ptr<Internal::ScriptEvent> ScriptEventsSystemComponentImpl::RegisterScriptEvent(const AZ::Data::AssetId& assetId, [[maybe_unused]] AZ::u32 version)
AZStd::intrusive_ptr<Internal::ScriptEventRegistration> ScriptEventsSystemComponentImpl::RegisterScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 /*version*/)
{
AZ_Assert(assetId.IsValid(), "Unable to register Script Event with invalid asset Id");
if (!assetId.IsValid())
@@ -29,7 +30,7 @@ namespace ScriptEvents
if (m_scriptEvents.find(key) == m_scriptEvents.end())
{
m_scriptEvents[key] = AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEvent>(aznew ScriptEvents::Internal::ScriptEvent(assetId));
m_scriptEvents[key] = AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEventRegistration>(aznew ScriptEvents::Internal::ScriptEventRegistration(assetId));
}
return m_scriptEvents[key];
@@ -55,13 +56,13 @@ namespace ScriptEvents
if (m_scriptEvents.find(key) == m_scriptEvents.end())
{
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> assetData = AZ::Data::AssetManager::Instance().CreateAsset<ScriptEvents::ScriptEventsAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> assetData = AZ::Data::AssetManager::Instance().CreateAsset<ScriptEvents::ScriptEventsAsset>(assetId);
// Install the definition that's coming from Lua
ScriptEvents::ScriptEventsAsset* scriptAsset = assetData.Get();
scriptAsset->m_definition = definition;
m_scriptEvents[key] = AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEvent>(aznew ScriptEvents::Internal::ScriptEvent(assetId));
m_scriptEvents[key] = AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEventRegistration>(aznew ScriptEvents::Internal::ScriptEventRegistration(assetId));
m_scriptEvents[key]->CompleteRegistration(assetData);
}
@@ -72,14 +73,14 @@ namespace ScriptEvents
const AZStd::string& busName = definition.GetName();
const AZ::Uuid& assetId = AZ::Uuid::CreateName(busName.c_str());
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> assetData = AZ::Data::AssetManager::Instance().FindAsset<ScriptEvents::ScriptEventsAsset>(assetId, AZ::Data::AssetLoadBehavior::Default);
AZ::Data::Asset<ScriptEvents::ScriptEventsAsset> assetData = AZ::Data::AssetManager::Instance().FindAsset<ScriptEvents::ScriptEventsAsset>(assetId, AZ::Data::AssetLoadBehavior::PreLoad);
if (assetData)
{
assetData.Release();
}
}
AZStd::intrusive_ptr<Internal::ScriptEvent> ScriptEventsSystemComponentImpl::GetScriptEvent(const AZ::Data::AssetId& assetId, [[maybe_unused]] AZ::u32 version)
AZStd::intrusive_ptr<Internal::ScriptEventRegistration> ScriptEventsSystemComponentImpl::GetScriptEvent(const AZ::Data::AssetId& assetId, [[maybe_unused]] AZ::u32 version)
{
ScriptEventKey key(assetId, 0);
@@ -13,6 +13,7 @@
#pragma once
#include "ScriptEventsBus.h"
#include "ScriptEvent.h"
namespace ScriptEvents
{
@@ -37,17 +38,17 @@ namespace ScriptEvents
////////////////////////////////////////////////////////////////////////
// ScriptEvents::ScriptEventBus::Handler
AZStd::intrusive_ptr<Internal::ScriptEvent> RegisterScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) override;
AZStd::intrusive_ptr<Internal::ScriptEventRegistration> RegisterScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) override;
void RegisterScriptEventFromDefinition(const ScriptEvents::ScriptEvent& definition) override;
void UnregisterScriptEventFromDefinition(const ScriptEvents::ScriptEvent& definition) override;
AZStd::intrusive_ptr<Internal::ScriptEvent> GetScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) override;
AZStd::intrusive_ptr<Internal::ScriptEventRegistration> GetScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) override;
const FundamentalTypes* GetFundamentalTypes() override;
////////////////////////////////////////////////////////////////////////
private:
// Script Event Assets
AZStd::unordered_map<ScriptEventKey, AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEvent>> m_scriptEvents;
AZStd::unordered_map<ScriptEventKey, AZStd::intrusive_ptr<ScriptEvents::Internal::ScriptEventRegistration>> m_scriptEvents;
FundamentalTypes m_fundamentalTypes;
@@ -0,0 +1,38 @@
/*
* 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 "precompiled.h"
#include "ScriptEventsAsset.h"
#include "ScriptEventDefinition.h"
#include "ScriptEventsBus.h"
namespace ScriptEvents
{
void ScriptEventAssetRuntimeHandler::InitAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset, bool loadStageSucceeded, bool isReload)
{
AssetHandler::InitAsset(asset, loadStageSucceeded, isReload);
if (loadStageSucceeded && !isReload)
{
const ScriptEvents::ScriptEvent& definition = asset.GetAs<ScriptEventsAsset>()->m_definition;
AZStd::intrusive_ptr<Internal::ScriptEventRegistration> scriptEvent;
ScriptEvents::ScriptEventBus::BroadcastResult(scriptEvent, &ScriptEvents::ScriptEventRequests::RegisterScriptEvent, asset.GetId(), definition.GetVersion());
}
}
ScriptEventAssetRuntimeHandler::ScriptEventAssetRuntimeHandler(const char* displayName, const char* group, const char* extension, const AZ::Uuid& componentTypeId /*= AZ::Uuid::CreateNull()*/, AZ::SerializeContext* serializeContext /*= nullptr*/)
: AzFramework::GenericAssetHandler<ScriptEventsAsset>(displayName, group, extension, componentTypeId, serializeContext)
{}
}
@@ -15,16 +15,19 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Script/ScriptAsset.h>
#include <AzCore/Script/ScriptContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Asset/GenericAssetHandler.h>
#include <AzFramework/Asset/SimpleAsset.h>
#include "ScriptEventDefinition.h"
#include <AzFramework/Asset/GenericAssetHandler.h>
#include "ScriptEventsBus.h"
#include "ScriptEvent.h"
namespace ScriptEventAsset
{
constexpr const char* k_RuntimeAssetIdStr = "{CB4D603E-8CB0-4D80-8165-4244F28AF187}";
}
namespace ScriptEvents
{
@@ -33,7 +36,7 @@ namespace ScriptEvents
{
public:
AZ_RTTI(ScriptEventsAsset, "{CB4D603E-8CB0-4D80-8165-4244F28AF187}", AZ::Data::AssetData);
AZ_RTTI(ScriptEventsAsset, ScriptEventAsset::k_RuntimeAssetIdStr, AZ::Data::AssetData);
AZ_CLASS_ALLOCATOR(ScriptEventsAsset, AZ::SystemAllocator, 0);
ScriptEventsAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId(), AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
@@ -50,8 +53,7 @@ namespace ScriptEvents
static const char* GetDisplayName() { return "Script Events"; }
static const char* GetGroup() { return "ScriptEvents"; }
static const char* GetFileFilter() { return "*.scriptevents"; }
static const char* GetFileExtension() { return ".scriptevents"; }
static const char* GetFileFilter() { return "scriptevents"; }
AZ::Crc32 GetBusId() const { return AZ::Crc32(GetId().ToString<AZStd::string>().c_str()); }
@@ -88,7 +90,7 @@ namespace ScriptEvents
AZ_RTTI(ScriptEventsAssetPtr, "{CE2C30CB-709B-4BC0-BAEE-3D192D33367D}", BaseType);
AZ_CLASS_ALLOCATOR(ScriptEventsAssetPtr, AZ::SystemAllocator, 0);
ScriptEventsAssetPtr(AZ::Data::AssetLoadBehavior loadBehavior = AZ::Data::AssetLoadBehavior::PreLoad)
explicit ScriptEventsAssetPtr(AZ::Data::AssetLoadBehavior loadBehavior = AZ::Data::AssetLoadBehavior::PreLoad)
: AZ::Data::Asset<ScriptEventsAsset>(loadBehavior)
{}
@@ -117,38 +119,9 @@ namespace ScriptEvents
public:
AZ_RTTI(ScriptEventAssetRuntimeHandler, "{002E913D-339A-4238-BCCD-ED077BBD72C5}", AzFramework::GenericAssetHandler<ScriptEventsAsset>);
ScriptEventAssetRuntimeHandler(const char* displayName, const char* group, const char* extension, const AZ::Uuid& componentTypeId = AZ::Uuid::CreateNull(), AZ::SerializeContext* serializeContext = nullptr)
: AzFramework::GenericAssetHandler<ScriptEventsAsset>(displayName, group, extension, componentTypeId, serializeContext)
{
}
using AzFramework::GenericAssetHandler<ScriptEventsAsset>::LoadAssetData;
AZ::Data::AssetHandler::LoadResult LoadAssetData(
const AZ::Data::Asset<AZ::Data::AssetData>& asset,
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
const AZ::Data::AssetFilterCB& assetLoadFilterCB) override
{
if (AzFramework::GenericAssetHandler<ScriptEventsAsset>::LoadAssetData(asset, stream, assetLoadFilterCB) ==
AZ::Data::AssetHandler::LoadResult::LoadComplete)
{
// Queue the registration against the AssetBus to be run on the main thread
// This avoids the following deadlock situation by moving RegisterScriptEvent to the main thread only:
// JobThread: LoadAssetData -> lock ScriptEventBus -> lock AssetBus
// MainThread: lock AssetBus OnAssetReady -> LoadAssetData -> ...
AZ::Data::AssetBus::QueueFunction([asset]()
{
const ScriptEvents::ScriptEvent& definition = asset.GetAs<ScriptEventsAsset>()->m_definition;
AZStd::intrusive_ptr<Internal::ScriptEvent> scriptEvent;
ScriptEvents::ScriptEventBus::BroadcastResult(scriptEvent, &ScriptEvents::ScriptEventRequests::RegisterScriptEvent, asset.GetId(), definition.GetVersion());
});
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
}
return AZ::Data::AssetHandler::LoadResult::Error;
}
ScriptEventAssetRuntimeHandler(const char* displayName, const char* group, const char* extension, const AZ::Uuid& componentTypeId = AZ::Uuid::CreateNull(), AZ::SerializeContext* serializeContext = nullptr);
void InitAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset, bool loadStageSucceeded, bool isReload) override;
};
}
@@ -27,7 +27,6 @@
namespace ScriptEvents
{
class ScriptEventsAsset;
/**
* Provides script bindings to expose Script Event assets as script property.
@@ -16,27 +16,32 @@
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
#include <AzCore/std/string/string.h>
#include <ScriptEvents/ScriptEvent.h>
#include <ScriptEvents/ScriptEventFundamentalTypes.h>
#include "ScriptEventRegistration.h"
namespace ScriptEvents
{
class ScriptEvent;
class ScriptEventsHandler;
namespace Internal
{
class ScriptEventRegistration;
}
//! External facing API for registering and getting ScriptEvents
class ScriptEventRequests : public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
typedef AZStd::recursive_mutex MutexType;
virtual AZStd::intrusive_ptr<Internal::ScriptEvent> RegisterScriptEvent([[maybe_unused]] const AZ::Data::AssetId& assetId, [[maybe_unused]] AZ::u32 version) { return nullptr; }
using MutexType = AZStd::recursive_mutex;
virtual AZStd::intrusive_ptr<Internal::ScriptEventRegistration> RegisterScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) = 0;
virtual void RegisterScriptEventFromDefinition([[maybe_unused]] const ScriptEvent& definition) {}
virtual void UnregisterScriptEventFromDefinition([[maybe_unused]] const ScriptEvent& definition) {}
virtual AZStd::intrusive_ptr<Internal::ScriptEvent> GetScriptEvent([[maybe_unused]] const AZ::Data::AssetId& assetId, [[maybe_unused]] AZ::u32 version) { return {}; }
virtual AZStd::intrusive_ptr<Internal::ScriptEventRegistration> GetScriptEvent(const AZ::Data::AssetId& assetId, AZ::u32 version) = 0;
virtual const FundamentalTypes* GetFundamentalTypes() = 0;
};