<commit_before>#include <gmock/gmock.h>
#include <string>
#include <utility>
#include <vector>

#include "action/action_service_impl.h"
#include "action/mocks/action_mock.h"

namespace {

using testing::_;
using testing::NiceMock;
using testing::Return;

using MockAction = NiceMock<dronecode_sdk::testing::MockAction>;
using ActionServiceImpl = dronecode_sdk::backend::ActionServiceImpl<MockAction>;

using ActionResult = dronecode_sdk::rpc::action::ActionResult;
using InputPair = std::pair<std::string, dronecode_sdk::ActionResult>;

static constexpr float ARBITRARY_ALTITUDE = 42.42f;
static constexpr float ARBITRARY_SPEED = 8.24f;

std::vector<InputPair> generateInputPairs();
std::string armAndGetTranslatedResult(dronecode_sdk::ActionResult arm_result);
std::string disarmAndGetTranslatedResult(dronecode_sdk::ActionResult disarm_result);
std::string takeoffAndGetTranslatedResult(dronecode_sdk::ActionResult takeoff_result);
std::string landAndGetTranslatedResult(dronecode_sdk::ActionResult land_result);
std::string killAndGetTranslatedResult(dronecode_sdk::ActionResult kill_result);
std::string returnToLaunchAndGetTranslatedResult(dronecode_sdk::ActionResult rtl_result);
std::string
transitionToFWAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result);
std::string
transitionToMCAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result);

class ActionServiceImplTest : public ::testing::TestWithParam<InputPair> {};

