Added Hydra API to extract all the classes, globals and EBuses exposed (#4953)
* Added Hydra API to extract all the classes, globals and EBuses exposed to lua: azlmbr.script.LuaSymbolsReporterBus: GetListOfClasses GetListOfGlobalProperties GetListOfGlobalFunctions GetListOfEBuses Also exposed to Hydra the classes that can be used to dump the symbols azlmbr.script.LuaPropertySymbol azlmbr.script.LuaMethodSymbol azlmbr.script.LuaClassSymbol azlmbr.script.LuaEBusSender azlmbr.script.LuaEBusSymbol The python file Assets/Editor/Scripts/lua_symbols.py can be used with "pyRunFile <script_name> [output.txt]" to create Game/output.txt will all the symbols OR passing up to three additional arguments "c" or "g" or "e" to dump only classes, globals or ebuses or a combination of those. Example: To create an output file with only classes and Ebuses: "pyRunFile <script_name> [output.txt] c e" Signed-off-by: garrieta <garrieta@amazon.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Script
|
||||
{
|
||||
struct LuaPropertySymbol
|
||||
{
|
||||
AZ_TYPE_INFO(LuaPropertySymbol, "{5AFB147F-50A4-4F00-9F82-D8D5BBC970D6}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
bool m_canRead;
|
||||
bool m_canWrite;
|
||||
|
||||
AZStd::string ToString() const;
|
||||
};
|
||||
|
||||
struct LuaMethodSymbol
|
||||
{
|
||||
AZ_TYPE_INFO(LuaMethodSymbol, "{7B074A36-C81D-46A0-8D2F-62E426EBE38A}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_debugArgumentInfo;
|
||||
|
||||
AZStd::string ToString() const;
|
||||
};
|
||||
|
||||
struct LuaClassSymbol
|
||||
{
|
||||
AZ_TYPE_INFO(LuaClassSymbol, "{5FBE5841-A8E1-44B6-BEDA-22302CF8DF5F}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
AZ::Uuid m_typeId;
|
||||
AZStd::vector<LuaPropertySymbol> m_properties;
|
||||
AZStd::vector<LuaMethodSymbol> m_methods;
|
||||
|
||||
AZStd::string ToString() const;
|
||||
};
|
||||
|
||||
struct LuaEBusSender
|
||||
{
|
||||
AZ_TYPE_INFO(LuaEBusSender, "{23EE4188-0924-49DB-BF3F-EB7AAB6D5E5C}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
AZStd::string m_debugArgumentInfo;
|
||||
AZStd::string m_category;
|
||||
|
||||
AZStd::string ToString() const;
|
||||
};
|
||||
|
||||
struct LuaEBusSymbol
|
||||
{
|
||||
AZ_TYPE_INFO(LuaEBusSymbol, "{381C5639-A916-4D2E-B825-50A3F2D93137}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
bool m_canBroadcast;
|
||||
bool m_canQueue;
|
||||
bool m_hasHandler;
|
||||
|
||||
AZStd::vector<LuaEBusSender> m_senders;
|
||||
|
||||
AZStd::string ToString() const;
|
||||
};
|
||||
|
||||
// This is an EBus useful to scrape classes, globals and EBuses exposed to game scripting
|
||||
// e.g: Lua.
|
||||
class LuaSymbolsReporterRequests
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(LuaSymbolsReporterRequests, "{3FF9A105-3159-49FF-8DC6-4948AE7B4AB8}");
|
||||
virtual ~LuaSymbolsReporterRequests() = default;
|
||||
// Put your public methods here
|
||||
|
||||
virtual const AZStd::vector<LuaClassSymbol>& GetListOfClasses() = 0;
|
||||
virtual const AZStd::vector<LuaPropertySymbol>& GetListOfGlobalProperties() = 0;
|
||||
virtual const AZStd::vector<LuaMethodSymbol>& GetListOfGlobalFunctions() = 0;
|
||||
virtual const AZStd::vector<LuaEBusSymbol>& GetListOfEBuses() = 0;
|
||||
|
||||
};
|
||||
|
||||
class LuaSymbolsReporterBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
using LuaSymbolsReporterRequestBus = AZ::EBus<LuaSymbolsReporterRequests, LuaSymbolsReporterBusTraits>;
|
||||
|
||||
} // namespace Script
|
||||
} // namespace AzToolsFramework
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Script/ScriptContextDebug.h>
|
||||
|
||||
#include "LuaSymbolsReporterSystemComponent.h"
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Script
|
||||
{
|
||||
AZStd::string LuaPropertySymbol::ToString() const
|
||||
{
|
||||
return AZStd::string::format("%s [%s/%s]",
|
||||
m_name.c_str(),
|
||||
m_canRead ? "R" : "_",
|
||||
m_canWrite ? "W" : "_");
|
||||
}
|
||||
|
||||
void LuaPropertySymbol::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<LuaPropertySymbol>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Property("name", BehaviorValueProperty(&LuaPropertySymbol::m_name))
|
||||
->Property("canRead", BehaviorValueProperty(&LuaPropertySymbol::m_canRead))
|
||||
->Property("canWrite", BehaviorValueProperty(&LuaPropertySymbol::m_canWrite))
|
||||
->Method("ToString", &LuaPropertySymbol::ToString)
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string LuaMethodSymbol::ToString() const
|
||||
{
|
||||
return AZStd::string::format("%s(%s)", m_name.c_str(), m_debugArgumentInfo.c_str());
|
||||
}
|
||||
|
||||
void LuaMethodSymbol::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<LuaMethodSymbol>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Property("name", BehaviorValueProperty(&LuaMethodSymbol::m_name))
|
||||
->Property("debugArgumentInfo", BehaviorValueProperty(&LuaMethodSymbol::m_debugArgumentInfo))
|
||||
->Method("ToString", &LuaMethodSymbol::ToString)
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string LuaClassSymbol::ToString() const
|
||||
{
|
||||
return AZStd::string::format("%s [%s]", m_name.c_str(), m_typeId.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
|
||||
void LuaClassSymbol::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<LuaClassSymbol>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Property("name", BehaviorValueProperty(&LuaClassSymbol::m_name))
|
||||
->Property("typeId", BehaviorValueProperty(&LuaClassSymbol::m_typeId))
|
||||
->Property("properties", BehaviorValueProperty(&LuaClassSymbol::m_properties))
|
||||
->Property("methods", BehaviorValueProperty(&LuaClassSymbol::m_methods))
|
||||
->Method("ToString", &LuaClassSymbol::ToString)
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string LuaEBusSender::ToString() const
|
||||
{
|
||||
return AZStd::string::format("%s(%s) - [%s]", m_name.c_str(), m_debugArgumentInfo.c_str(), m_category.c_str());
|
||||
}
|
||||
|
||||
void LuaEBusSender::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<LuaEBusSender>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Property("name", BehaviorValueProperty(&LuaEBusSender::m_name))
|
||||
->Property("debugArgumentInfo", BehaviorValueProperty(&LuaEBusSender::m_debugArgumentInfo))
|
||||
->Property("category", BehaviorValueProperty(&LuaEBusSender::m_category))
|
||||
->Method("ToString", &LuaEBusSender::ToString)
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::string LuaEBusSymbol::ToString() const
|
||||
{
|
||||
auto boolToStr = +[](bool val) { return val ? "true" : "false"; };
|
||||
return AZStd::string::format("%s: canBroadcast(%s), canQueue(%s), hasHandler(%s)",
|
||||
m_name.c_str(),
|
||||
boolToStr(m_canBroadcast), boolToStr(m_canQueue), boolToStr(m_hasHandler));
|
||||
}
|
||||
|
||||
void LuaEBusSymbol::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<LuaEBusSymbol>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Property("name", BehaviorValueProperty(&LuaEBusSymbol::m_name))
|
||||
->Property("canBroadcast", BehaviorValueProperty(&LuaEBusSymbol::m_canBroadcast))
|
||||
->Property("canQueue", BehaviorValueProperty(&LuaEBusSymbol::m_canQueue))
|
||||
->Property("hasHandler", BehaviorValueProperty(&LuaEBusSymbol::m_hasHandler))
|
||||
->Property("senders", BehaviorValueProperty(&LuaEBusSymbol::m_senders))
|
||||
->Method("ToString", &LuaEBusSymbol::ToString)
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
//! This local class helps us keeping private the sensitive data in LuaSymbolsReporterSystemComponent
|
||||
//! Used inside the function pointers for several AZ::SciptContextDebug::Enumerate* functions.
|
||||
class IntrusiveHelper
|
||||
{
|
||||
public:
|
||||
static AZStd::vector<LuaClassSymbol>& GetClassSymbols(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_cachedClassSymbols; }
|
||||
static AZStd::unordered_map<AZ::Uuid, size_t>& GetClassUuidToIndexMap(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_classUuidToIndexMap; }
|
||||
static AZStd::vector<LuaPropertySymbol>& GetGlobalPropertySymbols(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_cachedGlobalPropertySymbols; }
|
||||
static AZStd::vector<LuaMethodSymbol>& GetGlobalFunctionSymbols(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_cachedGlobalFunctionSymbols; }
|
||||
static AZStd::vector<LuaEBusSymbol>& GetEBusSymbols(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_cachedEbusSymbols; }
|
||||
static AZStd::unordered_map<AZStd::string, size_t>& GetEBusNameToIndexMap(LuaSymbolsReporterSystemComponent& symbolsReporter) { return symbolsReporter.m_ebusNameToIndexMap; }
|
||||
};
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
LuaPropertySymbol::Reflect(context);
|
||||
LuaMethodSymbol::Reflect(context);
|
||||
LuaClassSymbol::Reflect(context);
|
||||
LuaEBusSender::Reflect(context);
|
||||
LuaEBusSymbol::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<LuaSymbolsReporterSystemComponent, AZ::Component>()
|
||||
->Version(0);
|
||||
|
||||
serializeContext->RegisterGenericType<AZStd::vector<LuaPropertySymbol>>();
|
||||
serializeContext->RegisterGenericType<AZStd::vector<LuaMethodSymbol>>();
|
||||
serializeContext->RegisterGenericType<AZStd::vector<LuaClassSymbol>>();
|
||||
serializeContext->RegisterGenericType<AZStd::vector<LuaEBusSender>>();
|
||||
serializeContext->RegisterGenericType<AZStd::vector<LuaEBusSymbol>>();
|
||||
}
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<LuaSymbolsReporterRequestBus>("LuaSymbolsReporterBus")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
|
||||
->Attribute(AZ::Script::Attributes::Module, "script")
|
||||
->Event("GetListOfClasses", &LuaSymbolsReporterRequests::GetListOfClasses)
|
||||
->Event("GetListOfGlobalProperties", &LuaSymbolsReporterRequests::GetListOfGlobalProperties)
|
||||
->Event("GetListOfGlobalFunctions", &LuaSymbolsReporterRequests::GetListOfGlobalFunctions)
|
||||
->Event("GetListOfEBuses", &LuaSymbolsReporterRequests::GetListOfEBuses)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC_CE("LuaSymbolsReporterSystemService"));
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("LuaSymbolsReporterSystemService"));
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC_CE("ScriptService"));
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
// No dependent services.
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::Activate()
|
||||
{
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusConnect();
|
||||
LuaSymbolsReporterRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::Deactivate()
|
||||
{
|
||||
LuaSymbolsReporterRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZ::ScriptContext* LuaSymbolsReporterSystemComponent::InitScriptContext()
|
||||
{
|
||||
if (m_scriptContext)
|
||||
{
|
||||
return m_scriptContext;
|
||||
}
|
||||
|
||||
AZ::ScriptSystemRequestBus::BroadcastResult(m_scriptContext, &AZ::ScriptSystemRequests::GetContext, AZ::ScriptContextIds::DefaultScriptContextId);
|
||||
return m_scriptContext;
|
||||
}
|
||||
|
||||
void LuaSymbolsReporterSystemComponent::LoadGlobalSymbols()
|
||||
{
|
||||
auto scriptContext = InitScriptContext();
|
||||
if (!scriptContext)
|
||||
{
|
||||
AZ_Error(LogName, false, "Invalid scriptContext");
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext->EnableDebug();
|
||||
|
||||
auto debugContext = scriptContext->GetDebugContext();
|
||||
if (!debugContext)
|
||||
{
|
||||
AZ_Error(LogName, false, "Invalid debugContext from scriptContext");
|
||||
return;
|
||||
}
|
||||
|
||||
auto enumMethodFunc = +[]([[maybe_unused]] const AZ::Uuid* classTypeId, const char* methodName, const char* debugArgumentInfo, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
auto& methodSymbols = IntrusiveHelper::GetGlobalFunctionSymbols(mySelf);
|
||||
methodSymbols.push_back({});
|
||||
auto& methodSymbol = methodSymbols.back();
|
||||
methodSymbol.m_name = methodName;
|
||||
if (debugArgumentInfo)
|
||||
{
|
||||
methodSymbol.m_debugArgumentInfo = debugArgumentInfo;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto enumPropertyFunc = +[]([[maybe_unused]] const AZ::Uuid* classTypeId, const char* propertyName, bool canRead, bool canWrite, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
auto& propertySymbols = IntrusiveHelper::GetGlobalPropertySymbols(mySelf);
|
||||
propertySymbols.push_back({});
|
||||
auto& propertySymbol = propertySymbols.back();
|
||||
propertySymbol.m_name = propertyName;
|
||||
propertySymbol.m_canRead = canRead;
|
||||
propertySymbol.m_canWrite = canWrite;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
debugContext->EnumRegisteredGlobals(enumMethodFunc, enumPropertyFunc, this);
|
||||
|
||||
scriptContext->DisableDebug();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// LuaSymbolsReporterRequestBus::Handler
|
||||
const AZStd::vector<LuaClassSymbol>& LuaSymbolsReporterSystemComponent::GetListOfClasses()
|
||||
{
|
||||
if (!m_cachedClassSymbols.empty())
|
||||
{
|
||||
return m_cachedClassSymbols;
|
||||
}
|
||||
|
||||
auto scriptContext = InitScriptContext();
|
||||
if (!scriptContext)
|
||||
{
|
||||
return m_cachedClassSymbols;
|
||||
}
|
||||
|
||||
scriptContext->EnableDebug();
|
||||
|
||||
auto debugContext = scriptContext->GetDebugContext();
|
||||
if (!debugContext)
|
||||
{
|
||||
return m_cachedClassSymbols;
|
||||
}
|
||||
|
||||
auto enumClassFunc = +[](const char* className, const AZ::Uuid& classTypeId, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
|
||||
auto& classSymbols = IntrusiveHelper::GetClassSymbols(mySelf);
|
||||
classSymbols.push_back({});
|
||||
auto& classSymbol = classSymbols.back();
|
||||
classSymbol.m_name = className;
|
||||
classSymbol.m_typeId = classTypeId;
|
||||
|
||||
auto& uuidToClassMap = IntrusiveHelper::GetClassUuidToIndexMap(mySelf);
|
||||
uuidToClassMap.emplace(classTypeId, classSymbols.size() - 1);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto enumMethodFunc = +[](const AZ::Uuid* classTypeId, const char* methodName, const char* debugArgumentInfo, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
auto& classUuidToIndexMap = IntrusiveHelper::GetClassUuidToIndexMap(mySelf);
|
||||
auto itor = classUuidToIndexMap.find(*classTypeId);
|
||||
if (itor == classUuidToIndexMap.end())
|
||||
{
|
||||
AZ_Error(LogName, false, "Can not add method [%s] because class uuid [%s] is not registered", methodName, classTypeId->ToString<AZStd::string>().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto classIndex = itor->second;
|
||||
auto& classSymbols = IntrusiveHelper::GetClassSymbols(mySelf);
|
||||
auto& classSymbol = classSymbols[classIndex];
|
||||
classSymbol.m_methods.push_back({});
|
||||
auto& methodSymbol = classSymbol.m_methods.back();
|
||||
methodSymbol.m_name = methodName;
|
||||
if (debugArgumentInfo)
|
||||
{
|
||||
methodSymbol.m_debugArgumentInfo = debugArgumentInfo;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto enumPropertyFunc = +[](const AZ::Uuid* classTypeId, const char* propertyName, bool canRead, bool canWrite, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
auto& classUuidToIndexMap = IntrusiveHelper::GetClassUuidToIndexMap(mySelf);
|
||||
auto itor = classUuidToIndexMap.find(*classTypeId);
|
||||
if (itor == classUuidToIndexMap.end())
|
||||
{
|
||||
AZ_Error(LogName, false, "Can not add property [%s] because class uuid [%s] is not registered", propertyName, classTypeId->ToString<AZStd::string>().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto classIndex = itor->second;
|
||||
auto& classSymbols = IntrusiveHelper::GetClassSymbols(mySelf);
|
||||
auto& classSymbol = classSymbols[classIndex];
|
||||
classSymbol.m_properties.push_back({});
|
||||
auto& propertySymbol = classSymbol.m_properties.back();
|
||||
propertySymbol.m_name = propertyName;
|
||||
propertySymbol.m_canRead = canRead;
|
||||
propertySymbol.m_canWrite = canWrite;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
debugContext->EnumRegisteredClasses(enumClassFunc, enumMethodFunc, enumPropertyFunc, this);
|
||||
|
||||
scriptContext->DisableDebug();
|
||||
|
||||
return m_cachedClassSymbols;
|
||||
}
|
||||
|
||||
const AZStd::vector<LuaPropertySymbol>& LuaSymbolsReporterSystemComponent::GetListOfGlobalProperties()
|
||||
{
|
||||
if (!m_cachedGlobalPropertySymbols.empty())
|
||||
{
|
||||
return m_cachedGlobalPropertySymbols;
|
||||
}
|
||||
|
||||
LoadGlobalSymbols();
|
||||
|
||||
return m_cachedGlobalPropertySymbols;
|
||||
}
|
||||
|
||||
const AZStd::vector<LuaMethodSymbol>& LuaSymbolsReporterSystemComponent::GetListOfGlobalFunctions()
|
||||
{
|
||||
if (!m_cachedGlobalFunctionSymbols.empty())
|
||||
{
|
||||
return m_cachedGlobalFunctionSymbols;
|
||||
}
|
||||
|
||||
LoadGlobalSymbols();
|
||||
|
||||
return m_cachedGlobalFunctionSymbols;
|
||||
}
|
||||
|
||||
const AZStd::vector<LuaEBusSymbol>& LuaSymbolsReporterSystemComponent::GetListOfEBuses()
|
||||
{
|
||||
if (!m_cachedEbusSymbols.empty())
|
||||
{
|
||||
return m_cachedEbusSymbols;
|
||||
}
|
||||
|
||||
auto scriptContext = InitScriptContext();
|
||||
if (!scriptContext)
|
||||
{
|
||||
return m_cachedEbusSymbols;
|
||||
}
|
||||
|
||||
scriptContext->EnableDebug();
|
||||
|
||||
auto debugContext = scriptContext->GetDebugContext();
|
||||
if (!debugContext)
|
||||
{
|
||||
return m_cachedEbusSymbols;
|
||||
}
|
||||
|
||||
auto enumEBusFunc = +[](const AZStd::string& ebusName, bool canBroadcast, bool canQueue, bool hasHandler, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
|
||||
auto& ebusSymbols = IntrusiveHelper::GetEBusSymbols(mySelf);
|
||||
ebusSymbols.push_back({});
|
||||
auto& ebusSymbol = ebusSymbols.back();
|
||||
ebusSymbol.m_name = ebusName;
|
||||
ebusSymbol.m_canBroadcast = canBroadcast;
|
||||
ebusSymbol.m_canQueue = canQueue;
|
||||
ebusSymbol.m_hasHandler = hasHandler;
|
||||
|
||||
auto& nameToIndexMap = IntrusiveHelper::GetEBusNameToIndexMap(mySelf);
|
||||
nameToIndexMap.emplace(ebusName, ebusSymbols.size() - 1);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto enumEBusSenderFunc = +[](const AZStd::string& ebusName, const AZStd::string& senderName, const AZStd::string& debugArgumentInfo, const AZStd::string& category, void* userData) -> bool
|
||||
{
|
||||
auto& mySelf = *reinterpret_cast<LuaSymbolsReporterSystemComponent*>(userData);
|
||||
auto& nameToIndexMap = IntrusiveHelper::GetEBusNameToIndexMap(mySelf);
|
||||
auto itor = nameToIndexMap.find(ebusName);
|
||||
if (itor == nameToIndexMap.end())
|
||||
{
|
||||
AZ_Error(LogName, false, "Can not add ebus sender [%s] because ebus [%s] is not registered", senderName.c_str(), ebusName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ebusIndex = itor->second;
|
||||
auto& ebusSymbols = IntrusiveHelper::GetEBusSymbols(mySelf);
|
||||
auto& ebusSymbol = ebusSymbols[ebusIndex];
|
||||
|
||||
ebusSymbol.m_senders.push_back({});
|
||||
auto& ebusSender = ebusSymbol.m_senders.back();
|
||||
ebusSender.m_name = senderName;
|
||||
ebusSender.m_debugArgumentInfo = debugArgumentInfo;
|
||||
ebusSender.m_category = category;
|
||||
return true;
|
||||
};
|
||||
|
||||
debugContext->EnumRegisteredEBuses(enumEBusFunc, enumEBusSenderFunc, this);
|
||||
|
||||
scriptContext->DisableDebug();
|
||||
|
||||
return m_cachedEbusSymbols;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} //namespace Script
|
||||
} // namespace AzToolsFramework
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
|
||||
#include <AzToolsFramework/Script/LuaSymbolsReporterBus.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Script
|
||||
{
|
||||
/// System component for LuaSymbolsReporterRequestBus
|
||||
class LuaSymbolsReporterSystemComponent
|
||||
: public AZ::Component
|
||||
, public LuaSymbolsReporterRequestBus::Handler
|
||||
, private AzToolsFramework::EditorEvents::Bus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(LuaSymbolsReporterSystemComponent, "{DB8D95BA-FECF-4D81-A45C-8C05E706E2AC}");
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static constexpr char LogName[] = "LuaSymbolsReporter";
|
||||
|
||||
LuaSymbolsReporterSystemComponent() = default;
|
||||
~LuaSymbolsReporterSystemComponent() = default;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// LuaSymbolsReporterRequestBus::Handler
|
||||
const AZStd::vector<LuaClassSymbol>& GetListOfClasses() override;
|
||||
const AZStd::vector<LuaPropertySymbol>& GetListOfGlobalProperties() override;
|
||||
const AZStd::vector<LuaMethodSymbol>& GetListOfGlobalFunctions() override;
|
||||
const AZStd::vector<LuaEBusSymbol>& GetListOfEBuses() override;
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private:
|
||||
friend class IntrusiveHelper;
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
|
||||
// AZ::Component
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
|
||||
AZ::ScriptContext* InitScriptContext();
|
||||
void LoadGlobalSymbols();
|
||||
|
||||
AZ::ScriptContext* m_scriptContext = nullptr;
|
||||
|
||||
AZStd::vector<LuaClassSymbol> m_cachedClassSymbols;
|
||||
// The key is a class uuid, the value is the index in @m_cachedClassSymbols
|
||||
AZStd::unordered_map<AZ::Uuid, size_t> m_classUuidToIndexMap;
|
||||
|
||||
AZStd::vector<LuaPropertySymbol> m_cachedGlobalPropertySymbols;
|
||||
AZStd::vector<LuaMethodSymbol> m_cachedGlobalFunctionSymbols;
|
||||
|
||||
AZStd::vector<LuaEBusSymbol> m_cachedEbusSymbols;
|
||||
|
||||
// The key is the ebus name, the value is the index in @m_cachedEbusSymbols
|
||||
AZStd::unordered_map<AZStd::string, size_t> m_ebusNameToIndexMap;
|
||||
|
||||
};
|
||||
} // namespace Script
|
||||
} // namespace AzToolsFramework
|
||||
Reference in New Issue
Block a user