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> Signed-off-by: Gene Walters <genewalt@amazon.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
# This script shows basic usage of LuaSymbolsReporterBus,
|
||||
# Which can be used to report all symbols available for
|
||||
# game scripting with Lua.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import azlmbr.bus as azbus
|
||||
import azlmbr.script as azscript
|
||||
import azlmbr.legacy.general as azgeneral
|
||||
|
||||
|
||||
def _dump_class_symbol(class_symbol: azlmbr.script.LuaClassSymbol):
|
||||
print(f"** {class_symbol}")
|
||||
print("Properties:")
|
||||
for property_symbol in class_symbol.properties:
|
||||
print(f" - {property_symbol}")
|
||||
print("Methods:")
|
||||
for method_symbol in class_symbol.methods:
|
||||
print(f" - {method_symbol}")
|
||||
|
||||
|
||||
def _dump_lua_classes():
|
||||
class_symbols = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfClasses")
|
||||
print("======== Classes ==========")
|
||||
sorted_classes_by_named = sorted(class_symbols, key=lambda class_symbol: class_symbol.name)
|
||||
for class_symbol in sorted_classes_by_named:
|
||||
_dump_class_symbol(class_symbol)
|
||||
print("\n\n")
|
||||
|
||||
|
||||
def _dump_lua_globals():
|
||||
global_properties = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfGlobalProperties")
|
||||
print("======== Global Properties ==========")
|
||||
sorted_properties_by_name = sorted(global_properties, key=lambda symbol: symbol.name)
|
||||
for property_symbol in sorted_properties_by_name:
|
||||
print(f"- {property_symbol}")
|
||||
print("\n\n")
|
||||
global_functions = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfGlobalFunctions")
|
||||
print("======== Global Functions ==========")
|
||||
sorted_functions_by_name = sorted(global_functions, key=lambda symbol: symbol.name)
|
||||
for function_symbol in sorted_functions_by_name:
|
||||
print(f"- {function_symbol}")
|
||||
print("\n\n")
|
||||
|
||||
|
||||
def _dump_lua_ebus(ebus_symbol: azlmbr.script.LuaEBusSymbol):
|
||||
print(f">> {ebus_symbol}")
|
||||
sorted_senders = sorted(ebus_symbol.senders, key=lambda symbol: symbol.name)
|
||||
for sender in sorted_senders:
|
||||
print(f" - {sender}")
|
||||
print("\n")
|
||||
|
||||
|
||||
def _dump_lua_ebuses():
|
||||
ebuses = azscript.LuaSymbolsReporterBus(azbus.Broadcast,
|
||||
"GetListOfEBuses")
|
||||
print("======== Ebus List ==========")
|
||||
sorted_ebuses_by_name = sorted(ebuses, key=lambda symbol: symbol.name)
|
||||
for ebus_symbol in sorted_ebuses_by_name:
|
||||
_dump_lua_ebus(ebus_symbol)
|
||||
print("\n\n")
|
||||
|
||||
|
||||
class WhatToDo:
|
||||
DumpClasses = "c"
|
||||
DumpGlobals = "g"
|
||||
DumpEBuses = "e"
|
||||
|
||||
if __name__ == "__main__":
|
||||
redirecting_stdout = False
|
||||
orig_stdout = sys.stdout
|
||||
if len(sys.argv) > 1:
|
||||
output_file_name = sys.argv[1]
|
||||
if not os.path.isabs(output_file_name):
|
||||
game_root_path = os.path.normpath(azgeneral.get_game_folder())
|
||||
output_file_name = os.path.join(game_root_path, output_file_name)
|
||||
try:
|
||||
file_obj = open(output_file_name, 'wt')
|
||||
sys.stdout = file_obj
|
||||
redirecting_stdout = True
|
||||
except Exception as e:
|
||||
print(f"Failed to open {output_file_name}: {e}")
|
||||
sys.exit(-1)
|
||||
|
||||
what_to_do = [action.lower() for action in sys.argv[2:]]
|
||||
|
||||
# If the user did not specify what to do, then let's dump
|
||||
# all the symbols.
|
||||
if len(what_to_do) < 1:
|
||||
what_to_do = [WhatToDo.DumpClasses, WhatToDo.DumpGlobals, WhatToDo.DumpEBuses]
|
||||
|
||||
for action in what_to_do:
|
||||
if action == WhatToDo.DumpClasses:
|
||||
_dump_lua_classes()
|
||||
elif action == WhatToDo.DumpGlobals:
|
||||
_dump_lua_globals()
|
||||
elif action == WhatToDo.DumpEBuses:
|
||||
_dump_lua_ebuses()
|
||||
|
||||
if redirecting_stdout:
|
||||
sys.stdout.close()
|
||||
sys.stdout = orig_stdout
|
||||
print(f" Lua Symbols Are available in: {output_file_name}")
|
||||
@@ -70,6 +70,7 @@
|
||||
#include <AzToolsFramework/Undo/UndoCacheInterface.h>
|
||||
#include <AzToolsFramework/Prefab/PrefabPublicInterface.h>
|
||||
#include <Entity/EntityUtilityComponent.h>
|
||||
#include <AzToolsFramework/Script/LuaSymbolsReporterSystemComponent.h>
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QFileInfo::d_ptr': class 'QSharedDataPointer<QFileInfoPrivate>' needs to have dll-interface to be used by clients of class 'QFileInfo'
|
||||
@@ -273,7 +274,8 @@ namespace AzToolsFramework
|
||||
azrtti_typeid<Components::EditorEntitySearchComponent>(),
|
||||
azrtti_typeid<Components::EditorIntersectorComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::SliceRequestComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::EntityUtilityComponent>()
|
||||
azrtti_typeid<AzToolsFramework::EntityUtilityComponent>(),
|
||||
azrtti_typeid<AzToolsFramework::Script::LuaSymbolsReporterSystemComponent>(),
|
||||
});
|
||||
|
||||
return components;
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h>
|
||||
#include <AzToolsFramework/Entity/EntityUtilityComponent.h>
|
||||
#include <AzToolsFramework/Script/LuaSymbolsReporterSystemComponent.h>
|
||||
|
||||
AZ_DEFINE_BUDGET(AzToolsFramework);
|
||||
|
||||
@@ -106,6 +107,7 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Components::EditorIntersectorComponent::CreateDescriptor(),
|
||||
AzToolsFramework::AzToolsFrameworkConfigurationSystemComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Components::EditorEntityUiSystemComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Script::LuaSymbolsReporterSystemComponent::CreateDescriptor(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -770,6 +770,9 @@ set(FILES
|
||||
PythonTerminal/ScriptTermDialog.ui
|
||||
Input/QtEventToAzInputManager.h
|
||||
Input/QtEventToAzInputManager.cpp
|
||||
Script/LuaSymbolsReporterBus.h
|
||||
Script/LuaSymbolsReporterSystemComponent.h
|
||||
Script/LuaSymbolsReporterSystemComponent.cpp
|
||||
)
|
||||
|
||||
# Prevent the following files from being grouped in UNITY builds
|
||||
|
||||
Reference in New Issue
Block a user