Hey @aturtur,
Thank you for reaching out to us. EventAdd will never really work in script manager scripts in the sense you mean it, unless you use hacks like dangling async dialogs (which as I always point out are a really bad idea).
The reason is that Script Manager scripts are blocking, i.e., all scene and GUI execution is being halted until the script finishes. You can hack yourself around this with a dangling async dialog, i.e., a dialog that lives beyond the life time of its script. But that is not a good idea, you should implement some form of plugin to host your asnyc dialog, as you otherwise risk crashes.
A modal dialog is just an extension of this. It is right in the name, it is modal, i.e., synchronous. All scene and GUI execution is being halted while this dialog is open and only resumes once it closes. When you want updates while your dialog is open, you need an async dialog (and a plugin which hosts it).
Cheers,
Ferdinand
Since you also might misunderstand the nature of EventAdd() I am also putting here the C++ docs I updated a few weeks ago, to better reflect the nature of it (not yet live):
/// @brief Enqueues an update event for the active document.
/// @details Only must be called when modifying the active document and is without meaning for other documents. The typical example of using `EventAdd` is after adding or removing elements from the active document; and wanting these changes to be reflected in the UI. The function itself is technically thread-safe, but the vast majority of operations that require calling `EventAdd` are not thread-safe and must be called from the main thread (and therefore calling this function is usually main thread bound). The function also does not enqueue a dedicated event item, but rather sets a flag that is checked when the next update event is processed. Therefore, calling `EventAdd` multiple times in one function scope is unnecessary overhead which must be avoided. Because such multiple event flags cannot be consumed while a function on the main thread is still running, and instead the event will only be consumed after that function returns.
/// @code
/// Result<void> AddCubes()
/// {
/// CheckState(maxon::ThreadInterface::IsMainThread(), "AddCubes must be called from the main thread."_s);
///
/// // EventAdd(); // We could also technically call it here with the same effect. The event
/// // will only happen after this function returns.
///
/// BaseDocument* doc = GetActiveDocument();
/// for (int i = 0; i < 10; ++i)
/// {
/// BaseObject* cube = BaseObject::Alloc(Ocube);
/// if (!cube)
/// return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "Failed to allocate cube object."_s);
///
/// doc->InsertObject(cube);
///
/// // Calling EventAdd here would have no extra effect, since this event cannot be consumed while
/// // our main thread function is still running. And such extra calls on a large scale can cause
/// // considerable overhead.
/// }
///
/// // Notify C4D that the active document has changed. The very end of a function or scope is the
/// // canonical place to call EventAdd().
/// EventAdd();
/// }
/// @endcode
/// @see The article @link page_manual_coremessages Core Messages@endlink for more information.
/// @param[in] eventflag The event to add: @enumerateEnum{EVENT}




