[Plugin] Myo

Myo plugin crash fix

The current version of the Myo plugin (0.7.11) is still crashing the UE4 editor when Myo Connect is not running.

I’ve traced crash to an assert in a function being called after plugin startup.

The actual error is:



"Assertion failed: O != NULL [File:C:\Users\<*user*>\Desktop\<*project*>\Plugins\MyoPlugin\Intermediate\Build\Win64\UE4Editor\Inc\MyoPlugin\MyoPlugin.generated."

UE4Editor_Core!FDebug::AssertFailed() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.8\engine\source\runtime\core\private\misc\outputdevice.cpp:355]
UE4Editor_MyoPlugin!IMyoInterface::Execute_DeviceDisabled() [c:\users\<user>\desktop\<project>\plugins\myoplugin\intermediate\build\win64\ue4editor\inc\myoplugin\myoplugin.generated.cpp:196]
UE4Editor_MyoPlugin!FMyoPlugin::SetDelegate() [c:\users\<user>\desktop\<project>\plugins\myoplugin\source\myoplugin\private\fmyoplugin.cpp:814]
UE4Editor_MyoPlugin!MyoDelegate::MyoStartup() [c:\users\<user>\desktop\<project>\plugins\myoplugin\source\myoplugin\private\myodelegate.cpp:206]


Here’s what’s happening…

In MyoPlugin.generated.cpp:


    
void IMyoInterface::Execute_DeviceDisabled(UObject* O){
        check(O != NULL); // is where the assert is failing.
...


In FMyoPlugin.cpp:809:



void FMyoPlugin::SetDelegate(MyoDelegate* newDelegate){ 
    collector->myoDelegate = newDelegate;
    collector->Startup();


    //Emit disabled event if we didn't manage to create the hub
    if (!collector->Enabled){
        collector->myoDelegate->MyoDisabled(); // Here is where IMyoInterface::Execute_DeviceDisabled is ultimately getting called.
...


The reason assert is failing is that the pointer to the interface delegate (_interfaceDelegate) is null after startup/initialization of the plugin when Myo Connect is not running.

In MyoDelegateBlueprint.cpp:211


void MyoDelegateBlueprint::SetInterfaceDelegate(UObject* newDelegate)
{
    UE_LOG(LogClass, Log, TEXT("InterfaceDelegate passed: %s"), *newDelegate->GetName());


    //Use format to support both blueprint and C++ form
    if (newDelegate->GetClass()->ImplementsInterface(UMyoInterface::StaticClass()))
    {
        _interfaceDelegate = newDelegate;
    }
    else
    {
        //Try casting as self
        if (ValidSelfPointer->GetClass()->ImplementsInterface(UMyoInterface::StaticClass()))
        {
            _interfaceDelegate = (UObject*)this;
        }
        else
        {
            //If you're crashing its probably because of setting causing an assert failure
            _interfaceDelegate = NULL;
        }




There is a function which can be used to check for condition called MyoDelegateBlueprint::IsValidDelegate().

**In MyoDelegateBlueprint.cpp:187

**


bool MyoDelegateBlueprint::IsValidDelegate()
{
    return (_interfaceDelegate != NULL);
}


So, IsValidDelegate() can be used to detect condition and fix the crash.