Send Event "Disconnect" bug and event driven design considerations?

I meet a failure when using the Disconnect entry on a Receive Event Node
image

Do you get the same problem with a node always receiving Events even if set as Disconnected ?

If this is a Script Event, it is a known problem, we’ve implemented a fix that will be available in the 1.25 release. Sorry for the inconvenience.

1 Like

Thanks for the info Luis @LS1.
For me if this new version could contain little extra things like global variables which would prevent us from overloading our scripts with Events and synchronization problems, as well as elementary Math Nodes like Log and Exponential, plus prevent that the Script Canvas Asset becomes empty from time to time, it would be perfect for the canvas scripting part.
The best would be to be able to automatically draw some listings of things like Events and variables, like today we have to do it by hand …

And forgive me if I dare Luis, actually we are obliged to use Asynchronous Event transmission mode, thus the data items transmitted within a stream of Events are transmitted one after the other randomly, thus there are no further timing constraints on when transmission of items should take place.

In certain case as we discused before in this post, we need Synchronous transmission mode with a maximum end-to-end delay defined for each Event to respect a kind of pattern of repetition. I don’t see evident to do it with the actual version of Events and it could be cool to provide some specialized events for that in the futur. The games we can develop on Lumberyard are not necessarily with a “fast” game engine system but a system that satisfies time constraints.
(In short, you should allow us to manage easily the time constraints that depend on our application and its environment, while the speed will depend on the technology used in your game engine and the processor for example).

A last general remark too for

as we are actually in the 1.23.1 … it’s seems a long way before the 1.25 :checkered_flag: Where can we have a look of a road map to see what you plan in futur releases ?

1 Like

It sounds like what you’re looking for is Queued Script Events. We support event queuing in C++ but have not exposed that ability to Script Canvas. I have created a feature request ticket for us to look into adding this support.

If you are comfortable with C++ and recompiling Lumberyard, I could walk you through the changes you’d need to apply in order to fix Script Event disconnection.

2 Likes

:+1: Great Luis if we can get some control on the Queued Script Events using Nodes as I think that if you want to allow us to make well-designed systems with script events, it must be possible for us to selectively process our events and thus the deadlines of critical events and scripts will always be met.

More getting the possibility to monitor this event queue and thus adjust our strategy of events if not matching with user could be a plus.

Otherwise I suppose that lot of users of LY will experiment (as you propose to us a decoupled environment and as scripts use events to communicate with each other, even unnecessarily for the exchange of global data :wink: ) some sporadic events that could become the bugaboo of many applications on LY.

Thank you too and gladly for

Maybe too that we could make mistakes when building event-driven systems in LY, thus how to design it and design consideration could be welcome in a new chapter of the LY doc.

For example when I first experienced with LY, I needed a kind of best design pattern in LY in order to design something really event driven with large decoupling rather than a classic “Request-Reply” design pattern, that the use for the first time of the “Nodes Send/Receives Event” which trends to make us using this at a first step.

For example that doc could aware us too about design considerations like :sunglasses::

  • If we have multiple receivers that try to consume a single event, how to ensure that only one of them succeed or at contrary all of them ?

  • Possiblity to make a wildcard subscriptions to events ?

  • Possibility to create on the fly subscriptions to an event ?

  • Event expiration or how to specify a time limit for “how long this event is viable” ? …

  • Spawned entities that contains Events emitter/receiver in their script ? Entities with parent/children hierarchy ? activation ? ready state ? delivery reliability …

(I think mainly relies on the availability of the connect/disconnect :wink: )

It could be inspired by the Amazon SQS that is “on how it allows us to decouple application components so that they can run and fail independently, thereby strengthening the overall resilience of the system.” or this article https://www.ben-morris.com/event-driven-architecture-and-message-design-anti-patterns-and-pitfalls/

PS: is it a way here How to Activate / Deactivate Component of Entity with nodes that could replace the connect/disconnect which is currently missing ?

Hi @Didier,

Apologies for the delay. I have instructions for fixing the Disconnect feature of Script Events, and I will comment on your recommendations on a separate reply.

File:
Gems\ScriptCanvas\Code\Include\ScriptCanvas\Libraries\Core\ReceiveScriptEvent.h

Line 96, Add:

void CompleteDisconnection();

Line 137, Add:

bool m_connected = false;