TEST_P(ActionServiceImplTest, armResultIsTranslatedCorrectly)
{
    const auto rpc_result = armAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string armAndGetTranslatedResult(const dronecode_sdk::ActionResult arm_result)
{
    MockAction action;
    ON_CALL(action, arm()).WillByDefault(Return(arm_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::ArmResponse response;

    actionService.Arm(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, armsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, arm()).Times(1);

    actionService.Arm(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, disarmResultIsTranslatedCorrectly)
{
    const auto rpc_result = disarmAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string disarmAndGetTranslatedResult(dronecode_sdk::ActionResult disarm_result)
{
    MockAction action;
    ON_CALL(action, disarm()).WillByDefault(Return(disarm_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::DisarmResponse response;

    actionService.Disarm(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, disarmsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, disarm()).Times(1);

    actionService.Disarm(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, takeoffResultIsTranslatedCorrectly)
{
    const auto rpc_result = takeoffAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string takeoffAndGetTranslatedResult(const dronecode_sdk::ActionResult takeoff_result)
{
    MockAction action;
    ON_CALL(action, takeoff()).WillByDefault(Return(takeoff_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TakeoffResponse response;

    actionService.Takeoff(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, takeoffEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, takeoff()).Times(1);

    actionService.Takeoff(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, landResultIsTranslatedCorrectly)
{
    const auto rpc_result = landAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string landAndGetTranslatedResult(const dronecode_sdk::ActionResult land_result)
{
    MockAction action;
    ON_CALL(action, land()).WillByDefault(Return(land_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::LandResponse response;

    actionService.Land(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, landsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, land()).Times(1);

    actionService.Land(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, killResultIsTranslatedCorrectly)
{
    const auto rpc_result = killAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string killAndGetTranslatedResult(const dronecode_sdk::ActionResult kill_result)
{
    MockAction action;
    ON_CALL(action, kill()).WillByDefault(Return(kill_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::KillResponse response;

    actionService.Kill(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, killsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, kill()).Times(1);

    actionService.Kill(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, rtlResultIsTranslatedCorrectly)
{
    const auto rpc_result = returnToLaunchAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string returnToLaunchAndGetTranslatedResult(const dronecode_sdk::ActionResult rtl_result)
{
    MockAction action;
    ON_CALL(action, return_to_launch()).WillByDefault(Return(rtl_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::ReturnToLaunchResponse response;

    actionService.ReturnToLaunch(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, rtlsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, return_to_launch()).Times(1);

    actionService.ReturnToLaunch(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, transition2fwResultIsTranslatedCorrectly)
{
    const auto rpc_result = transitionToFWAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string
transitionToFWAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result)
{
    MockAction action;
    ON_CALL(action, transition_to_fixedwing()).WillByDefault(Return(transition_to_fw_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TransitionToFixedWingResponse response;

    actionService.TransitionToFixedWing(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, transitions2fwEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, transition_to_fixedwing()).Times(1);

    actionService.TransitionToFixedWing(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, transition2mcResultIsTranslatedCorrectly)
{
    const auto rpc_result = transitionToMCAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string
transitionToMCAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_mc_result)
{
    MockAction action;
    ON_CALL(action, transition_to_multicopter()).WillByDefault(Return(transition_to_mc_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TransitionToMulticopterResponse response;

    actionService.TransitionToMulticopter(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, transitions2mcEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, transition_to_multicopter()).Times(1);

    actionService.TransitionToMulticopter(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, getTakeoffAltitudeCallsGetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, get_takeoff_altitude()).Times(1);
    dronecode_sdk::rpc::action::GetTakeoffAltitudeResponse response;

    actionService.GetTakeoffAltitude(nullptr, nullptr, &response);
}

TEST_P(ActionServiceImplTest, getsCorrectTakeoffAltitude)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_pair =
        std::make_pair<>(dronecode_sdk::ActionResult::SUCCESS, ARBITRARY_ALTITUDE);
    ON_CALL(action, get_takeoff_altitude()).WillByDefault(Return(expected_pair));
    dronecode_sdk::rpc::action::GetTakeoffAltitudeResponse response;

    actionService.GetTakeoffAltitude(nullptr, nullptr, &response);

    EXPECT_EQ(GetParam().first, ActionResult::Result_Name(response.action_result().result()));
    EXPECT_EQ(expected_pair.second, response.altitude());
}

TEST_F(ActionServiceImplTest, getTakeoffAltitudeDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.GetTakeoffAltitude(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, setTakeoffAltitudeDoesNotCrashWithNullRequest)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.SetTakeoffAltitude(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, setTakeoffAltitudeCallsSetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, set_takeoff_altitude(_)).Times(1);
    dronecode_sdk::rpc::action::SetTakeoffAltitudeRequest request;

    actionService.SetTakeoffAltitude(nullptr, &request, nullptr);
}

TEST_P(ActionServiceImplTest, setTakeoffAltitudeSetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    float expected_altitude = ARBITRARY_ALTITUDE;
    EXPECT_CALL(action, set_takeoff_altitude(expected_altitude)).Times(1);
    dronecode_sdk::rpc::action::SetTakeoffAltitudeRequest request;
    request.set_altitude(expected_altitude);

    actionService.SetTakeoffAltitude(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, getMaxSpeedDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.GetMaximumSpeed(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, getMaxSpeedCallsGetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, get_max_speed()).Times(1);
    dronecode_sdk::rpc::action::GetMaximumSpeedResponse response;

    actionService.GetMaximumSpeed(nullptr, nullptr, &response);
}

TEST_P(ActionServiceImplTest, getMaxSpeedGetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_pair =
        std::make_pair<>(dronecode_sdk::ActionResult::SUCCESS, ARBITRARY_SPEED);
    ON_CALL(action, get_max_speed()).WillByDefault(Return(expected_pair));
    dronecode_sdk::rpc::action::GetMaximumSpeedResponse response;

    actionService.GetMaximumSpeed(nullptr, nullptr, &response);

    EXPECT_EQ(GetParam().first, ActionResult::Result_Name(response.action_result().result()));
    EXPECT_EQ(expected_pair.second, response.speed());
}

TEST_F(ActionServiceImplTest, setMaxSpeedDoesNotCrashWithNullRequest)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::SetMaximumSpeedResponse response;

    actionService.SetMaximumSpeed(nullptr, nullptr, &response);
}

TEST_F(ActionServiceImplTest, setMaxSpeedDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;
    request.set_speed(ARBITRARY_SPEED);

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, setMaxSpeedCallsSetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, set_max_speed(_)).Times(1);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, setMaxSpeedSetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_speed = ARBITRARY_SPEED;
    EXPECT_CALL(action, set_max_speed(expected_speed)).Times(1);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;
    request.set_speed(expected_speed);

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

INSTANTIATE_TEST_CASE_P(ActionResultCorrespondences,
                        ActionServiceImplTest,
                        ::testing::ValuesIn(generateInputPairs()));

std::vector<InputPair> generateInputPairs()
{
    std::vector<InputPair> input_pairs;
    input_pairs.push_back(std::make_pair("SUCCESS", dronecode_sdk::ActionResult::SUCCESS));
    input_pairs.push_back(std::make_pair("NO_SYSTEM", dronecode_sdk::ActionResult::NO_SYSTEM));
    input_pairs.push_back(
        std::make_pair("CONNECTION_ERROR", dronecode_sdk::ActionResult::CONNECTION_ERROR));
    input_pairs.push_back(std::make_pair("BUSY", dronecode_sdk::ActionResult::BUSY));
    input_pairs.push_back(
        std::make_pair("COMMAND_DENIED", dronecode_sdk::ActionResult::COMMAND_DENIED));
    input_pairs.push_back(
        std::make_pair("COMMAND_DENIED_LANDED_STATE_UNKNOWN",
                       dronecode_sdk::ActionResult::COMMAND_DENIED_LANDED_STATE_UNKNOWN));
    input_pairs.push_back(std::make_pair("COMMAND_DENIED_NOT_LANDED",
                                         dronecode_sdk::ActionResult::COMMAND_DENIED_NOT_LANDED));
    input_pairs.push_back(std::make_pair("TIMEOUT", dronecode_sdk::ActionResult::TIMEOUT));
    input_pairs.push_back(
        std::make_pair("VTOL_TRANSITION_SUPPORT_UNKNOWN",
                       dronecode_sdk::ActionResult::VTOL_TRANSITION_SUPPORT_UNKNOWN));
    input_pairs.push_back(std::make_pair("NO_VTOL_TRANSITION_SUPPORT",
                                         dronecode_sdk::ActionResult::NO_VTOL_TRANSITION_SUPPORT));
    input_pairs.push_back(std::make_pair("UNKNOWN", dronecode_sdk::ActionResult::UNKNOWN));

    return input_pairs;
}

} // namespace
<commit_msg>backend: fix getsCorrectTakeoffAltitude and getMaxSpeedGetsRightValue unit tests<commit_after>#include <gmock/gmock.h>
#include <string>
#include <utility>
#include <vector>

#include "action/action_service_impl.h"
#include "action/mocks/action_mock.h"

namespace {

using testing::_;
using testing::NiceMock;
using testing::Return;

using MockAction = NiceMock<dronecode_sdk::testing::MockAction>;
using ActionServiceImpl = dronecode_sdk::backend::ActionServiceImpl<MockAction>;

using ActionResult = dronecode_sdk::rpc::action::ActionResult;
using InputPair = std::pair<std::string, dronecode_sdk::ActionResult>;

static constexpr float ARBITRARY_ALTITUDE = 42.42f;
static constexpr float ARBITRARY_SPEED = 8.24f;

std::vector<InputPair> generateInputPairs();
std::string armAndGetTranslatedResult(dronecode_sdk::ActionResult arm_result);
std::string disarmAndGetTranslatedResult(dronecode_sdk::ActionResult disarm_result);
std::string takeoffAndGetTranslatedResult(dronecode_sdk::ActionResult takeoff_result);
std::string landAndGetTranslatedResult(dronecode_sdk::ActionResult land_result);
std::string killAndGetTranslatedResult(dronecode_sdk::ActionResult kill_result);
std::string returnToLaunchAndGetTranslatedResult(dronecode_sdk::ActionResult rtl_result);
std::string
transitionToFWAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result);
std::string
transitionToMCAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result);

class ActionServiceImplTest : public ::testing::TestWithParam<InputPair> {};

TEST_P(ActionServiceImplTest, armResultIsTranslatedCorrectly)
{
    const auto rpc_result = armAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string armAndGetTranslatedResult(const dronecode_sdk::ActionResult arm_result)
{
    MockAction action;
    ON_CALL(action, arm()).WillByDefault(Return(arm_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::ArmResponse response;

    actionService.Arm(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, armsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, arm()).Times(1);

    actionService.Arm(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, disarmResultIsTranslatedCorrectly)
{
    const auto rpc_result = disarmAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string disarmAndGetTranslatedResult(dronecode_sdk::ActionResult disarm_result)
{
    MockAction action;
    ON_CALL(action, disarm()).WillByDefault(Return(disarm_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::DisarmResponse response;

    actionService.Disarm(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, disarmsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, disarm()).Times(1);

    actionService.Disarm(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, takeoffResultIsTranslatedCorrectly)
{
    const auto rpc_result = takeoffAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string takeoffAndGetTranslatedResult(const dronecode_sdk::ActionResult takeoff_result)
{
    MockAction action;
    ON_CALL(action, takeoff()).WillByDefault(Return(takeoff_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TakeoffResponse response;

    actionService.Takeoff(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, takeoffEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, takeoff()).Times(1);

    actionService.Takeoff(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, landResultIsTranslatedCorrectly)
{
    const auto rpc_result = landAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string landAndGetTranslatedResult(const dronecode_sdk::ActionResult land_result)
{
    MockAction action;
    ON_CALL(action, land()).WillByDefault(Return(land_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::LandResponse response;

    actionService.Land(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, landsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, land()).Times(1);

    actionService.Land(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, killResultIsTranslatedCorrectly)
{
    const auto rpc_result = killAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string killAndGetTranslatedResult(const dronecode_sdk::ActionResult kill_result)
{
    MockAction action;
    ON_CALL(action, kill()).WillByDefault(Return(kill_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::KillResponse response;

    actionService.Kill(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, killsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, kill()).Times(1);

    actionService.Kill(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, rtlResultIsTranslatedCorrectly)
{
    const auto rpc_result = returnToLaunchAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string returnToLaunchAndGetTranslatedResult(const dronecode_sdk::ActionResult rtl_result)
{
    MockAction action;
    ON_CALL(action, return_to_launch()).WillByDefault(Return(rtl_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::ReturnToLaunchResponse response;

    actionService.ReturnToLaunch(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, rtlsEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, return_to_launch()).Times(1);

    actionService.ReturnToLaunch(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, transition2fwResultIsTranslatedCorrectly)
{
    const auto rpc_result = transitionToFWAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string
transitionToFWAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_fw_result)
{
    MockAction action;
    ON_CALL(action, transition_to_fixedwing()).WillByDefault(Return(transition_to_fw_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TransitionToFixedWingResponse response;

    actionService.TransitionToFixedWing(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, transitions2fwEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, transition_to_fixedwing()).Times(1);

    actionService.TransitionToFixedWing(nullptr, nullptr, nullptr);
}

TEST_P(ActionServiceImplTest, transition2mcResultIsTranslatedCorrectly)
{
    const auto rpc_result = transitionToMCAndGetTranslatedResult(GetParam().second);
    EXPECT_EQ(rpc_result, GetParam().first);
}

std::string
transitionToMCAndGetTranslatedResult(const dronecode_sdk::ActionResult transition_to_mc_result)
{
    MockAction action;
    ON_CALL(action, transition_to_multicopter()).WillByDefault(Return(transition_to_mc_result));
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::TransitionToMulticopterResponse response;

    actionService.TransitionToMulticopter(nullptr, nullptr, &response);

    return ActionResult::Result_Name(response.action_result().result());
}

TEST_F(ActionServiceImplTest, transitions2mcEvenWhenArgsAreNull)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, transition_to_multicopter()).Times(1);

    actionService.TransitionToMulticopter(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, getTakeoffAltitudeCallsGetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, get_takeoff_altitude()).Times(1);
    dronecode_sdk::rpc::action::GetTakeoffAltitudeResponse response;

    actionService.GetTakeoffAltitude(nullptr, nullptr, &response);
}

TEST_P(ActionServiceImplTest, getsCorrectTakeoffAltitude)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_pair = std::make_pair<>(GetParam().second, ARBITRARY_ALTITUDE);
    ON_CALL(action, get_takeoff_altitude()).WillByDefault(Return(expected_pair));
    dronecode_sdk::rpc::action::GetTakeoffAltitudeResponse response;

    actionService.GetTakeoffAltitude(nullptr, nullptr, &response);

    EXPECT_EQ(GetParam().first, ActionResult::Result_Name(response.action_result().result()));
    EXPECT_EQ(expected_pair.second, response.altitude());
}

TEST_F(ActionServiceImplTest, getTakeoffAltitudeDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.GetTakeoffAltitude(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, setTakeoffAltitudeDoesNotCrashWithNullRequest)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.SetTakeoffAltitude(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, setTakeoffAltitudeCallsSetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, set_takeoff_altitude(_)).Times(1);
    dronecode_sdk::rpc::action::SetTakeoffAltitudeRequest request;

    actionService.SetTakeoffAltitude(nullptr, &request, nullptr);
}

TEST_P(ActionServiceImplTest, setTakeoffAltitudeSetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    float expected_altitude = ARBITRARY_ALTITUDE;
    EXPECT_CALL(action, set_takeoff_altitude(expected_altitude)).Times(1);
    dronecode_sdk::rpc::action::SetTakeoffAltitudeRequest request;
    request.set_altitude(expected_altitude);

    actionService.SetTakeoffAltitude(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, getMaxSpeedDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);

    actionService.GetMaximumSpeed(nullptr, nullptr, nullptr);
}

TEST_F(ActionServiceImplTest, getMaxSpeedCallsGetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, get_max_speed()).Times(1);
    dronecode_sdk::rpc::action::GetMaximumSpeedResponse response;

    actionService.GetMaximumSpeed(nullptr, nullptr, &response);
}

TEST_P(ActionServiceImplTest, getMaxSpeedGetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_pair = std::make_pair<>(GetParam().second, ARBITRARY_SPEED);
    ON_CALL(action, get_max_speed()).WillByDefault(Return(expected_pair));
    dronecode_sdk::rpc::action::GetMaximumSpeedResponse response;

    actionService.GetMaximumSpeed(nullptr, nullptr, &response);

    EXPECT_EQ(GetParam().first, ActionResult::Result_Name(response.action_result().result()));
    EXPECT_EQ(expected_pair.second, response.speed());
}

TEST_F(ActionServiceImplTest, setMaxSpeedDoesNotCrashWithNullRequest)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::SetMaximumSpeedResponse response;

    actionService.SetMaximumSpeed(nullptr, nullptr, &response);
}

TEST_F(ActionServiceImplTest, setMaxSpeedDoesNotCrashWithNullResponse)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;
    request.set_speed(ARBITRARY_SPEED);

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, setMaxSpeedCallsSetter)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    EXPECT_CALL(action, set_max_speed(_)).Times(1);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

TEST_F(ActionServiceImplTest, setMaxSpeedSetsRightValue)
{
    MockAction action;
    ActionServiceImpl actionService(action);
    const auto expected_speed = ARBITRARY_SPEED;
    EXPECT_CALL(action, set_max_speed(expected_speed)).Times(1);
    dronecode_sdk::rpc::action::SetMaximumSpeedRequest request;
    request.set_speed(expected_speed);

    actionService.SetMaximumSpeed(nullptr, &request, nullptr);
}

INSTANTIATE_TEST_CASE_P(ActionResultCorrespondences,
                        ActionServiceImplTest,
                        ::testing::ValuesIn(generateInputPairs()));

std::vector<InputPair> generateInputPairs()
{
    std::vector<InputPair> input_pairs;
    input_pairs.push_back(std::make_pair("SUCCESS", dronecode_sdk::ActionResult::SUCCESS));
    input_pairs.push_back(std::make_pair("NO_SYSTEM", dronecode_sdk::ActionResult::NO_SYSTEM));
    input_pairs.push_back(
        std::make_pair("CONNECTION_ERROR", dronecode_sdk::ActionResult::CONNECTION_ERROR));
    input_pairs.push_back(std::make_pair("BUSY", dronecode_sdk::ActionResult::BUSY));
    input_pairs.push_back(
        std::make_pair("COMMAND_DENIED", dronecode_sdk::ActionResult::COMMAND_DENIED));
    input_pairs.push_back(
        std::make_pair("COMMAND_DENIED_LANDED_STATE_UNKNOWN",
                       dronecode_sdk::ActionResult::COMMAND_DENIED_LANDED_STATE_UNKNOWN));
    input_pairs.push_back(std::make_pair("COMMAND_DENIED_NOT_LANDED",
                                         dronecode_sdk::ActionResult::COMMAND_DENIED_NOT_LANDED));
    input_pairs.push_back(std::make_pair("TIMEOUT", dronecode_sdk::ActionResult::TIMEOUT));
    input_pairs.push_back(
        std::make_pair("VTOL_TRANSITION_SUPPORT_UNKNOWN",
                       dronecode_sdk::ActionResult::VTOL_TRANSITION_SUPPORT_UNKNOWN));
    input_pairs.push_back(std::make_pair("NO_VTOL_TRANSITION_SUPPORT",
                                         dronecode_sdk::ActionResult::NO_VTOL_TRANSITION_SUPPORT));
    input_pairs.push_back(std::make_pair("UNKNOWN", dronecode_sdk::ActionResult::UNKNOWN));

    return input_pairs;
}

} // namespace
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org.  If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/

#include "precompiled_configmgr.hxx"
#include "sal/config.h"

#include <vector>

#include "com/sun/star/container/XChild.hpp"
#include "com/sun/star/lang/NoSupportException.hpp"
#include "com/sun/star/lang/XUnoTunnel.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/Type.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "rtl/ref.hxx"
#include "rtl/string.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "rtl/uuid.h"
#include "sal/types.h"

#include "access.hxx"
#include "childaccess.hxx"
#include "components.hxx"
#include "data.hxx"
#include "groupnode.hxx"
#include "localizedpropertynode.hxx"
#include "localizedvaluenode.hxx"
#include "lock.hxx"
#include "modifications.hxx"
#include "node.hxx"
#include "path.hxx"
#include "propertynode.hxx"
#include "rootaccess.hxx"
#include "setnode.hxx"
#include "type.hxx"

namespace configmgr {

namespace {

namespace css = com::sun::star;

}

css::uno::Sequence< sal_Int8 > ChildAccess::getTunnelId() {
    static css::uno::Sequence< sal_Int8 > id;
    if (id.getLength() == 0) {
        css::uno::Sequence< sal_Int8 > uuid(16);
        rtl_createUuid(
            reinterpret_cast< sal_uInt8 * >(uuid.getArray()), 0, false);
        id = uuid;
    }
    return id;
}

ChildAccess::ChildAccess(
    Components & components, rtl::Reference< RootAccess > const & root,
    rtl::Reference< Access > const & parent, rtl::OUString const & name,
    rtl::Reference< Node > const & node):
    Access(components), root_(root), parent_(parent), name_(name), node_(node),
    inTransaction_(false)
{
    lock_ = lock();
    OSL_ASSERT(root.is() && parent.is() && node.is());
}

ChildAccess::ChildAccess(
    Components & components, rtl::Reference< RootAccess > const & root,
    rtl::Reference< Node > const & node):
    Access(components), root_(root), node_(node), inTransaction_(false)
{
    lock_ = lock();
    OSL_ASSERT(root.is() && node.is());
}

Path ChildAccess::getAbsolutePath() {
    OSL_ASSERT(getParentAccess().is());
    Path path(getParentAccess()->getAbsolutePath());
    path.push_back(name_);
    return path;
}

Path ChildAccess::getRelativePath() {
    Path path;
    rtl::Reference< Access > parent(getParentAccess());
    if (parent.is()) {
        path = parent->getRelativePath();
    }
    path.push_back(name_);
    return path;
}

rtl::OUString ChildAccess::getRelativePathRepresentation() {
    rtl::OUStringBuffer path;
    rtl::Reference< Access > parent(getParentAccess());
    if (parent.is()) {
        path.append(parent->getRelativePathRepresentation());
        if (path.getLength() != 0) {
            path.append(sal_Unicode('/'));
        }
    }
    path.append(Data::createSegment(node_->getTemplateName(), name_));
    return path.makeStringAndClear();
}

rtl::Reference< Node > ChildAccess::getNode() {
    return node_;
}

bool ChildAccess::isFinalized() {
    return node_->getFinalized() != Data::NO_LAYER ||
        (parent_.is() && parent_->isFinalized());
}

rtl::OUString ChildAccess::getNameInternal() {
    return name_;
}

rtl::Reference< RootAccess > ChildAccess::getRootAccess() {
    return root_;
}

rtl::Reference< Access > ChildAccess::getParentAccess() {
    return parent_;
}

void ChildAccess::acquire() throw () {
    Access::acquire();
}

void ChildAccess::release() throw () {
    Access::release();
}

css::uno::Reference< css::uno::XInterface > ChildAccess::getParent()
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    return static_cast< cppu::OWeakObject * >(parent_.get());
}

void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &)
    throw (css::lang::NoSupportException, css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    throw css::lang::NoSupportException(
        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("setParent")),
        static_cast< cppu::OWeakObject * >(this));
}

sal_Int64 ChildAccess::getSomething(
    css::uno::Sequence< sal_Int8 > const & aIdentifier)
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    return aIdentifier == getTunnelId()
        ? reinterpret_cast< sal_Int64 >(this) : 0;
}

void ChildAccess::bind(
    rtl::Reference< RootAccess > const & root,
    rtl::Reference< Access > const & parent, rtl::OUString const & name)
    throw ()
{
    OSL_ASSERT(
        !parent_.is() && root.is() && parent.is() && name.getLength() != 0);
    root_ = root;
    parent_ = parent;
    name_ = name;
}

void ChildAccess::unbind() throw () {
    OSL_ASSERT(parent_.is());
    parent_->releaseChild(name_);
    parent_.clear();
    inTransaction_ = true;
}

void ChildAccess::committed() {
    inTransaction_ = false;
}

void ChildAccess::setNode(rtl::Reference< Node > const & node) {
    node_ = node;
}

void ChildAccess::setProperty(
    css::uno::Any const & value, Modifications * localModifications)
{
    OSL_ASSERT(localModifications != 0);
    Type type = TYPE_ERROR;
    bool nillable = false;
    switch (node_->kind()) {
    case Node::KIND_PROPERTY:
        {
            PropertyNode * prop = dynamic_cast< PropertyNode * >(node_.get());
            type = prop->getStaticType();
            nillable = prop->isNillable();
        }
        break;
    case Node::KIND_LOCALIZED_PROPERTY:
        {
            rtl::OUString locale(getRootAccess()->getLocale());
            if (!Components::allLocales(locale)) {
                rtl::Reference< ChildAccess > child(getChild(locale));
                if (child.is()) {
                    child->setProperty(value, localModifications);
                } else {
                    insertLocalizedValueChild(
                        locale, value, localModifications);
                }
                return;
            }
        }
        break;
    case Node::KIND_LOCALIZED_VALUE:
        {
            LocalizedPropertyNode * locprop =
                dynamic_cast< LocalizedPropertyNode * >(getParentNode().get());
            type = locprop->getStaticType();
            nillable = locprop->isNillable();
        }
        break;
    default:
        break;
    }
    checkValue(value, type, nillable);
    getParentAccess()->markChildAsModified(this);
    changedValue_.reset(new css::uno::Any(value));
    localModifications->add(getRelativePath());
}

css::uno::Any ChildAccess::asValue() {
    if (changedValue_.get() != 0) {
        return *changedValue_;
    }
    switch (node_->kind()) {
    case Node::KIND_PROPERTY:
        return dynamic_cast< PropertyNode * >(node_.get())->getValue(
            getComponents());
    case Node::KIND_LOCALIZED_PROPERTY:
        {
            rtl::OUString locale(getRootAccess()->getLocale());
            if (!Components::allLocales(locale)) {
                // Find best match using an adaption of RFC 4647 lookup matching
                // rules, removing "-" or "_" delimited segments from the end;
                // defaults are the "en-US" locale, the "en" locale, the empty
                // string locale, the first child (if any), or a nil value (even
                // though it may be illegal for the given property), in that
                // order:
                rtl::Reference< ChildAccess > child;
                for (;;) {
                    child = getChild(locale);
                    if (child.is() || locale.getLength() == 0) {
                        break;
                    }
                    sal_Int32 i = locale.getLength() - 1;
                    while (i > 0 && locale[i] != '-' && locale[i] != '_') {
                        --i;
                    }
                    if (i == 0) {
                        break;
                    }
                    locale = locale.copy(0, i);
                }
                if (!child.is()) {
                    child = getChild(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US")));
                    if (!child.is()) {
                        child = getChild(
                            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")));
                        if (!child.is()) {
                            child = getChild(rtl::OUString());
                            if (!child.is()) {
                                std::vector< rtl::Reference< ChildAccess > >
                                    all(getAllChildren());
                                if (!all.empty()) {
                                    child = all.front();
                                }
                            }
                        }
                    }
                }
                return child.is() ? child->asValue() : css::uno::Any();
            }
        }
        break;
    case Node::KIND_LOCALIZED_VALUE:
        return dynamic_cast< LocalizedValueNode * >(node_.get())->getValue();
    default:
        break;
    }
    return css::uno::makeAny(
        css::uno::Reference< css::uno::XInterface >(
            static_cast< cppu::OWeakObject * >(this)));
}

void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
{
    OSL_ASSERT(globalModifications != 0);
    commitChildChanges(valid, globalModifications);
    if (valid && changedValue_.get() != 0) {
        Path path(getAbsolutePath());
        getComponents().addModification(path);
        globalModifications->add(path);
        switch (node_->kind()) {
        case Node::KIND_PROPERTY:
            dynamic_cast< PropertyNode * >(node_.get())->setValue(
                Data::NO_LAYER, *changedValue_);
            break;
        case Node::KIND_LOCALIZED_VALUE:
            dynamic_cast< LocalizedValueNode * >(node_.get())->setValue(
                Data::NO_LAYER, *changedValue_);
            break;
        default:
            OSL_ASSERT(false); // this cannot happen
            break;
        }
    }
    changedValue_.reset();
}

ChildAccess::~ChildAccess() {
    osl::MutexGuard g(*lock_);
    if (parent_.is()) {
        parent_->releaseChild(name_);
    }
}

void ChildAccess::addTypes(std::vector< css::uno::Type > * types) const {
    OSL_ASSERT(types != 0);
    types->push_back(cppu::UnoType< css::container::XChild >::get());
    types->push_back(cppu::UnoType< css::lang::XUnoTunnel >::get());
}

void ChildAccess::addSupportedServiceNames(
    std::vector< rtl::OUString > * services)
{
    OSL_ASSERT(services != 0);
    services->push_back(
        getParentNode()->kind() == Node::KIND_GROUP
        ? rtl::OUString(
            RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.GroupElement"))
        : rtl::OUString(
            RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.SetElement")));
}

css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    css::uno::Any res(Access::queryInterface(aType));
    return res.hasValue()
        ? res
        : cppu::queryInterface(
            aType, static_cast< css::container::XChild * >(this),
            static_cast< css::lang::XUnoTunnel * >(this));
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Resolves: fdo#33638 add extra level of language tag matching<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org.  If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/

#include "precompiled_configmgr.hxx"
#include "sal/config.h"

#include <vector>

#include "com/sun/star/container/XChild.hpp"
#include "com/sun/star/lang/NoSupportException.hpp"
#include "com/sun/star/lang/XUnoTunnel.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/Type.hxx"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/weak.hxx"
#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "rtl/ref.hxx"
#include "rtl/string.h"
#include "rtl/ustrbuf.hxx"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "rtl/uuid.h"
#include "sal/types.h"

#include "access.hxx"
#include "childaccess.hxx"
#include "components.hxx"
#include "data.hxx"
#include "groupnode.hxx"
#include "localizedpropertynode.hxx"
#include "localizedvaluenode.hxx"
#include "lock.hxx"
#include "modifications.hxx"
#include "node.hxx"
#include "path.hxx"
#include "propertynode.hxx"
#include "rootaccess.hxx"
#include "setnode.hxx"
#include "type.hxx"

namespace configmgr {

namespace {

namespace css = com::sun::star;

}

css::uno::Sequence< sal_Int8 > ChildAccess::getTunnelId() {
    static css::uno::Sequence< sal_Int8 > id;
    if (id.getLength() == 0) {
        css::uno::Sequence< sal_Int8 > uuid(16);
        rtl_createUuid(
            reinterpret_cast< sal_uInt8 * >(uuid.getArray()), 0, false);
        id = uuid;
    }
    return id;
}

ChildAccess::ChildAccess(
    Components & components, rtl::Reference< RootAccess > const & root,
    rtl::Reference< Access > const & parent, rtl::OUString const & name,
    rtl::Reference< Node > const & node):
    Access(components), root_(root), parent_(parent), name_(name), node_(node),
    inTransaction_(false)
{
    lock_ = lock();
    OSL_ASSERT(root.is() && parent.is() && node.is());
}

ChildAccess::ChildAccess(
    Components & components, rtl::Reference< RootAccess > const & root,
    rtl::Reference< Node > const & node):
    Access(components), root_(root), node_(node), inTransaction_(false)
{
    lock_ = lock();
    OSL_ASSERT(root.is() && node.is());
}

Path ChildAccess::getAbsolutePath() {
    OSL_ASSERT(getParentAccess().is());
    Path path(getParentAccess()->getAbsolutePath());
    path.push_back(name_);
    return path;
}

Path ChildAccess::getRelativePath() {
    Path path;
    rtl::Reference< Access > parent(getParentAccess());
    if (parent.is()) {
        path = parent->getRelativePath();
    }
    path.push_back(name_);
    return path;
}

rtl::OUString ChildAccess::getRelativePathRepresentation() {
    rtl::OUStringBuffer path;
    rtl::Reference< Access > parent(getParentAccess());
    if (parent.is()) {
        path.append(parent->getRelativePathRepresentation());
        if (path.getLength() != 0) {
            path.append(sal_Unicode('/'));
        }
    }
    path.append(Data::createSegment(node_->getTemplateName(), name_));
    return path.makeStringAndClear();
}

rtl::Reference< Node > ChildAccess::getNode() {
    return node_;
}

bool ChildAccess::isFinalized() {
    return node_->getFinalized() != Data::NO_LAYER ||
        (parent_.is() && parent_->isFinalized());
}

rtl::OUString ChildAccess::getNameInternal() {
    return name_;
}

rtl::Reference< RootAccess > ChildAccess::getRootAccess() {
    return root_;
}

rtl::Reference< Access > ChildAccess::getParentAccess() {
    return parent_;
}

void ChildAccess::acquire() throw () {
    Access::acquire();
}

void ChildAccess::release() throw () {
    Access::release();
}

css::uno::Reference< css::uno::XInterface > ChildAccess::getParent()
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    return static_cast< cppu::OWeakObject * >(parent_.get());
}

void ChildAccess::setParent(css::uno::Reference< css::uno::XInterface > const &)
    throw (css::lang::NoSupportException, css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    throw css::lang::NoSupportException(
        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("setParent")),
        static_cast< cppu::OWeakObject * >(this));
}

sal_Int64 ChildAccess::getSomething(
    css::uno::Sequence< sal_Int8 > const & aIdentifier)
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    return aIdentifier == getTunnelId()
        ? reinterpret_cast< sal_Int64 >(this) : 0;
}

void ChildAccess::bind(
    rtl::Reference< RootAccess > const & root,
    rtl::Reference< Access > const & parent, rtl::OUString const & name)
    throw ()
{
    OSL_ASSERT(
        !parent_.is() && root.is() && parent.is() && name.getLength() != 0);
    root_ = root;
    parent_ = parent;
    name_ = name;
}

void ChildAccess::unbind() throw () {
    OSL_ASSERT(parent_.is());
    parent_->releaseChild(name_);
    parent_.clear();
    inTransaction_ = true;
}

void ChildAccess::committed() {
    inTransaction_ = false;
}

void ChildAccess::setNode(rtl::Reference< Node > const & node) {
    node_ = node;
}

void ChildAccess::setProperty(
    css::uno::Any const & value, Modifications * localModifications)
{
    OSL_ASSERT(localModifications != 0);
    Type type = TYPE_ERROR;
    bool nillable = false;
    switch (node_->kind()) {
    case Node::KIND_PROPERTY:
        {
            PropertyNode * prop = dynamic_cast< PropertyNode * >(node_.get());
            type = prop->getStaticType();
            nillable = prop->isNillable();
        }
        break;
    case Node::KIND_LOCALIZED_PROPERTY:
        {
            rtl::OUString locale(getRootAccess()->getLocale());
            if (!Components::allLocales(locale)) {
                rtl::Reference< ChildAccess > child(getChild(locale));
                if (child.is()) {
                    child->setProperty(value, localModifications);
                } else {
                    insertLocalizedValueChild(
                        locale, value, localModifications);
                }
                return;
            }
        }
        break;
    case Node::KIND_LOCALIZED_VALUE:
        {
            LocalizedPropertyNode * locprop =
                dynamic_cast< LocalizedPropertyNode * >(getParentNode().get());
            type = locprop->getStaticType();
            nillable = locprop->isNillable();
        }
        break;
    default:
        break;
    }
    checkValue(value, type, nillable);
    getParentAccess()->markChildAsModified(this);
    changedValue_.reset(new css::uno::Any(value));
    localModifications->add(getRelativePath());
}

namespace
{
    rtl::OUString lcl_StripSegment(const rtl::OUString &rLocale)
    {
        sal_Int32 i = rLocale.getLength() ? rLocale.getLength() - 1 : 0;
        while (i > 0 && rLocale[i] != '-' && rLocale[i] != '_')
            --i;
        return rLocale.copy(0, i);
    }
}

css::uno::Any ChildAccess::asValue() {
    if (changedValue_.get() != 0) {
        return *changedValue_;
    }
    switch (node_->kind()) {
    case Node::KIND_PROPERTY:
        return dynamic_cast< PropertyNode * >(node_.get())->getValue(
            getComponents());
    case Node::KIND_LOCALIZED_PROPERTY:
        {
            rtl::OUString sLocale(getRootAccess()->getLocale());
            if (!Components::allLocales(sLocale))
            {
                rtl::Reference< ChildAccess > child;
                // Find best match using an adaption of RFC 4647 lookup matching
                // rules, removing "-" or "_" delimited segments from the end
                while (1)
                {
                    child = getChild(sLocale);
                    if (child.is())
                        break;
                    rtl::OUString sTmpLocale = lcl_StripSegment(sLocale);
                    if (!sTmpLocale.getLength())
                        break;
                    sLocale = sTmpLocale;
                }

                //Resolves: fdo#33638 Look for the first entry with the same
                //first segment as the requested language tag, before falling
                //back to en-US, etc.
                typedef std::vector< rtl::Reference< ChildAccess > > ChildVector;
                if (!child.is())
                {
                    const ChildVector &rAllChildren = getAllChildren();
                    for (ChildVector::const_iterator aI = rAllChildren.begin(),
                         aEnd = rAllChildren.end(); aI != aEnd; ++aI)
                    {
                        rtl::OUString sLanguage = lcl_StripSegment((*aI)->getNameInternal());
                        if (sLocale == sLanguage)
                        {
                            child = *aI;
                            break;
                        }
                    }
                }

                // defaults are the "en-US" locale, the "en" locale, the empty
                // string locale, the first child (if any), or a nil value (even
                // though it may be illegal for the given property), in that
                // order:
                if (!child.is())
                {
                    child = getChild(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US")));
                    if (!child.is())
                    {
                        child = getChild(
                            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")));
                        if (!child.is())
                        {
                            child = getChild(rtl::OUString());
                            if (!child.is())
                            {
                                ChildVector all(getAllChildren());
                                if (!all.empty())
                                    child = all.front();
                            }
                        }
                    }
                }
                return child.is() ? child->asValue() : css::uno::Any();
            }
        }
        break;
    case Node::KIND_LOCALIZED_VALUE:
        return dynamic_cast< LocalizedValueNode * >(node_.get())->getValue();
    default:
        break;
    }
    return css::uno::makeAny(
        css::uno::Reference< css::uno::XInterface >(
            static_cast< cppu::OWeakObject * >(this)));
}

void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
{
    OSL_ASSERT(globalModifications != 0);
    commitChildChanges(valid, globalModifications);
    if (valid && changedValue_.get() != 0) {
        Path path(getAbsolutePath());
        getComponents().addModification(path);
        globalModifications->add(path);
        switch (node_->kind()) {
        case Node::KIND_PROPERTY:
            dynamic_cast< PropertyNode * >(node_.get())->setValue(
                Data::NO_LAYER, *changedValue_);
            break;
        case Node::KIND_LOCALIZED_VALUE:
            dynamic_cast< LocalizedValueNode * >(node_.get())->setValue(
                Data::NO_LAYER, *changedValue_);
            break;
        default:
            OSL_ASSERT(false); // this cannot happen
            break;
        }
    }
    changedValue_.reset();
}

ChildAccess::~ChildAccess() {
    osl::MutexGuard g(*lock_);
    if (parent_.is()) {
        parent_->releaseChild(name_);
    }
}

void ChildAccess::addTypes(std::vector< css::uno::Type > * types) const {
    OSL_ASSERT(types != 0);
    types->push_back(cppu::UnoType< css::container::XChild >::get());
    types->push_back(cppu::UnoType< css::lang::XUnoTunnel >::get());
}

void ChildAccess::addSupportedServiceNames(
    std::vector< rtl::OUString > * services)
{
    OSL_ASSERT(services != 0);
    services->push_back(
        getParentNode()->kind() == Node::KIND_GROUP
        ? rtl::OUString(
            RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.GroupElement"))
        : rtl::OUString(
            RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.SetElement")));
}

css::uno::Any ChildAccess::queryInterface(css::uno::Type const & aType)
    throw (css::uno::RuntimeException)
{
    OSL_ASSERT(thisIs(IS_ANY));
    osl::MutexGuard g(*lock_);
    checkLocalizedPropertyAccess();
    css::uno::Any res(Access::queryInterface(aType));
    return res.hasValue()
        ? res
        : cppu::queryInterface(
            aType, static_cast< css::container::XChild * >(this),
            static_cast< css::lang::XUnoTunnel * >(this));
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "BtuLinear.h"

BtuLinear::BtuLinear():
    m_depthPid(DEP_KC, DEP_KI, DEP_KD, PID_FREQ, DEPTH_MIN, DEPTH_MAX, VEL_MIN, VEL_MAX, 0),
    m_actA(PIN_ACTA_PWM, PIN_ACTA_DIR, PIN_ACTA_POT, PID_FREQ),
    m_actB(PIN_ACTB_PWM, PIN_ACTB_DIR, PIN_ACTB_POT, PID_FREQ),
	m_pressureSensor(PIN_IMU_SDA, PIN_IMU_SCL),
    m_dryRunPot(DRY_RUN_POT_PIN)
{
    m_dryRun = false;
};

BtuLinear::BtuLinear(bool dryRun):
    m_depthPid(DEP_K_C, DEP_TAU_I, DEP_TAU_D, PID_FREQ, DEPTH_MIN, DEPTH_MAX, VEL_MIN, VEL_MAX, 0),
    m_actA(PIN_ACTA_PWM, PIN_ACTA_DIR, PIN_ACTA_POT, PID_FREQ),
    m_actB(PIN_ACTB_PWM, PIN_ACTB_DIR, PIN_ACTB_POT, PID_FREQ),
	m_pressureSensor(PIN_IMU_SDA, PIN_IMU_SCL),
    m_dryRunPot(DRY_RUN_POT_PIN)
{
    m_dryRun = dryRun;
};

BtuLinear::~BtuLinear(){}

void BtuLinear::init() {
    m_mode = DEFAULT_CTRL_MODE;

    // default gain values for depth controller
    m_kc = DEP_KC;
    m_kI = DEP_KI;
    m_kD = DEP_KD;

    // default gain values for position controller
    m_p_kc = POS_KC;
    m_p_kI = POS_KI;
    m_p_kD = POS_KD;

    // default gain values for velocity controller
    m_v_kc = VEL_KC;
    m_v_kI = VEL_KI;
    m_v_kD = VEL_KD;

    // initialize Pressure Sensor
    m_pressureSensor.MS5837Init();
    m_pressureSensor.MS5837Start();
    wait(0.1);                    // remnant from old BTU class TODO: check if can be removed

    // initialize the actuators
    m_actA.reset();
    m_actB.reset();

    // initialize the Windows for SMA to 0
    // for(int i = 0; i < AVG_WINDOW_WIDTH; i++) {
    //     m_avg_windowA[i] = 0;
    //     m_avg_windowB[i] = 0;
    // }

    // initialize starting voltage for velocity control to 0
    // m_currentVoltage = 0;
}

// return a pressure reading
float BtuLinear::getPressure() {
    return m_pressureSensor.MS5837_Pressure();
}

// resets values of the controllers
void BtuLinear::stop() {
	m_depthPid.reset();
    m_actA.reset();
    m_actB.reset();
	return;
}

// updates depth PID tunings
void BtuLinear::updateDepthTunings(float kc, float kI, float kD) {
    m_kc = kc;
    m_kI = kI;
    m_kD = kD;
    m_depthPid.setTunings(kc, kI, kD);
}

// updates Position PID tunings
void BtuLinear::updatePosTunings(float kc, float kI, float kD) {
    m_p_kc = kc;
    m_p_kI = kI;
    m_p_kD = kD;
    m_actA.setPosTunings(kc, kI, kD);
    m_actB.setPosTunings(kc, kI, kD);
}

// updates Velocity PID tunings
void BtuLinear::updateVelTunings(float kc, float kI, float kD) {
    m_v_kc = kc;
    m_v_kI = kI;
    m_v_kD = kD;
    m_actA.setVelTunings(kc, kI, kD);
    m_actB.setVelTunings(kc, kI, kD);
}

// updates Mode.  Resets most values if the mode has changed
void BtuLinear::updateMode(int mode) {
    if(m_mode != mode) {
        stop();
        m_mode = mode;
    }
}

// runs one cycle of the controller dictated by mode
void BtuLinear::runCycle(float setVal) {
    switch (m_mode) {

    case VOLTAGE_CTRL_MODE:
        voltageControl(setVal);
        break;

    case VELOCITY_CTRL_MODE:
        velocityControl(setVal);
        break;

    case DEPTH_CTRL_MODE:
        depthControl(setVal);
        break;

    case POSITION_CTRL_MODE:
        positionControl(setVal);
        break;
    }
}

// convenience function, updates mode, then runs a cycle in the chosen mode
void BtuLinear::updateAndRunCycle(int mode, float value) {
    updateMode(mode);
    runCycle(value);
}

// calls voltageControlHelper on both actuators
void BtuLinear::voltageControl(float setDuty) {
    m_actA.runVoltControl(setDuty);
    m_actB.runVoltControl(setDuty);
}

// updates the SMA window with the current position reading
/*
void BtuLinear::updatePositionReadings() {
    float aPosition = m_actAPot;
    float bPosition = m_actBPot;

    float aOldPos = m_avg_windowA[m_avg_windowPtr];
    float bOldPos = m_avg_windowB[m_avg_windowPtr];
    m_avg_windowA[m_avg_windowPtr] = aPosition;
    m_avg_windowB[m_avg_windowPtr] = bPosition;
    m_avg_windowPtr = (m_avg_windowPtr+1) % AVG_WINDOW_WIDTH;
    if(m_avg_windowSize >= AVG_WINDOW_WIDTH) {
        // buffer is full
    	m_currentAvgA = m_currentAvgA + (aPosition / AVG_WINDOW_WIDTH)- (aOldPos / AVG_WINDOW_WIDTH);
        m_currentAvgB = m_currentAvgB + (bPosition / AVG_WINDOW_WIDTH)- (bOldPos / AVG_WINDOW_WIDTH);
    } else {
    	// buffer is still filling up
        m_avg_windowSize++;
        m_currentAvgA = 0;
        m_currentAvgB = 0;
        for(int i = 0; i < m_avg_windowSize; i++) {
            m_currentAvgA = (m_avg_windowA[i] / m_avg_windowSize);
            m_currentAvgB = (m_avg_windowB[i] / m_avg_windowSize);
        }
    }
}
*/

// gets the current Actuator Position.  No SMA, just reads and rescales the potentiometer
float BtuLinear::getActPosition(int act) {
    if(act == ACT_A) {
        return m_actA.getPosition();
    } else {
        return m_actB.getPosition();
    }
}

// does velocity control on both actuators
void BtuLinear::velocityControl(float setVel) {
    m_actA.runVelControl(setVel);
    m_actB.runVelControl(setVel);
}

// control position of both actuators
void BtuLinear::positionControl(float setPos) {
    m_actA.runPosControl(setPos);
    m_actB.runPosControl(setPos);
}

// control depth via master-slave
void BtuLinear::depthControlHelper(float cmdVoltage) {
	// control velocity on one actuator
    m_actA.runVoltControl(cmdVoltage);
    // have the second mirror the first
    m_actB.runPosControl(m_actA.getPosition());
}

// do depth control
void BtuLinear::depthControl(float setDepthMeters) {
    float curDepth = getDepth();

    m_depthPid.setProcessValue(curDepth);
	m_depthPid.setSetPoint(setDepthMeters);

    float cmdVolt = m_depthPid.compute();

    // extending the actuator increases buoyancy -> less depth
    // therefore the axis direction has to be reversed
    depthControlHelper( -1 * cmdVolt );
}

// get a depth reading
float BtuLinear::getDepth() {
    if(m_dryRun) {
        float pvDepth = m_dryRunPot * (DEPTH_MAX);
        return pvDepth;
    }
    float pvDepth = getPressure();
    float pvDepthMeters = (pvDepth - P_ATMOS_MBAR) / P_WATER_SURFACE_MBAR;
    return pvDepthMeters;
}
<commit_msg>fixed more merge conflicts<commit_after>#include "BtuLinear.h"

BtuLinear::BtuLinear():
    m_depthPid(DEP_KC, DEP_KI, DEP_KD, PID_FREQ, DEPTH_MIN, DEPTH_MAX, VEL_MIN, VEL_MAX, 0),
    m_actA(PIN_ACTA_PWM, PIN_ACTA_DIR, PIN_ACTA_POT, PID_FREQ),
    m_actB(PIN_ACTB_PWM, PIN_ACTB_DIR, PIN_ACTB_POT, PID_FREQ),
	m_pressureSensor(PIN_IMU_SDA, PIN_IMU_SCL),
    m_dryRunPot(DRY_RUN_POT_PIN)
{
    m_dryRun = false;
};

BtuLinear::BtuLinear(bool dryRun):
    m_depthPid(DEP_K_C, DEP_TAU_I, DEP_TAU_D, PID_FREQ, DEPTH_MIN, DEPTH_MAX, VEL_MIN, VEL_MAX, 0),
    m_actA(PIN_ACTA_PWM, PIN_ACTA_DIR, PIN_ACTA_POT, PID_FREQ),
    m_actB(PIN_ACTB_PWM, PIN_ACTB_DIR, PIN_ACTB_POT, PID_FREQ),
	m_pressureSensor(PIN_IMU_SDA, PIN_IMU_SCL),
    m_dryRunPot(DRY_RUN_POT_PIN)
{
    m_dryRun = dryRun;
};

BtuLinear::~BtuLinear(){}

void BtuLinear::init() {
    m_mode = DEFAULT_CTRL_MODE;

    // default gain values for depth controller
    m_kc = DEP_KC;
    m_kI = DEP_KI;
    m_kD = DEP_KD;

    // default gain values for position controller
    m_p_kc = POS_KC;
    m_p_kI = POS_KI;
    m_p_kD = POS_KD;

    // default gain values for velocity controller
    m_v_kc = VEL_KC;
    m_v_kI = VEL_KI;
    m_v_kD = VEL_KD;

    // initialize Pressure Sensor
    m_pressureSensor.MS5837Init();
    m_pressureSensor.MS5837Start();
    wait(0.1);                    // remnant from old BTU class TODO: check if can be removed

    // initialize the actuators
    m_actA.reset();
    m_actB.reset();

    // initialize the Windows for SMA to 0
    // for(int i = 0; i < AVG_WINDOW_WIDTH; i++) {
    //     m_avg_windowA[i] = 0;
    //     m_avg_windowB[i] = 0;
    // }

    // initialize starting voltage for velocity control to 0
    // m_currentVoltage = 0;
}

// return a pressure reading
float BtuLinear::getPressure() {
    return m_pressureSensor.MS5837_Pressure();
}

// resets values of the controllers
void BtuLinear::stop() {
	m_depthPid.reset();
    m_actA.reset();
    m_actB.reset();
	return;
}

// updates depth PID tunings
void BtuLinear::updateDepthTunings(float kc, float kI, float kD) {
    m_kc = kc;
    m_kI = kI;
    m_kD = kD;
    m_depthPid.setTunings(kc, kI, kD);
}

// updates Position PID tunings
void BtuLinear::updatePosTunings(float kc, float kI, float kD) {
    m_p_kc = kc;
    m_p_kI = kI;
    m_p_kD = kD;
    m_actA.setPosTunings(kc, kI, kD);
    m_actB.setPosTunings(kc, kI, kD);
}

// updates Velocity PID tunings
void BtuLinear::updateVelTunings(float kc, float kI, float kD) {
    m_v_kc = kc;
    m_v_kI = kI;
    m_v_kD = kD;
    m_actA.setVelTunings(kc, kI, kD);
    m_actB.setVelTunings(kc, kI, kD);
}

// updates Mode.  Resets most values if the mode has changed
void BtuLinear::updateMode(int mode) {
    if(m_mode != mode) {
        stop();
        m_mode = mode;
    }
}

// runs one cycle of the controller dictated by mode
void BtuLinear::runCycle(float setVal) {
    switch (m_mode) {

    case VOLTAGE_CTRL_MODE:
        voltageControl(setVal);
        break;

    case VELOCITY_CTRL_MODE:
        velocityControl(setVal);
        break;

    case DEPTH_CTRL_MODE:
        depthControl(setVal);
        break;

    case POSITION_CTRL_MODE:
        positionControl(setVal);
        break;
    }
}

// convenience function, updates mode, then runs a cycle in the chosen mode
void BtuLinear::updateAndRunCycle(int mode, float value) {
    updateMode(mode);
    runCycle(value);
}

// calls voltageControlHelper on both actuators
void BtuLinear::voltageControl(float setDuty) {
    m_actA.runVoltControl(setDuty);
    m_actB.runVoltControl(setDuty);
}

// updates the SMA window with the current position reading
/*
void BtuLinear::updatePositionReadings() {
    float aPosition = m_actAPot;
    float bPosition = m_actBPot;

    float aOldPos = m_avg_windowA[m_avg_windowPtr];
    float bOldPos = m_avg_windowB[m_avg_windowPtr];
    m_avg_windowA[m_avg_windowPtr] = aPosition;
    m_avg_windowB[m_avg_windowPtr] = bPosition;
    m_avg_windowPtr = (m_avg_windowPtr+1) % AVG_WINDOW_WIDTH;
    if(m_avg_windowSize >= AVG_WINDOW_WIDTH) {
        // buffer is full
    	m_currentAvgA = m_currentAvgA + (aPosition / AVG_WINDOW_WIDTH)- (aOldPos / AVG_WINDOW_WIDTH);
        m_currentAvgB = m_currentAvgB + (bPosition / AVG_WINDOW_WIDTH)- (bOldPos / AVG_WINDOW_WIDTH);
    } else {
    	// buffer is still filling up
        m_avg_windowSize++;
        m_currentAvgA = 0;
        m_currentAvgB = 0;
        for(int i = 0; i < m_avg_windowSize; i++) {
            m_currentAvgA = (m_avg_windowA[i] / m_avg_windowSize);
            m_currentAvgB = (m_avg_windowB[i] / m_avg_windowSize);
        }
    }
}
*/

// gets the current Actuator Position.  No SMA, just reads and rescales the potentiometer
float BtuLinear::getActPosition(int act) {
    if(act == ACT_A) {
        return m_actA.getPosition();
    } else {
        return m_actB.getPosition();
    }
}

// does velocity control on both actuators
void BtuLinear::velocityControl(float setVel) {
    m_actA.runVelControl(setVel);
    m_actB.runVelControl(setVel);
}

// control position of both actuators
void BtuLinear::positionControl(float setPos) {
    m_actA.runPosControl(setPos);
    m_actB.runPosControl(setPos);
}

// control depth via master-slave
void BtuLinear::depthControlHelper(float cmdVoltage) {
	// control velocity on one actuator
    m_actA.runVoltControl(cmdVoltage);
    // have the second mirror the first
    m_actB.runPosControl(m_actA.getPosition());
}

// do depth control
void BtuLinear::depthControl(float setDepthMeters) {
    // Read Pressure Value and Convert into Depth in Meters
	float curDepth = getDepth();

	// current depth becomes process variable for PID controller
    m_depthPid.setProcessValue(curDepth);

    // desired depth in meters becomes set point of PID controller
	m_depthPid.setSetPoint(setDepthMeters);

	// commanded voltage is calculated by PID controller
    float cmdVolt = m_depthPid.compute();

    // extending the actuator increases buoyancy -> less depth
    // therefore the axis direction has to be reversed
    // and commanded voltage with opposite sign is therefore applied
    depthControlHelper( -1 * cmdVolt );
}

// get a depth reading
float BtuLinear::getDepth() {
    if(m_dryRun) {
        float pvDepth = m_dryRunPot * (DEPTH_MAX);
        return pvDepth;
    }
    // read out pressure in mbar
    float pvDepth = getPressure();
    // convert pressure to meters
    float pvDepthMeters = (pvDepth - P_ATMOS_MBAR) / P_WATER_SURFACE_MBAR;
    return pvDepthMeters;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cmtree.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: jb $ $Date: 2000-12-06 17:57:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */

#include "cmtree.hxx"

#include <stl/deque>
#include <stl/vector>
#include <iostream>
#include <exception>
#include <sal/types.h>
#include <stl/set>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <osl/diagnose.h>

#include "confname.hxx"                          // Iterator for PathName scans
#include "cmtreemodel.hxx"
#include "treeactions.hxx"

#include <com/sun/star/uno/Any.hxx>

// WISDOM
// !!Never write same code twice!!

using namespace std;
using namespace rtl;
using namespace com::sun::star::uno;

namespace configmgr
{

// ------------------------ ChildListSet implementations ------------------------
    ChildListSet::ChildListSet(ChildListSet const& aSet)
    {
        for(ChildList::iterator it = aSet.GetSet().begin();
            it != aSet.GetSet().end();
            ++it)
            m_aChildList.insert(m_aChildList.end(), (*it)->clone());
    }
    ChildListSet::~ChildListSet()
    {
        for(ChildList::iterator it = m_aChildList.begin();
            it != m_aChildList.end();
            ++it)
            delete *it;
    }

// ---------------------------- Node implementation ----------------------------

    INode::INode(configuration::Attributes _aAttr):m_aAttributes(_aAttr){}
    INode::INode(OUString const& aName, configuration::Attributes _aAttr)
          :m_aName(aName)
          ,m_aAttributes(_aAttr){}
    // CopyCTor will be create automatically

    INode::~INode() {}

    ISubtree*         INode::asISubtree(){return NULL;}
    ISubtree const*   INode::asISubtree() const {return NULL;}
    ValueNode*       INode::asValueNode() {return NULL;}
    ValueNode const* INode::asValueNode() const {return NULL;}

// ------------------------- SearchNode implementation -------------------------
    SearchNode::SearchNode():INode(configuration::Attributes()){}
    SearchNode::SearchNode(OUString const& aName)
        :INode(aName, configuration::Attributes()){}

    INode* SearchNode::clone() const {return new SearchNode(*this);}

    SearchNode::~SearchNode(){}

    //==========================================================================
    //= OPropagateLevels
    //==========================================================================
    /** fills a subtree with the correct level informations
    */
    struct OPropagateLevels : public NodeModification
    {
    protected:
        sal_Int32   nChildLevel;
    public:
        OPropagateLevels(sal_Int32 _nParentLevel)
        {
            nChildLevel = (ITreeProvider::ALL_LEVELS == _nParentLevel) ? ITreeProvider::ALL_LEVELS : _nParentLevel - 1;
        }
        virtual void handle(ValueNode&) { /* not interested in value nodes */ }
        virtual void handle(ISubtree& _rSubtree)
        {
            if ((ITreeProvider::ALL_LEVELS == nChildLevel) || nChildLevel > _rSubtree.getLevel())
                _rSubtree.setLevel(nChildLevel);
        }
    };

// -------------------------- ISubtree implementation --------------------------
    ISubtree* ISubtree::asISubtree() {return this;}
    ISubtree const* ISubtree::asISubtree() const {return this;}

    //--------------------------------------------------------------------------
    void ISubtree::setLevel(sal_Int16 _nLevel)
    {
        m_nLevel = _nLevel;
        if (0 == _nLevel)
            // nothing more to do, this means "nothing known about any children"
            return;

        // forward the level number to any child subtrees we have
        OPropagateLevels aDeeperInto(_nLevel);
        aDeeperInto.applyToChildren(*this);
    }

// --------------------------- Subtree implementation ---------------------------
    INode* Subtree::clone() const {return new Subtree(*this);}

    INode* Subtree::doGetChild(OUString const& aName) const
    {
        SearchNode searchObj(aName);

#ifdef DEBUG
        for (ChildList::iterator it2 = m_aChildren.GetSet().begin();
            it2 != m_aChildren.GetSet().end();
            ++it2)
        {
            INode* pINode = *it2;
            OUString aName2 = pINode->getName();
            volatile int dummy = 0;
        }
#endif

        ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
        if (it == m_aChildren.GetSet().end())
            return NULL;
        else
            return *it;
    }

    INode* Subtree::addChild(std::auto_ptr<INode> aNode)    // takes ownership
    {
        OUString aName = aNode->getName();
        std::pair<ChildList::iterator, bool> aInserted =
            m_aChildren.GetSet().insert(aNode.get());
        if (aInserted.second)
            aNode.release();
        return *aInserted.first;
    }

    ::std::auto_ptr<INode> Subtree::removeChild(OUString const& aName)
    {
        SearchNode searchObj(aName);
        ChildList::const_iterator it = m_aChildren.GetSet().find(&searchObj);

        ::std::auto_ptr<INode> aReturn;
        if (m_aChildren.GetSet().end() != it)
        {
            aReturn = ::std::auto_ptr<INode>(*it);
            m_aChildren.GetSet().erase(it);
        }
        return aReturn;
    }

    //==========================================================================
    //= OBuildChangeTree - historic
    //==========================================================================
    /** generates a change tree by comparing two trees
    */
/*  struct OBuildChangeTree : public NodeModification
    {
    protected:
        SubtreeChange&  m_rChangeList;
        INode*          m_pCacheNode;

    public:
        OBuildChangeTree(SubtreeChange& rList, INode* pNode)
            :m_rChangeList(rList)
            ,m_pCacheNode(pNode)
        {
        }

        virtual void handle(ValueNode& _nNode)
        {
            OUString aNodeName = _nNode.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSHURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                ValueNode* pValueNode = pChild ? pChild->asValueNode() : NULL;
                OSL_ENSHURE(pValueNode, "OBuildChangeTree::handle : node must be a value node!");

                // if the values differ add a new change
                if (pValueNode && _nNode.getValue() != pValueNode->getValue())
                {
                    ValueChange* pChange = new ValueChange(_nNode.getValue(), *pValueNode);
                    m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                }
            }
        }

        virtual void handle(ISubtree& _rSubtree)
        {
            OUString aNodeName = _rSubtree.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSHURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                // node not in cache, so ignore it
                // later, when we get additions and removements within on transaction, then we have to care about
                if (pChild)
                {
                    ISubtree* pSubTree = pChild->asISubtree();
                    OSL_ENSHURE(pSubTree, "OBuildChangeTree::handle : node must be a inner node!");
                    // generate a new change

                    SubtreeChange* pChange = new SubtreeChange(_rSubtree);
                    OBuildChangeTree aNextLevel(*pChange, pSubTree);
                    aNextLevel.applyToChildren(_rSubtree);

                    // now count if there are any changes
                    OChangeCounter aCounter;
                    pChange->dispatch(aCounter);

                    if (aCounter.nCount != 0)
                        m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                    else
                        delete pChange;
                }
            }
        }
    };

*/
    void Subtree::forEachChild(NodeAction& anAction) const {
        for(ChildList::const_iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

    void Subtree::forEachChild(NodeModification& anAction) {
        for(ChildList::iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

// -------------------------- ValueNode implementation --------------------------
    void ValueNode::check_init()    // may throw in the future
    {
        if (m_aValue.hasValue())
        {
            OSL_ASSERT(m_aType != ::getVoidCppuType());
            OSL_ASSERT(m_aType == m_aValue.getValueType());
        }
        else OSL_ASSERT(getVoidCppuType() == m_aValue.getValueType());

        if (m_aDefaultValue.hasValue())
        {
            OSL_ASSERT(m_aType != ::getVoidCppuType());
            OSL_ASSERT(m_aType == m_aDefaultValue.getValueType());
        }
        else OSL_ASSERT(getVoidCppuType() == m_aDefaultValue.getValueType());
    }

    void ValueNode::init()
    {
        OSL_ASSERT(m_aType == ::getVoidCppuType());

        if (m_aDefaultValue.hasValue())
        {
            m_aType = m_aDefaultValue.getValueType();
            OSL_ASSERT(m_aType != ::getVoidCppuType());
        }
        else if (m_aValue.hasValue())
        {
            m_aType = m_aValue.getValueType();
            OSL_ASSERT(m_aType != ::getVoidCppuType());
        }
    }

    void ValueNode::setValue(Any aValue)
    {
        m_aValue = aValue;
        // flip the type if necessary
        if  (   (m_aType.getTypeClass() == TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_VOID)
            )
            m_aType = aValue.getValueType();
    }

    void ValueNode::changeDefault(Any aValue)
    {
        m_aDefaultValue = aValue;
        // flip the type if necessary
        if  (   (m_aType.getTypeClass() == TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_VOID)
            )
            m_aType = aValue.getValueType();
    }

    void ValueNode::setDefault()
    {
        // PRE: ????
        // POST: isDefault() == true
        m_aValue = Any();
    }

    INode* ValueNode::clone() const
    {
        return new ValueNode(*this);
    }

    ValueNode* ValueNode::asValueNode() {return this;}
    ValueNode const* ValueNode::asValueNode() const {return this;}

} // namespace configmgr

<commit_msg>include stdio.h to compile under Solaris 8<commit_after>/*************************************************************************
 *
 *  $RCSfile: cmtree.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: fs $ $Date: 2000-12-10 09:59:57 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */

#include "cmtree.hxx"

#include <stl/deque>
#include <stl/vector>
#include <iostream>
#include <exception>
#include <sal/types.h>
#include <stl/set>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
#include <osl/diagnose.h>

#include "confname.hxx"                          // Iterator for PathName scans
#include "cmtreemodel.hxx"
#include "treeactions.hxx"

#include <com/sun/star/uno/Any.hxx>

// WISDOM
// !!Never write same code twice!!

using namespace std;
using namespace rtl;
using namespace com::sun::star::uno;

namespace configmgr
{

// ------------------------ ChildListSet implementations ------------------------
    ChildListSet::ChildListSet(ChildListSet const& aSet)
    {
        for(ChildList::iterator it = aSet.GetSet().begin();
            it != aSet.GetSet().end();
            ++it)
            m_aChildList.insert(m_aChildList.end(), (*it)->clone());
    }
    ChildListSet::~ChildListSet()
    {
        for(ChildList::iterator it = m_aChildList.begin();
            it != m_aChildList.end();
            ++it)
            delete *it;
    }

// ---------------------------- Node implementation ----------------------------

    INode::INode(configuration::Attributes _aAttr):m_aAttributes(_aAttr){}
    INode::INode(OUString const& aName, configuration::Attributes _aAttr)
          :m_aName(aName)
          ,m_aAttributes(_aAttr){}
    // CopyCTor will be create automatically

    INode::~INode() {}

    ISubtree*         INode::asISubtree(){return NULL;}
    ISubtree const*   INode::asISubtree() const {return NULL;}
    ValueNode*       INode::asValueNode() {return NULL;}
    ValueNode const* INode::asValueNode() const {return NULL;}

// ------------------------- SearchNode implementation -------------------------
    SearchNode::SearchNode():INode(configuration::Attributes()){}
    SearchNode::SearchNode(OUString const& aName)
        :INode(aName, configuration::Attributes()){}

    INode* SearchNode::clone() const {return new SearchNode(*this);}

    SearchNode::~SearchNode(){}

    //==========================================================================
    //= OPropagateLevels
    //==========================================================================
    /** fills a subtree with the correct level informations
    */
    struct OPropagateLevels : public NodeModification
    {
    protected:
        sal_Int32   nChildLevel;
    public:
        OPropagateLevels(sal_Int32 _nParentLevel)
        {
            nChildLevel = (ITreeProvider::ALL_LEVELS == _nParentLevel) ? ITreeProvider::ALL_LEVELS : _nParentLevel - 1;
        }
        virtual void handle(ValueNode&) { /* not interested in value nodes */ }
        virtual void handle(ISubtree& _rSubtree)
        {
            if ((ITreeProvider::ALL_LEVELS == nChildLevel) || nChildLevel > _rSubtree.getLevel())
                _rSubtree.setLevel(nChildLevel);
        }
    };

// -------------------------- ISubtree implementation --------------------------
    ISubtree* ISubtree::asISubtree() {return this;}
    ISubtree const* ISubtree::asISubtree() const {return this;}

    //--------------------------------------------------------------------------
    void ISubtree::setLevel(sal_Int16 _nLevel)
    {
        m_nLevel = _nLevel;
        if (0 == _nLevel)
            // nothing more to do, this means "nothing known about any children"
            return;

        // forward the level number to any child subtrees we have
        OPropagateLevels aDeeperInto(_nLevel);
        aDeeperInto.applyToChildren(*this);
    }

// --------------------------- Subtree implementation ---------------------------
    INode* Subtree::clone() const {return new Subtree(*this);}

    INode* Subtree::doGetChild(OUString const& aName) const
    {
        SearchNode searchObj(aName);

#ifdef DEBUG
        for (ChildList::iterator it2 = m_aChildren.GetSet().begin();
            it2 != m_aChildren.GetSet().end();
            ++it2)
        {
            INode* pINode = *it2;
            OUString aName2 = pINode->getName();
            volatile int dummy = 0;
        }
#endif

        ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
        if (it == m_aChildren.GetSet().end())
            return NULL;
        else
            return *it;
    }

    INode* Subtree::addChild(std::auto_ptr<INode> aNode)    // takes ownership
    {
        OUString aName = aNode->getName();
        std::pair<ChildList::iterator, bool> aInserted =
            m_aChildren.GetSet().insert(aNode.get());
        if (aInserted.second)
            aNode.release();
        return *aInserted.first;
    }

    ::std::auto_ptr<INode> Subtree::removeChild(OUString const& aName)
    {
        SearchNode searchObj(aName);
        ChildList::const_iterator it = m_aChildren.GetSet().find(&searchObj);

        ::std::auto_ptr<INode> aReturn;
        if (m_aChildren.GetSet().end() != it)
        {
            aReturn = ::std::auto_ptr<INode>(*it);
            m_aChildren.GetSet().erase(it);
        }
        return aReturn;
    }

    //==========================================================================
    //= OBuildChangeTree - historic
    //==========================================================================
    /** generates a change tree by comparing two trees
    */
/*  struct OBuildChangeTree : public NodeModification
    {
    protected:
        SubtreeChange&  m_rChangeList;
        INode*          m_pCacheNode;

    public:
        OBuildChangeTree(SubtreeChange& rList, INode* pNode)
            :m_rChangeList(rList)
            ,m_pCacheNode(pNode)
        {
        }

        virtual void handle(ValueNode& _nNode)
        {
            OUString aNodeName = _nNode.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSHURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                ValueNode* pValueNode = pChild ? pChild->asValueNode() : NULL;
                OSL_ENSHURE(pValueNode, "OBuildChangeTree::handle : node must be a value node!");

                // if the values differ add a new change
                if (pValueNode && _nNode.getValue() != pValueNode->getValue())
                {
                    ValueChange* pChange = new ValueChange(_nNode.getValue(), *pValueNode);
                    m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                }
            }
        }

        virtual void handle(ISubtree& _rSubtree)
        {
            OUString aNodeName = _rSubtree.getName();
            ISubtree* pTree = m_pCacheNode->asISubtree();
            OSL_ENSHURE(pTree, "OBuildChangeTree::handle : node must be a inner node!");
            if (pTree)
            {
                INode* pChild = pTree->getChild(aNodeName);
                // node not in cache, so ignore it
                // later, when we get additions and removements within on transaction, then we have to care about
                if (pChild)
                {
                    ISubtree* pSubTree = pChild->asISubtree();
                    OSL_ENSHURE(pSubTree, "OBuildChangeTree::handle : node must be a inner node!");
                    // generate a new change

                    SubtreeChange* pChange = new SubtreeChange(_rSubtree);
                    OBuildChangeTree aNextLevel(*pChange, pSubTree);
                    aNextLevel.applyToChildren(_rSubtree);

                    // now count if there are any changes
                    OChangeCounter aCounter;
                    pChange->dispatch(aCounter);

                    if (aCounter.nCount != 0)
                        m_rChangeList.addChange(::std::auto_ptr<Change>(pChange));
                    else
                        delete pChange;
                }
            }
        }
    };

*/
    void Subtree::forEachChild(NodeAction& anAction) const {
        for(ChildList::const_iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

    void Subtree::forEachChild(NodeModification& anAction) {
        for(ChildList::iterator it = m_aChildren.GetSet().begin();
            it != m_aChildren.GetSet().end();
            ++it)
            (**it).dispatch(anAction);
    }

// -------------------------- ValueNode implementation --------------------------
    void ValueNode::check_init()    // may throw in the future
    {
        if (m_aValue.hasValue())
        {
            OSL_ASSERT(m_aType != ::getVoidCppuType());
            OSL_ASSERT(m_aType == m_aValue.getValueType());
        }
        else OSL_ASSERT(getVoidCppuType() == m_aValue.getValueType());

        if (m_aDefaultValue.hasValue())
        {
            OSL_ASSERT(m_aType != ::getVoidCppuType());
            OSL_ASSERT(m_aType == m_aDefaultValue.getValueType());
        }
        else OSL_ASSERT(getVoidCppuType() == m_aDefaultValue.getValueType());
    }

    void ValueNode::init()
    {
        OSL_ASSERT(m_aType == ::getVoidCppuType());

        if (m_aDefaultValue.hasValue())
        {
            m_aType = m_aDefaultValue.getValueType();
            OSL_ASSERT(m_aType != ::getVoidCppuType());
        }
        else if (m_aValue.hasValue())
        {
            m_aType = m_aValue.getValueType();
            OSL_ASSERT(m_aType != ::getVoidCppuType());
        }
    }

    void ValueNode::setValue(Any aValue)
    {
        m_aValue = aValue;
        // flip the type if necessary
        if  (   (m_aType.getTypeClass() == TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_VOID)
            )
            m_aType = aValue.getValueType();
    }

    void ValueNode::changeDefault(Any aValue)
    {
        m_aDefaultValue = aValue;
        // flip the type if necessary
        if  (   (m_aType.getTypeClass() == TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_ANY)
            &&  (aValue.getValueType().getTypeClass() != TypeClass_VOID)
            )
            m_aType = aValue.getValueType();
    }

    void ValueNode::setDefault()
    {
        // PRE: ????
        // POST: isDefault() == true
        m_aValue = Any();
    }

    INode* ValueNode::clone() const
    {
        return new ValueNode(*this);
    }

    ValueNode* ValueNode::asValueNode() {return this;}
    ValueNode const* ValueNode::asValueNode() const {return this;}

} // namespace configmgr

<|endoftext|>