ACAPI_​Command_​CallFromEventLoop

Calls a command of an add-on from Archicad’s main event loop.

    GSErrCode  ACAPI_Command_CallFromEventLoop (
        const API_ModulID*           mdid,
        GSType                       cmdID,
        Int32                        cmdVersion,
        GSHandle                     paramsHandle,
        bool                         silentMode,
        APICommandCallBackProc*     callbackProc
    );

 

Parameters

mdid
[in] the identifier of the target add-on. It is defined by the ‘MDID’ resource
cmdID
[in] the identifier of the command to be executed
cmdVersion
[in] the required command version
params
[in/out] passed parameters (optional). See the Inter-add-on communication section of the ACAPI_Goodies functions
silentMode
[in] instruct the target add-on to work in silent mode. No option dialogs, error alerts …etc.
callbackProc
[in] optional callback procedure for handling the responses asynchronously

 

Return Values

NoError
the function completed successfully
APIERR_BADPARS
the mdid parameter is nullptr
APIERR_MODULNOTINSTALLED
the referenced add-on is not installed
APIERR_MODULCMDNOTSUPPORTED
the referenced command is not supported by the target add-on
APIERR_MODULCMDVERSNOTSUPPORTED
the requested command version is too new; not supported by the target add-on

For other common errors see the list of error codes.

 

Remarks

This function is used to call a command implemented in an add-on from Archicad’s main event loop.

Refer to the ACAPI_Command_Test function to test the command availability.

Refer to the Communication Manager for more detailed description on

  • how to pass parameters,
  • how to get return values,
  • how the heaps and API environments are managed by the API.

 

Example

The following sample starts a new working thread and calls an add-on command to place a column in the given position:


// ---------------------------------------------------------------------------------------------------------------------
// Add double parameter to MDCL parameter list
// ---------------------------------------------------------------------------------------------------------------------
bool    AddFloatMDCLParameter (GSHandle& paramHandle, const char* name, double value)
{
    API_MDCLParameter   par;
    BNZeroMemory (&par, sizeof (par));
    par.name = name;
    par.type = MDCLPar_float;
    par.float_par = value;
    return ACAPI_Goodies (APIAny_AddMDCLParameterID, paramHandle, &par) == NoError;
}


// ---------------------------------------------------------------------------------------------------------------------
// Get double parameter from MDCL parameter list
// ---------------------------------------------------------------------------------------------------------------------
bool    GetFloatMDCLParameter (GSHandle paramHandle, const char *name, double& value)
{
    API_MDCLParameter   par;
    BNZeroMemory (&par, sizeof (API_MDCLParameter));
    par.name = name;

    if (ACAPI_Goodies (APIAny_GetMDCLParameterID, paramHandle, &par) == NoError && par.type == MDCLPar_float)
    {
        value = par.float_par;
        return true;
    }
    return false;
}


// ---------------------------------------------------------------------------------------------------------------------
// Create column command handler
// ---------------------------------------------------------------------------------------------------------------------
GSErrCode __ACENV_CALL  Create_Column_CommandHandler (GSHandle paramHandle, GSPtr /*resultData*/, bool /*silentMode*/)
{
    GSErrCode           err = NoError;
    API_Coord           origoPos;

    if (!GetFloatMDCLParameter (paramHandle, "origoPosX", origoPos.x) ||
        !GetFloatMDCLParameter (paramHandle, "origoPosY", origoPos.y))
        return APIERR_BADPARS;

    API_Element     element;
    API_ElementMemo memo;

    BNZeroMemory (&element, sizeof (API_Element));
    BNZeroMemory (&memo, sizeof (API_ElementMemo));

    element.header.type = API_ColumnID;
    err = ACAPI_Element_GetDefaults (&element, nullptr);
    if (err != NoError)
        return err;

    element.column.origoPos    = origoPos;

    ACAPI_CallUndoableCommand ("Test - Create column command",
        [&] () -> GSErrCode {
            return ACAPI_Element_Create (&element, &memo);
    });

    ACAPI_DisposeElemMemoHdls (&memo);

    return err;
}

// ---------------------------------------------------------------------------------------------------------------------
// CallBack function for command call from event loop
// ---------------------------------------------------------------------------------------------------------------------
void __ACENV_CALL   CommandCallBackProc (GSHandle* paramHandle, GSPtr /*resultData*/, GSErrCode returnCode)
{
    if (returnCode != NoError)
        WriteReport_Err ("Command finished in event loop with Error", returnCode);
    else
        WriteReport ("Command successfully finished in event loop!");

    if (paramHandle != nullptr)
        ACAPI_Goodies (APIAny_FreeMDCLParameterListID, paramHandle, nullptr);
}

// --- MonitoredTask -----------------------------------------------------------

class MonitoredTask : public GS::Runnable {
public:
    explicit MonitoredTask ();

    virtual void    Run ();
};


MonitoredTask::MonitoredTask ()
{
}


void    MonitoredTask::Run ()
{
    try {
        GSErrCode   err = NoError;
        API_Coord   origoPos;
        BNZeroMemory (&origoPos, sizeof (API_Coord));
        origoPos.x = 10.0;
        origoPos.y = 20.0;

        GSHandle    paramHandle = nullptr;
        err = ACAPI_Goodies (APIAny_InitMDCLParameterListID, &paramHandle, nullptr);
        if (err == NoError) {
            if (AddFloatMDCLParameter (paramHandle, "origoPosX", origoPos.x) &&
                AddFloatMDCLParameter (paramHandle, "origoPosY", origoPos.y))
            {
                API_ModulID mdid;
                BNZeroMemory (&mdid, sizeof (mdid));
                mdid.developerID = MDID_GSDEV;
                mdid.localID = MDID_GSDEV_Test;
                err = ACAPI_Command_CallFromEventLoop (&mdid, 'CCOL', 1, paramHandle, false, CommandCallBackProc);
                if (err != NoError) {
                    WriteReport_Err ("ACAPI_Command_CallFromEventLoop failed", err);
                    ACAPI_Goodies (APIAny_FreeMDCLParameterListID, &paramHandle, nullptr);
                }
            }
        }
    }
    catch (GS::InterruptedException&) {
        // Empty handler
    }
    catch (...) {
    }
}


/*----------------------------------------------------------*/

static void     Do_CommandCallFromEventLoop (void)
{
    GS::Thread m_worker (new MonitoredTask (), "CommandCallFromEventLoop_MonitoredTaskThread");
    m_worker.Start ();
}


//------------------------------------------------------
// Interface definitions
//------------------------------------------------------
GSErrCode __ACENV_CALL  RegisterInterface (void)
{
    // register supported command
    GSErrCode err = ACAPI_Register_SupportedService ('CCOL', 1);

    return err;
}       /* RegisterInterface */


//------------------------------------------------------
// Called when the Add-On has been loaded into memory
// to perform an operation
//------------------------------------------------------
GSErrCode __ACENV_CALL  Initialize (void)
{
    // install command handler
    GSErrCode err = ACAPI_Install_ModulCommandHandler ('CCOL', 1, Create_Column_CommandHandler);

    return err;
}       /* Initialize */

 

Requirements

Version: API 19 or later
Header: ACAPinc.h

 

See Also

API_ModulID, ‘MDID’
APICommandCallBackProc
APIModulCommandProc
ACAPI_Command_Call
ACAPI_Command_Test
Communication Manager
API Functions