In file Gems\ScriptCanvas\Code\Include\ScriptCanvas\Libraries\Core\ReceiveScriptEvent.cpp:

Line 38, replace:

if (m_handler)

With:

if (m_connected && m_handler)

line: 696
Delete these two lines:

SlotId onDisconnectSlotId = ReceiveScriptEventProperty::GetOnDisconnectedSlotId(this);
SignalOutput(onDisconnectSlotId);

Lines: 490 to 529
Replace existing code with:

                if (!IsIDRequired() || busIdParameter.GetValueAddress())
                {
                    if (m_connected)
                    {
                        // Ensure we disconnect if this bus is already connected, this could happen if a different bus Id is provided
                        // and this node is connected through the Connect slot.
                        m_handler->Disconnect();
                    }

                    AZ_VerifyError("Script Canvas", m_handler->Connect(&busIdParameter),
                        "Unable to connect to EBus with BusIdType %s. The BusIdType of the Script Event (%s) does not match the BusIdType provided.",
                        busIdType.ToString<AZStd::string>().data(), m_definition.GetName().c_str());

                    m_connected = true;
                }
            }

            void ReceiveScriptEvent::CompleteDisconnection()
            {
                m_handler->Disconnect();
                m_connected = false;

                SlotId onDisconnectSlotId = ReceiveScriptEventProperty::GetOnDisconnectedSlotId(this);
                SignalOutput(onDisconnectSlotId);
            }

            void ReceiveScriptEvent::Disconnect(bool queueDisconnect)
            {
                if (m_connected && m_handler)
                {
                    if (queueDisconnect)
                    {
                        AZ::SystemTickBus::QueueFunction(
                            [this]()
                            {
                                CompleteDisconnection();
                            }
                        );
                    }
                    else
                    {
                        CompleteDisconnection();
                    }
                }
            }

After these changes are applied, you can rebuild the Lumberyard editor and if everything compiles Disconnecting should work.

Let me know if you run into any problems.

1 Like

Hi @Didier

These are excellent suggestions! Thank you!

If we have multiple receivers that try to consume a single event, how to ensure that only one of them succeed or at contrary all of them ?

I will investigate how we can implement this, it sounds very useful, thank you!

Possiblity to make a wildcard subscriptions to events ?

This is possible, if you create a Script Event and do not specify an Address Type, this Script Event will be a Broadcast Script Event, any receive node in any graph will handle this event. I will work on updating the documentation to cover this.

Possibility to create on the fly subscriptions to an event ?

We don’t currently support this, but I will add it to our requested features

Event expiration or how to specify a time limit for “how long this event is viable” ? …

This is interesting, currently we don’t have builtin support to do this, but it can be managed through scripting, will also add as a feature request.

Thanks again for the excellent feedback!

1 Like

Thanks Luis … as I did’nt seen the same code that your in this post, I reinstalled LY with the last version I can find, that is 1.23.1.0 which date is 16.03.2020 …


and it stills that I have’nt the same code as you as well in .h or .cpp

see thereafter
no line 137
image

and in .cpp no line 38 with the same if (m_handler) but inspite a
if (m_ebus && m_handler && m_ebus->m_destroyHandler) at line 34 …
image

the line to declare SlotId is in line 647, not 696

Thus it seems that you have more lines of code in your version …

Just for info too, I took the time to look at your code a little… and here it seems to me that there is a potential problem :thinking:

Globally the malfunction of this part could cause problems like when you deactivate an Entity with a child and then reactivate it … then you can’t get back to the normal state of OnActivated for the child.

@LS1 I think that you have already developped the base for making the doc for those Event-driven design considerations if we look at the existing doc here https://docs.aws.amazon.com/fr_fr/lumberyard/latest/userguide/ebus-in-depth.html#ebus-in-depth-configuration .

This doc could be reused but now with a script canvas user point of view. :sunglasses:

For example, the usage of the Adress Type when defining an Event with the Asset Editor isn’t clear, if we consider all the possibilties that it offers and it’s not straitghtforward when trying to make the link with the existing doc, and it takes time to find answers by a search into source code.

1 Like

@Didier,

Great suggestion! I will work with our documentation team to get this going.

thanks!

1 Like

Hello Luis @LS1 , I didn’t find if the connect/disconnect is ok now in the new 1.24 version … is it the case ?

1 Like