////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: Parameter Parser V5.5.1 (2411131018)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxactuatordriver.cpp
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxactuatordriver.h"
#include "parametersetmanager.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SetValue/GetValue Functions
/// Gets or sets the requested value
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_ActuatorType(
    ParameterFileSymbolTableEntry* const entry,
    ActuatorType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(ActuatorType::VCM):
            enumValue = ActuatorType::VCM;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorType::BIVCM):
            enumValue = ActuatorType::BIVCM;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to ActuatorType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_ActuatorFeedbackType(
    ParameterFileSymbolTableEntry* const entry,
    ActuatorFeedbackType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(ActuatorFeedbackType::OPENLOOP):
            enumValue = ActuatorFeedbackType::OPENLOOP;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorFeedbackType::CLOSEDLOOP):
            enumValue = ActuatorFeedbackType::CLOSEDLOOP;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to ActuatorFeedbackType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_ParkLensExecution(
    ParameterFileSymbolTableEntry* const entry,
    ParkLensExecution& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(ParkLensExecution::BEFOREPOWEROFF):
            enumValue = ParkLensExecution::BEFOREPOWEROFF;
            result    = true;
            break;
        case static_cast<UINT32>(ParkLensExecution::BEFORESTANDBY):
            enumValue = ParkLensExecution::BEFORESTANDBY;
            result    = true;
            break;
        case static_cast<UINT32>(ParkLensExecution::NONE):
            enumValue = ParkLensExecution::NONE;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to ParkLensExecution", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_ActuatorOperation(
    ParameterFileSymbolTableEntry* const entry,
    ActuatorOperation& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(ActuatorOperation::WRITE_HW_DAMP):
            enumValue = ActuatorOperation::WRITE_HW_DAMP;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorOperation::WRITE_DAC_VALUE):
            enumValue = ActuatorOperation::WRITE_DAC_VALUE;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorOperation::WRITE):
            enumValue = ActuatorOperation::WRITE;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorOperation::WRITE_DIR_REG):
            enumValue = ActuatorOperation::WRITE_DIR_REG;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorOperation::POLL):
            enumValue = ActuatorOperation::POLL;
            result    = true;
            break;
        case static_cast<UINT32>(ActuatorOperation::READ_WRITE):
            enumValue = ActuatorOperation::READ_WRITE;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to ActuatorOperation", uintValue);
            break;
        }
    }
    return result;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default Constructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ActuatorDriverDataClass::ActuatorDriverDataClass(
    const CHAR* const name)
    : ParameterModule(name, MAJOR, MINOR, PATCH, nullptr)
{
    PARAMETER_INITIALIZE(SymbolTableID);
    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(registerConfig);
    PARAMETER_INITIALIZE(initSettings);
    PARAMETER_INITIALIZE(activateSettingsExists);
    PARAMETER_INITIALIZE(activateSettings);
    PARAMETER_INITIALIZE(standbySettingsExists);
    PARAMETER_INITIALIZE(standbySettings);
    PARAMETER_INITIALIZE(uninitSettingsExists);
    PARAMETER_INITIALIZE(uninitSettings);
    PARAMETER_INITIALIZE(tunedParams);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ActuatorDriverDataClass::ActuatorDriverDataClass(
    const CHAR* const name,
    ModuleData* const moduleData)
    : ParameterModule(name, MAJOR, MINOR, PATCH, moduleData)
{
    PARAMETER_INITIALIZE(SymbolTableID);
    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(registerConfig);
    PARAMETER_INITIALIZE(initSettings);
    PARAMETER_INITIALIZE(activateSettings);
    PARAMETER_INITIALIZE(standbySettings);
    PARAMETER_INITIALIZE(uninitSettings);
    PARAMETER_INITIALIZE(tunedParams);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ActuatorDriverDataClass::~ActuatorDriverDataClass()
{
    if (Loaded)
    {
        UnloadModule();
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// GetName
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const CHAR* ActuatorDriverDataClass::GetName(
    const CHAR* const type)
{
    const CHAR* name = type;
    CHAR temp[ParameterFileSymbolTableEntry::TYPE_LEN + 1];
    if (PARAMETER_STRCMP(type, ModuleData::GetType(temp, "actuatorDriver")) == 0)
    {
        name = "actuatorDriver";
    }
    if (PARAMETER_STRCMP(type, ModuleData::GetType(temp, "actuatorDriver1")) == 0)
    {
        name = "actuatorDriver1";
    }
    return name;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ParkLensParameters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ParkLensParameters::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(executionMode);
    PARAMETER_INITIALIZE(numberOfSteps);
    PARAMETER_INITIALIZE(delayBetweenStepsInMs);

    result = ReadEnum_ParkLensExecution(entry, executionMode, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, numberOfSteps, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, delayBetweenStepsInMs, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorSlaveInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorSlaveInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(actuatorName);
    PARAMETER_INITIALIZE(actuatorIDExists);
    PARAMETER_INITIALIZE(actuatorID);
    PARAMETER_INITIALIZE(slaveAddress);
    PARAMETER_INITIALIZE(i2cFrequencyMode);
    PARAMETER_INITIALIZE(actuatorType);
    PARAMETER_INITIALIZE(actuatorFeedbackTypeExists);
    PARAMETER_INITIALIZE(actuatorFeedbackType);
    PARAMETER_INITIALIZE(dataBitWidth);
    PARAMETER_INITIALIZE(powerUpSequence);
    PARAMETER_INITIALIZE(powerDownSequence);


    // Reading String actuatorName from symbol table
    {
        UINT32 count = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, count, alignment)
        ParameterFileSymbolTableEntry stringPointerEntryCls;
        ParameterFileSymbolTableEntry* const stringPointerEntry = &stringPointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(stringPointerEntryCls, entry, alignment);
        }
        SYMBOL_TABLE_ENTRY_READ_STRING(stringPointerEntry, result, actuatorName, count, alignment)
    }

    // Reading Optional parameter actuatorID from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, actuatorIDExists, alignment)
        actuatorIDID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && actuatorIDExists)
        {
            SYMBOL_TABLE_ENTRY_READ(pointerEntry, result, actuatorID, alignment)
        }
        else
        {
            PARAMETER_INITIALIZE(actuatorID);
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, slaveAddress, alignment)
    if (result)
    {
        result = ReadEnum_I2CFrequencyMode(entry, i2cFrequencyMode, alignment);
    }
    if (result)
    {
        result = ReadEnum_ActuatorType(entry, actuatorType, alignment);
    }

    // Reading Optional parameter actuatorFeedbackType from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, actuatorFeedbackTypeExists, alignment)
        actuatorFeedbackTypeID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && actuatorFeedbackTypeExists)
        {
            if (result)
            {
                result = ReadEnum_ActuatorFeedbackType(pointerEntry, actuatorFeedbackType, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(actuatorFeedbackType);
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, dataBitWidth, alignment)
    if (result)
    {
        result = powerUpSequence.Load(entry, alignment);
    }
    if (result)
    {
        result = powerDownSequence.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorRegParam
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorRegParam::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(regAddrType);
    PARAMETER_INITIALIZE(regDataType);
    PARAMETER_INITIALIZE(registerAddr);
    PARAMETER_INITIALIZE(registerData);
    PARAMETER_INITIALIZE(operation);
    PARAMETER_INITIALIZE(delayUs);
    PARAMETER_INITIALIZE(hwMask);
    PARAMETER_INITIALIZE(hwShift);
    PARAMETER_INITIALIZE(dataShift);

    SYMBOL_TABLE_ENTRY_READ(entry, result, regAddrType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, regDataType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, registerAddr, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, registerData, alignment)
    if (result)
    {
        result = ReadEnum_ActuatorOperation(entry, operation, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, delayUs, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, hwMask, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, hwShift, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, dataShift, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorRegConfig
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorRegConfig::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(registerParam);


    // Reading Array registerParam from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        registerParamCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, registerParamCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            registerParamID = pointerEntry->ID;
            DupObjInfo* registerParamDupInfo = pointerEntry->GetDupObject(registerParamCount, file, line);
            if (registerParamDupInfo != nullptr && registerParamDupInfo->Object != nullptr)
            {
                registerParam = (ActuatorRegParam*)registerParamDupInfo->Object;
                if (registerParam == nullptr)
                {
                    if (registerParamDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "registerParam duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            registerParamDupInfo->File, registerParamDupInfo->Line, registerParamDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "registerParam duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            registerParamDupInfo->Line, registerParamDupInfo->RefCount);
                    }
                }
            }

            if (registerParam == nullptr)
            {
                if (result && registerParamCount > 0)
                {
                    registerParam = PARAMETER_NEW ActuatorRegParam[registerParamCount];
                    (void)pointerEntry->SetDupObject(registerParam, registerParamCount, file, line);
                }
                if (!result || registerParam == nullptr)
                {
                    if (registerParamCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate registerParam\n");
                    }
                    registerParamCount = 0;
                }
                for (UINT32 i = 0; result && i < registerParamCount; i++)
                {
                    result = registerParam[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (registerParam == nullptr)
        {
            registerParamCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorRegionParams
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorRegionParams::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(macroStepBoundary);
    PARAMETER_INITIALIZE(infinityStepBoundary);
    PARAMETER_INITIALIZE(codePerStep);
    PARAMETER_INITIALIZE(qValue);

    SYMBOL_TABLE_ENTRY_READ(entry, result, macroStepBoundary, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, infinityStepBoundary, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, codePerStep, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, qValue, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorRegionParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorRegionParamsArray::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(region);


    // Reading Array region from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        regionCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, regionCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            regionID = pointerEntry->ID;
            DupObjInfo* regionDupInfo = pointerEntry->GetDupObject(regionCount, file, line);
            if (regionDupInfo != nullptr && regionDupInfo->Object != nullptr)
            {
                region = (ActuatorRegionParams*)regionDupInfo->Object;
                if (region == nullptr)
                {
                    if (regionDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "region duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            regionDupInfo->File, regionDupInfo->Line, regionDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "region duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            regionDupInfo->Line, regionDupInfo->RefCount);
                    }
                }
            }

            if (region == nullptr)
            {
                if (result && regionCount > 0)
                {
                    region = PARAMETER_NEW ActuatorRegionParams[regionCount];
                    (void)pointerEntry->SetDupObject(region, regionCount, file, line);
                }
                if (!result || region == nullptr)
                {
                    if (regionCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate region\n");
                    }
                    regionCount = 0;
                }
                for (UINT32 i = 0; result && i < regionCount; i++)
                {
                    result = region[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (region == nullptr)
        {
            regionCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorDampingParams
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorDampingParams::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(dampingStep);
    PARAMETER_INITIALIZE(dampingDelayUs);
    PARAMETER_INITIALIZE(hwParams);

    SYMBOL_TABLE_ENTRY_READ(entry, result, dampingStep, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, dampingDelayUs, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, hwParams, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load RegionDampingParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool RegionDampingParamsArray::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(region);


    // Reading Array region from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        regionCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, regionCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            regionID = pointerEntry->ID;
            DupObjInfo* regionDupInfo = pointerEntry->GetDupObject(regionCount, file, line);
            if (regionDupInfo != nullptr && regionDupInfo->Object != nullptr)
            {
                region = (ActuatorDampingParams*)regionDupInfo->Object;
                if (region == nullptr)
                {
                    if (regionDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "region duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            regionDupInfo->File, regionDupInfo->Line, regionDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "region duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            regionDupInfo->Line, regionDupInfo->RefCount);
                    }
                }
            }

            if (region == nullptr)
            {
                if (result && regionCount > 0)
                {
                    region = PARAMETER_NEW ActuatorDampingParams[regionCount];
                    (void)pointerEntry->SetDupObject(region, regionCount, file, line);
                }
                if (!result || region == nullptr)
                {
                    if (regionCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate region\n");
                    }
                    regionCount = 0;
                }
                for (UINT32 i = 0; result && i < regionCount; i++)
                {
                    result = region[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (region == nullptr)
        {
            regionCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ScenarioDampingParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ScenarioDampingParamsArray::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(scenario);


    // Reading Array scenario from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        scenarioCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, scenarioCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            scenarioID = pointerEntry->ID;
            DupObjInfo* scenarioDupInfo = pointerEntry->GetDupObject(scenarioCount, file, line);
            if (scenarioDupInfo != nullptr && scenarioDupInfo->Object != nullptr)
            {
                scenario = (RegionDampingParamsArray*)scenarioDupInfo->Object;
                if (scenario == nullptr)
                {
                    if (scenarioDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "scenario duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            scenarioDupInfo->File, scenarioDupInfo->Line, scenarioDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "scenario duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            scenarioDupInfo->Line, scenarioDupInfo->RefCount);
                    }
                }
            }

            if (scenario == nullptr)
            {
                if (result && scenarioCount > 0)
                {
                    scenario = PARAMETER_NEW RegionDampingParamsArray[scenarioCount];
                    (void)pointerEntry->SetDupObject(scenario, scenarioCount, file, line);
                }
                if (!result || scenario == nullptr)
                {
                    if (scenarioCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate scenario\n");
                    }
                    scenarioCount = 0;
                }
                for (UINT32 i = 0; result && i < scenarioCount; i++)
                {
                    result = scenario[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (scenario == nullptr)
        {
            scenarioCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorDampingInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorDampingInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(ringingScenario);
    PARAMETER_INITIALIZE(scenarioDampingParams);

    SYMBOL_TABLE_ENTRY_READ(entry, result, ringingScenario, alignment)
    if (result)
    {
        result = scenarioDampingParams.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorTunedParams
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorTunedParams::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(initialCode);
    PARAMETER_INITIALIZE(parkLensParamsExists);
    PARAMETER_INITIALIZE(parkLensParams);
    PARAMETER_INITIALIZE(regionParams);
    PARAMETER_INITIALIZE(forwardDamping);
    PARAMETER_INITIALIZE(backwardDamping);

    SYMBOL_TABLE_ENTRY_READ(entry, result, initialCode, alignment)

    // Reading Optional parameter parkLensParams from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, parkLensParamsExists, alignment)
        parkLensParamsID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && parkLensParamsExists)
        {
            if (result)
            {
                result = parkLensParams.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(parkLensParams);
        }
    }
    if (result)
    {
        result = regionParams.Load(entry, alignment);
    }
    if (result)
    {
        result = forwardDamping.Load(entry, alignment);
    }
    if (result)
    {
        result = backwardDamping.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load ActuatorDriverData
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorDriverData::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(registerConfig);
    PARAMETER_INITIALIZE(initSettings);
    PARAMETER_INITIALIZE(activateSettingsExists);
    PARAMETER_INITIALIZE(activateSettings);
    PARAMETER_INITIALIZE(standbySettingsExists);
    PARAMETER_INITIALIZE(standbySettings);
    PARAMETER_INITIALIZE(uninitSettingsExists);
    PARAMETER_INITIALIZE(uninitSettings);
    PARAMETER_INITIALIZE(tunedParams);

    result = module_version.Load(entry, alignment);
    if (result)
    {
        result = slaveInfo.Load(entry, alignment);
    }
    if (result)
    {
        result = registerConfig.Load(entry, alignment);
    }
    if (result)
    {
        result = initSettings.Load(entry, alignment);
    }

    // Reading Optional parameter activateSettings from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, activateSettingsExists, alignment)
        activateSettingsID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && activateSettingsExists)
        {
            if (result)
            {
                result = activateSettings.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(activateSettings);
        }
    }

    // Reading Optional parameter standbySettings from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, standbySettingsExists, alignment)
        standbySettingsID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && standbySettingsExists)
        {
            if (result)
            {
                result = standbySettings.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(standbySettings);
        }
    }

    // Reading Optional parameter uninitSettings from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, uninitSettingsExists, alignment)
        uninitSettingsID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && uninitSettingsExists)
        {
            if (result)
            {
                result = uninitSettings.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(uninitSettings);
        }
    }
    if (result)
    {
        result = tunedParams.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load module_versionStruct
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorDriverData::module_versionStruct::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(major_revision);
    PARAMETER_INITIALIZE(minor_revision);
    PARAMETER_INITIALIZE(incr_revision);

    SYMBOL_TABLE_ENTRY_READ(entry, result, major_revision, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, minor_revision, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, incr_revision, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorSlaveInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorSlaveInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(actuatorName))
    {
        PARAMETER_DELETE[] actuatorName;
    }
    actuatorName = nullptr;
    powerUpSequence.Unload(__table);
    powerDownSequence.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorRegConfig
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorRegConfig::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(registerParam))
    {
        PARAMETER_DELETE[] registerParam;
    }
    registerParam = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorRegionParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorRegionParamsArray::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(region))
    {
        PARAMETER_DELETE[] region;
    }
    region = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload RegionDampingParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RegionDampingParamsArray::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(region))
    {
        PARAMETER_DELETE[] region;
    }
    region = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ScenarioDampingParamsArray
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ScenarioDampingParamsArray::Unload(ParameterFileSymbolTable* const __table)
{
    for (UINT32 i = 0; i < scenarioCount; i++)
    {
        scenario[i].Unload(__table);
    }
    if (__table != nullptr && __table->ReleaseDupObject(scenario))
    {
        PARAMETER_DELETE[] scenario;
    }
    scenario = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorDampingInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorDampingInfo::Unload(ParameterFileSymbolTable* const __table)
{
    scenarioDampingParams.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorTunedParams
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorTunedParams::Unload(ParameterFileSymbolTable* const __table)
{
    regionParams.Unload(__table);
    forwardDamping.Unload(__table);
    backwardDamping.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload ActuatorDriverData
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorDriverData::Unload(ParameterFileSymbolTable* const __table)
{
    slaveInfo.Unload(__table);
    registerConfig.Unload(__table);
    initSettings.Unload(__table);
    activateSettings.Unload(__table);
    standbySettings.Unload(__table);
    uninitSettings.Unload(__table);
    tunedParams.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Release the ParameterModule object
/// Requires that this object was created via a ParameterSetManager::GetModule call
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorDriverData::Release()
{
    ((ActuatorDriverDataClass*)this)->Release();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Returns the ParameterModule::Modified value
/// The Modified value is incremented when the module's data or pointer values change
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
UINT32 ActuatorDriverData::GetModified()
{
    return ((ActuatorDriverDataClass*)this)->Modified;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create module, and return a new object
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ParameterModule* ActuatorDriverDataClass::Create(
    ModuleData*    moduleData,
    DefaultModule* const defModule) const
{
    ActuatorDriverDataClass* cls = nullptr;

    if (PARAMETER_STRCMP(Type, moduleData->Type) == 0 && Version.Value == moduleData->Version.Value)
    {
        const UINT32 id = moduleData->DuplicateID > 0 ? moduleData->DuplicateID : moduleData->ID;

        ParameterModule* const module = defModule->Find(id);
        if (module != nullptr)
        {
            cls = (ActuatorDriverDataClass*)module;
        }
        else
        {
            cls = PARAMETER_NEW ActuatorDriverDataClass(GetName(moduleData->Type), moduleData);
            cls->SymbolTableID = id;
            defModule->AddModule((ParameterModule*)cls);
        }
    }
    else if (Version.Value != moduleData->Version.Value)
    {
        PARAMETER_LOG_ERROR(moduleData->SetManager, "Unable to create ActuatorDriverDataClass, binary version (%lld) does not match source version (%lld)\n",
            moduleData->Version.Value, Version.Value);
    }
    else
    {
        PARAMETER_LOG_ERROR(moduleData->SetManager, "Unable to create ActuatorDriverDataClass, binary name (%s) does not match source name (%s)\n",
            moduleData->Type, Type);
    }

    return (ParameterModule*)cls;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load module data, return true is successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ActuatorDriverDataClass::LoadModule(
    ParameterFileSymbolTable* const table)
{
    bool result = true;

    if (!Loaded)
    {
        BYTE const alignment = table->Alignment;
        ActuatorDriverDataClass* const cls = this;

        ParameterFileSymbolTableEntry  entryObj;
        ParameterFileSymbolTableEntry* const entry = &entryObj;
        result = table->Find(entryObj, SymbolTableID);

        if (!result)
        {
            PARAMETER_LOG_ERROR(entry->SetManager, "ActuatorDriverDataClass::LoadModule Failed to find module ID (%d) in Symbol Table\n", SymbolTableID);
        }

        if (result)
        {
            result = cls->Load(entry, alignment);
        }
        Modified++;
        Loaded = true;
    }

    if (!result)
    {
        /// Module failed to fully load, unload it
        UnloadModule();
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload module data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorDriverDataClass::UnloadModule()
{
    if (Loaded)
    {
        if (Data != nullptr && Data->SymbolTable != nullptr)
        {
            Unload(Data->SymbolTable);
        }
        else
        {
            PARAMETER_LOG_ERROR(Data != nullptr ? Data->SetManager : nullptr, "UnloadModule %s called with nullptr "
                "Data->SymbolTable object\n", Name);
            Unload(nullptr);
        }
        Loaded = false;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// /// Release the ParameterModule object
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ActuatorDriverDataClass::Release()
{
    ParameterModule::Release();
}

CAMX_NAMESPACE_END
