Integrating latest 47acbe8
This commit is contained in:
+1
-1
@@ -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)
|
||||
{
|
||||
|
||||
+5
-13
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user