o3de / o3de.org

The O3DE website
Other
86 stars 159 forks source link

[DOCS] Document Best Practices for reflecting constructors for Lua/ScriptCanvas #1429

Open lsemp3d opened 2 years ago

lsemp3d commented 2 years ago

Reflecting Lua constructors to the Behavior Context has a few different configurations, some work better than others.

Depending on the approach, construction of some objects may be slow, force programmers to code directly against ScriptContext, rather than just the Behavior Context, and ends up as a surprise for Lua uses as such behavior in functions is rare generally not recommended in the language since it is known there is no method overloading

We need to document everything about reflecting constructors with Best Practices and a FAQ:

Q. I've got a Bus with a custom busID that I'm trying to connect to in Lua script. This ID type can be constructed from a generic void* or an AZ::EntityId . Both constructors convert down to a stored type, this essentially allows me to use this bus in both low-level and high-level (ECS) contexts.

    struct TriggerNotificationIdType
    {
        AZ_TYPE_INFO(TriggerNotificationIdType, "{E355AC15-8C88-4BDD-8CCE-9999EC32F970}");
        uintptr_t m_owner{ 0 };

        TriggerNotificationIdType() = default;
        ~TriggerNotificationIdType() = default;

        TriggerNotificationIdType(void* owner)
            : m_owner(reinterpret_cast<uintptr_t>(owner))
        {
        }
        TriggerNotificationIdType(AZ::EntityId owner)
            : m_owner(static_cast<uintptr_t>(static_cast<AZ::u64>(owner)))
        {
        }
    };

I've added the constructor taking the EntityId to the behavior context:

            behaviorContext->Class<Audio::TriggerNotificationIdType>("TriggerNotificationIdType")
                ->Constructor<AZ::EntityId>()

And in Lua script I'm trying to connect to it:

    local id = TriggerNotificationIdType(self.entityId);
    self.audioTriggerNotificationHandler = AudioTriggerNotificationBus.Connect(self, id);

It does not call the constructor taking AZ::EntityId . If I catch the bus Connect I see that the busId has a zero value, I verified it's calling the default construtor. I've also tried doing a more explicit EntityId(self.entityId) in the script, with no luck.

Does this work have an engineering dependency? What is it?

Scripting

galibzon commented 2 years ago

From EBus.h, regarding BusIdType requirements:

I wonder if that's the problem.

lsemp3d commented 2 years ago

From EBus.h, regarding BusIdType requirements: The type must support AZStd::hash<ID> and bool operator==(const ID&, const ID&).

I wonder if that's the problem.

There's a lot of nuance in reflecting constructors. We need to get a good 'best practices' guide for it